Winsock code produces 0xc0000022 error

0

I recently ported a linux application I wrote that uses BSD sockets extensively to winsock. The code seems to work perfectly fine on linux, and it compiles fine on windows, however when the executable is run I get a message box with the following content:

The application was unable to start correctly (0xc0000022). Click OK to close the application.

Of course I googled around about that error and mostly was pointed to antivirus issues. I gathered that the application is having trouble reading a dll somehow, so I tried downloading a copy of winsock.dll and tossing it in the runpath of my executable, to no avail. I also ran dependency walker on the executable which gave a long list of errors. Most errors were just warnings (multiple CPU types found for example) but I did notice Error: A circular dependency was detected which raised an eyebrow.

As I said, the code works as-is on linux. Here is my tcp.c:

    #include "tcp.h"

#define BUFSIZE 2048

#if defined(_WIN32)
    #include <winsock2.h>
    typedef int socklen_t;

    struct pollfd {
        SOCKET fd;
        short events;
        short revents;
    };

    #define poll(X,Y,Z) winpoll(X,Y,Z)
    #define POLLOUT 1
    #define POLLIN 0

static int winpoll(struct pollfd *pfd, int ignored, int ignored2) {
    fd_set rfds;
    struct timeval zero = {0};

    int retval;

    FD_ZERO(&rfds);
    FD_SET(pfd->fd, &rfds);

    if (pfd->events == POLLOUT) {
        retval = select(1,NULL,&rfds,NULL,&zero);
    } else {
        retval = select(1,&rfds,NULL,NULL,&zero);
    }

    if (retval < 0) {
        perror("select");
    }

    return retval;
}
#else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/poll.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <netinet/ip.h>
    #include <netdb.h>
    #include <ifaddrs.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#define BIND(SOCK,ADDR) bind(SOCK,(struct sockaddr*)&(ADDR),sizeof(struct sockaddr_in))
#define CONN(SOCK,ADDR) connect(SOCK,(struct sockaddr*)&(ADDR),sizeof(struct sockaddr_in))

void tcp_wrapup(void) 
{
#if defined(_WIN32)
    WSACleanup();
#endif
}

void tcp_setup(void)
{
#if defined(_WIN32)
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2),&wsaData);
#endif
}

static void set_nonblocking(int fd) 
{
#if defined(_WIN32)
    unsigned long mode = 1; /* non-blocking */
    ioctlsocket(fd, FIONBIO, &mode);
#else
    fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NONBLOCK);
#endif
}

int tcp_server_init(unsigned short port)
{
    int server_sock;
    struct sockaddr_in server_addr = {0};


    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock < 0) { perror("sock"); return -1; }

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    if (BIND(server_sock,server_addr) < 0) { perror("bind"); return -1; }

    set_nonblocking(server_sock);

    if (listen(server_sock, 0) < 0) { perror("listen"); return -1; }

    return server_sock;
}

int tcp_server_poll(int server_sock)
{
    int client_sock;

    client_sock = accept(server_sock,NULL,NULL);
    if (client_sock < 0) {
        return -1;
    }
    return client_sock;
}

int tcp_client_init(unsigned int ip, unsigned short port)
{
    int client_sock;
    struct sockaddr_in client_addr = {0};

    client_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (client_sock < 0) { perror("socket"); return -1; }

    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = htonl(ip);
    client_addr.sin_port = htons(port);

    set_nonblocking(client_sock);

    /* Note: WILL fail, operation in progress, non-blocking sockets wait for
     * handshake. */
    CONN(client_sock,client_addr);

    return client_sock;
}

void tcp_send(int sock, const char *msg) 
{
    int status;
    struct pollfd myfd;
    myfd.fd = sock;
    myfd.events = POLLOUT;

    status = poll(&myfd,1,0);

    if (status == 1) {
        if (send(sock, msg, strlen(msg)+1, 0) < 0) {
            perror("send");
        }
    }
}

int tcp_recv(int sock, char *buf, int max)
{
    int status;
    struct pollfd myfd;
    myfd.fd = sock;
    myfd.events = POLLIN;

    status = poll(&myfd,1,0);

    if (status == 1) {
        int ret;
        if ((ret = recv(sock,buf,max,0)) < 0) {
            return 0;
        }
        return ret;
    }
    return 0;
}

void tcp_close(int sock)
{
#if defined(_WIN32)
    closesocket(sock);
#else
    if (close(sock) < 0) {
        perror("close");
    }
#endif
}

unsigned int tcp_str_to_ip(const char *ip)
{
#if defined(_WIN32)
    int bytes[4];
    sscanf(ip,"%d.%d.%d.%d",&bytes[0],&bytes[1],&bytes[2],&bytes[3]);

    return ntohl(((bytes[0]<<24) & 0xFF) |
                 ((bytes[1]<<16) & 0xFF) | 
                 ((bytes[2]<<8) & 0xFF) |
                 (bytes[3] & 0xFF));
#else
    struct addrinfo *cursor;
    struct addrinfo *server = NULL;
    getaddrinfo(ip,NULL,NULL,&server);

    for (cursor = server; cursor; cursor = cursor->ai_next) {
        if (cursor->ai_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)cursor->ai_addr;
            return ntohl(addr->sin_addr.s_addr);
        }
    }

    return ntohl((unsigned int)inet_addr(ip));
#endif
}

char *tcp_ip_to_str(unsigned int ip)
{
    struct in_addr addr;
    addr.s_addr = htonl(ip);
    return inet_ntoa(addr);
}

unsigned short tcp_get_port(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getpeername(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getpeername");
        return -1;
    }

    return ntohs(addr.sin_port);
}

unsigned int tcp_get_ip(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getpeername(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getpeername");
        return -1;
    }

    return ntohl(addr.sin_addr.s_addr);
}

unsigned short tcp_get_local_port(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getsockname(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getsockname");
        return -1;
    }

    return ntohs(addr.sin_port);
}

unsigned int tcp_get_local_ip(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getsockname(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getsockname");
        return -1;
    }

    return ntohl(addr.sin_addr.s_addr);
}

My tcp.h header:

#ifndef _TCP_H
#define _TCP_H

typedef int TCP_Socket;

/* <0 means no connection, try again */
TCP_Socket tcp_server_init(unsigned short);
TCP_Socket tcp_server_poll(TCP_Socket);
TCP_Socket tcp_client_init(unsigned int, unsigned short); 

void tcp_send(TCP_Socket, const char *); 
int tcp_recv(TCP_Socket, char *, int); /* 0 = no data */

void tcp_close(TCP_Socket);

unsigned int tcp_str_to_ip(const char *);
char *tcp_ip_to_str(unsigned int); /* in static buf */

unsigned short tcp_get_port(TCP_Socket);
unsigned int tcp_get_ip(TCP_Socket);
unsigned short tcp_get_local_port(TCP_Socket);
unsigned int tcp_get_local_ip(TCP_Socket);

/* Windows needs wrapup code. */
void tcp_wrapup(void);
void tcp_setup(void);
#endif /* _TCP_H */

As for the command line, the windows version just adds -lwsock32 to the end of the command that the linux version uses. Any idea how to get my code working?

Note

I tried compiling with debug mode, which still provides the same error code. I ran gdb with break main and before it could even hit the main breakpoint it crashed saying During startup program exited with code 0xc0000022. This leads me to believe that it may be an issue outside of the code? or perhaps with the permissions of the code?

c
dll
winsock
winsock2
asked on Stack Overflow Jun 15, 2016 by LambdaBeta • edited Jun 15, 2016 by LambdaBeta

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0