mysql udf respond is random - c++

I call the function AES_Dec with the same Parameters. In most of the cases it returns the correct respond. But with a randomness of around 15% the respond is different.
char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error)
{
//initialize variables
//initialize key
char *keyPlain = args->args[1];
int keylength = (static_cast<int>(args->lengths[1])) / 2;
uint16_t *key = new uint16_t;
hex2bin(keyPlain, reinterpret_cast<unsigned char*>(key));
//output
char *output = new char;
bin2hex(key , keylength, output);
*length = keylength* 2;
return output;
}
void hex2bin(const char* src, unsigned char* target)
{
while (*src && src[1])
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
}
}
int char2int(char input)
{
if (input >= '0' && input <= '9')
return input - '0';
if (input >= 'A' && input <= 'F')
return input - 'A' + 10;
if (input >= 'a' && input <= 'f')
return input - 'a' + 10;
return 0;
}
void bin2hex(unsigned short* pv, size_t len, char *output)
{
const unsigned char * buf = reinterpret_cast<const unsigned char*>(pv);
static const char* hex_lookup = "0123456789ABCDEF";
char *p = output;
for (int i = 0; i < len; i++) {
*p++ = hex_lookup[buf[i] >> 4];
*p++ = hex_lookup[buf[i] & 0x0F];
}
*p = '\0';
}
I call this function with the following parameters:
SELECT AES_Dec('2C4E907536FBB3C9FADD4CFBD45950EF03517AA5F7F402DA9E3ABD03FC6E0068EF39F3DFC26A92B871E8D8CE521EAF6C', 'B99DD1D646CDBC8505419D069B5C0209', '1')
The correct respond which is returned most of the time is:
B99DD1D646CDBC8505419D069B5C0209
And the respond which comes randomly is
B2323332333333323333333333333332
There are only these two responses. And I have no idea why the random respond appears. In a console application it all works fine without any problems. So the code should work.
Have anyone a solution?
Thank you.
Edit: the full quellcode:
#include "Header.h"
#ifdef HAVE_DLOPEN
my_bool AES_Dec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if (args->arg_count != 3) {
return 1;
}
else if (args->arg_type[0] != STRING_RESULT ||
args->arg_type[1] != STRING_RESULT ||
args->arg_type[2] != STRING_RESULT) {
return 1;
}
return 0;
}
void AES_Dec_clear(UDF_INIT *initid, char *is_null, char *message) {
}
void AES_Dec_add(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *message) {
}
char* AES_Dec(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error)
{
//initialize variables
//initialize modus
char* modChar = args->args[2];
int mod;
if (modChar[0] == '1')
mod = 1;
else
mod = 0;
//initialize key
char *keyPlain = args->args[1];
int keylength = (static_cast<int>(args->lengths[1])) / 2;
uint16_t *key = new uint16_t;
hex2bin(keyPlain, reinterpret_cast<unsigned char*>(key));
//initialize value
const char *plain = args->args[0];
int plainLength = 0;
if (mod == 0)
plainLength = args->lengths[0] / 2;
else
plainLength = args->lengths[0] / 2 - 16;
uint16_t *contentWithIv = new uint16_t;
uint16_t *iv = new uint16_t;
hex2bin(plain, (unsigned char*)contentWithIv);
if (mod == 1) {
for (int i = 0; i < 8; i++) {
iv[i] = *contentWithIv;
contentWithIv++;
}
}
else
iv == NULL;
uint16_t *plaintext = contentWithIv;
// Buffer for the decrypted text
uint16_t *decryptedtext = new uint16_t;
int decryptedtext_len, ciphertext_len;
// Initialise the library
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);
// Encrypt the plaintext
decryptedtext_len = decrypt((unsigned char*)plaintext, plainLength, (unsigned char*)key, (unsigned char*)iv, (unsigned char*)decryptedtext, keylength * 8, mod);
// Add a NULL terminator. We are expecting printable text
decryptedtext[decryptedtext_len] = '\0';
// Clean up
EVP_cleanup();
ERR_free_strings();
char *finalDec = (char*)malloc(decryptedtext_len * 2);
bin2hex(decryptedtext, decryptedtext_len, finalDec);
*length = decryptedtext_len * 2;
return finalDec;
}
void AES_Dec_deinit(UDF_INIT *initid) {
free(initid->ptr);
}
void handleErrors(void) {
ERR_print_errors_fp(stderr);
abort();
}
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext, int keylength, int mod)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
// Create and initialise the context
if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
// Initialise the decryption operation.
if (mod == 0) {
if (keylength == 128)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
handleErrors();
if (keylength == 192)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_ecb(), NULL, key, NULL))
handleErrors();
if (keylength == 256)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
handleErrors();
}
else if (mod == 1) {
if (keylength == 128)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
handleErrors();
if (keylength == 192)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_192_cbc(), NULL, key, iv))
handleErrors();
if (keylength == 256)
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
handleErrors();
}
else
handleErrors();
// Provide the message to be decrypted, and obtain the plaintext output.
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;
// Finalise the decryption.
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
plaintext_len += len;
// Clean up
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
void hex2bin(const char* src, unsigned char* target)
{
while (*src && src[1])
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
}
}
int char2int(char input)
{
if (input >= '0' && input <= '9')
return input - '0';
if (input >= 'A' && input <= 'F')
return input - 'A' + 10;
if (input >= 'a' && input <= 'f')
return input - 'a' + 10;
return 0;
}
void bin2hex(unsigned short* pv, size_t len, char *output)
{
const unsigned char * buf = reinterpret_cast<const unsigned char*>(pv);
static const char* hex_lookup = "0123456789ABCDEF";
char *p = output;
for (int i = 0; i < len; i++) {
*p++ = hex_lookup[buf[i] >> 4];
*p++ = hex_lookup[buf[i] & 0x0F];
}
*p = '\0';
}
#endif /* HAVE_DLOPEN */

Related

How to correctly return pointer to array of chars?

I have the following code to read from file, it uses byte-at-a-time system call I/O and is thus quite slow
int readc(io61_file* f) {
unsigned char buf[1];
ssize_t nr = read(f->fd, buf, 1);
if (nr == 1) {
return buf[0];
} else if (nr == 0) {
errno = 0; // clear `errno` to indicate EOF
return -1;
} else {
assert(nr == -1 && errno > 0);
return -1;
}
}
This is how I use it
// io_read(f, buf, sz)
// Reads up to `sz` bytes from `f` into `buf`. Returns the number of
// bytes read on success. Returns 0 if end-of-file is encountered before
// any bytes are read, and -1 if an error is encountered before any
// bytes are read.
//
// Note that the return value might be positive, but less than `sz`,
// if end-of-file or error is encountered before all `sz` bytes are read.
// This is called a “short read.”
ssize_t io_read(io61_file* f, unsigned char* buf, size_t sz) {
size_t nread = 0;
while (nread != sz) {
int ch = readc(f);
if (ch == EOF) {
break;
}
buf[nread] = ch;
++nread;
}
if (nread != 0 || sz == 0 || errno == 0) {
return nread;
} else {
return -1;
}
}
I want to speed up this code and as the first step, I want to increase the buf size inside readc to 10. How to do this correctly? As the first step I decided to return an array of size 1 from readc but it doesn't work as expected. Where I made a mistake?
unsigned char* io_readc2(io61_file* f) {
static unsigned char buf[1];
ssize_t nr = read(f->fd, buf, 1);
if (nr > 0 && nr < 2) {
return buf;
} else if (nr == 0) {
errno = 0; // clear `errno` to indicate EOF
static unsigned char t[1];
t[0] = -1;
return t;
} else {
assert(nr == -1 && errno > 0);
static unsigned char t[1];
t[0] = -1;
return t;
}
}
ssize_t io_read(io61_file* f, unsigned char* buf, size_t sz) {
size_t nread = 0;
while (nread != sz) {
unsigned char* chars = io_readc2(f);
int ch = *chars;
if (ch == EOF) {
break;
}
buf[nread] = ch;
++nread;
}
if (nread != 0 || sz == 0 || errno == 0) {
return nread;
} else {
return -1;
}
}
There is no need for an intermediate buffer. Just take the data from the standard library and write it into the output buffer:
// f->fd is the file descriptor to read from
// buf is the output, sz is the maximum bytes to read
// return value is the number of bytes read
// if there was an error, returns -1 with error != 0
// if there was no data available, returns -1 with errno == 0
ssize_t io_read(io61_file* f, unsigned char* buf, size_t sz)
{
ssize_t nr = read(f->fd, buf, sz);
if (nr == 0 && sz != 0)
{
errno = 0;
return -1;
}
return nr;
}
Edit: since you say you need an intermediate buffer, here you go:
// same effect as io_read() but with extra buffering for some reason
ssize_t io_read_extra(io61_file* f, unsigned char* buf, size_t sz)
{
std::vector<char> innerbuf(sz);
ssize_t nr = read(f->fd, innerbuf.data(), sz);
if (nr == 0 && sz != 0)
{
errno = 0;
return -1;
}
if (nr > 0)
{
memcpy(buf, innerbuf.data(), nr);
}
return nr;
}

server client sending receiving structure via raw data errors C++

I am doing a sending and receiving functions for structure(in my case "frame") via TCP/IP. But the functions don't seem to work out and I cannot find where my errors are. I am asked to store all the data in a char array and send it, while receiving the char array and convert them into the structure.
struct frame {
int length;
int * body;
int tail;
};
void winsock_client::send_frame(frame f) {
char * arr;
char * tx;
int length = 8 + f.length * sizeof(int);
arr = new char[length];
tx = (char*)&f.length;
for (int i = 0; i < sizeof(int); i++) {
arr[i] = *(tx++);
}
for (int i = 0; i < f.length; i++) {
tx =(char*)&f.body[i];
for (int j = 0; j < sizeof(int); j++) {
arr[4 + i * sizeof(int) + j] = *(tx++);
}
}
tx = (char*)&f.tail;
for (int i = 0; i < sizeof(int); i++) {
arr[4 + f.length * sizeof(int) + i] = *(tx++);
}
send(client_socket, arr, sizeof(arr), 0);
}
void winsock_server::receive_frame(frame & f) {
int * rx;
recv(server_socket, rx_buffer, sizeof(rx_buffer), 0);
rx =(int *) &rx_buffer[0];
f.length = *rx;
f.body = new int[f.length];
rx = (int *)&rx_buffer[4];
for (int i = 0; i < f.length; i++) {
f.body[i] = *(rx++);
}
rx = (int*)&rx_buffer[16];
f.tail = *rx;
}
Can anyone tell me what my errors are in my functions?
You are not checking the return values of send() and recv() to make sure that you are actually sending/receiving everything you are expecting. TCP is a streaming transport, there is no 1:1 relationship between sends and receives, like there is in UDP. Both functions can send/receive fewer bytes than requested, so you need to handle that.
Also, your read_frame() is using a fixed-length buffer to receive data, but you aren't taking into account how much data is actually being sent, so your buffer may not receive a full frame, or worse may receive a frame that is larger than it can hold.
The code is just plain ugly to read, too. It should be be re-written.
Try something more like this instead:
bool sendAll(SOCKET s, const void *buf, int len)
{
const char *pbuf = (const char*) buf;
while (len > 0)
{
int sent = send(s, pbuf, len, 0);
if (sent == SOCKET_ERROR)
return false;
pbuf += sent;
len -= sent;
}
return true;
}
bool winsock_client::send_frame(const frame &f)
{
int size = (2 + f.length) * sizeof(u_long);
char *arr = new char[size];
// multi-byte integers should always be transmitted in network
// byte order to avoid any endian issues across machine boundaries...
u_long *ptr = (u_long*) arr;
*ptr++ = htonl(f.length);
for (int i = 0; i < f.length; ++i)
*ptr++ = htonl(f.body[i]);
*ptr = htonl(f.tail);
bool result = sendAll(client_socket, arr, size);
delete[] arr;
return result;
}
bool recvAll(SOCKET s, void *buf, int len)
{
char *pbuf = (char*) buf;
while (len > 0)
{
int recvd = recv(s, pbuf, len, 0);
if (recvd <= 0) // -1 on error, 0 on disconnect
return false;
pbuf += recvd;
len -= recvd;
}
return true;
}
bool winsock_server::receive_frame(frame &f)
{
u_long temp;
if (!recvAll(server_socket, &temp, sizeof(temp)))
return false;
f.length = ntohl(temp);
u_long *arr = new u_long[f.length+1];
if (!recvAll(server_socket, arr, sizeof(u_long) * (f.length + 1)))
{
delete[] arr;
return false;
}
f.body = new int[f.length];
for(int i = 0; i < f.length; ++i)
f.body[i] = ntohl(arr[i]);
f.tail = ntohl(arr[f.length]);
delete[] arr;
return true;
}
Alternatively, you can simplify the code a bit if you take into account that the socket already does its own internal buffering for you:
bool sendAll(SOCKET s, const void *buf, int len)
{
const char *pbuf = (const char*) buf;
while (len > 0)
{
int sent = send(s, pbuf, len, 0);
if (sent == SOCKET_ERROR)
return false;
pbuf += sent;
len -= sent;
}
return true;
}
bool sendInt(SOCKET s, int value)
{
// multi-byte integers should always be transmitted in network
// byte order to avoid any endian issues across machine boundaries...
u_long temp = htonl(value);
return sendAll(s, &temp, sizeof(temp));
}
bool winsock_client::send_frame(const frame &f)
{
if (!sendInt(client_socket, f.length))
return false;
for (int i = 0; i < f.length; ++i)
{
if (!sendInt(client_socket, f.body[i]))
return false;
}
return sendInt(client_socket, f.tail);
}
bool recvAll(SOCKET s, void *buf, int len)
{
char *pbuf = (char*) buf;
while (len > 0)
{
int recvd = recv(s, pbuf, len, 0);
if (recvd <= 0) // -1 on error, 0 on disconnect
return false;
pbuf += recvd;
len -= recvd;
}
return true;
}
bool recvInt(SOCKET s, int &value)
{
u_long temp;
bool result = recvAll(s, &temp, sizeof(temp));
if (result) value = ntohl(temp);
return result;
}
bool winsock_server::receive_frame(frame &f)
{
if (!recvInt(server_socket, f.length))
return false;
f.body = new int[f.length];
for(int i = 0; i < f.length; ++i)
{
if (!recvInt(server_socket, f.body[i]))
{
delete[] f.body;
return false;
}
}
if (!recvInt(server_socket, f.tail))
{
delete[] f.body;
return false;
}
return true;
}

decrypt/encrypt large data using RSA public key

I wan encrypt large DATA using an RSA public key then decrypt it using the private key
So my encryption function is :
unsigned char* encryptFile::rsaEncrypt( RSA *pubKey, const unsigned char* msg, int msg_len, int *enc_len )
{
int rsa_size = RSA_size(pubKey);
int block_size = rsa_size - 12;
int blocks = msg_len/block_size;
int rest = msg_len % block_size;
unsigned char* enc = 0;
int curr_len = 0;
int i = 0;
if (0 == rest) {
enc = (unsigned char*)malloc(blocks*rsa_size + 1);
}
else {
enc = (unsigned char*)malloc((blocks+1)*rsa_size + 1);
}
for (i = 0; i < blocks; i++) {
if (0 > (curr_len = RSA_public_encrypt(block_size , msg + i*block_size, enc + i*rsa_size, pubKey, RSA_PKCS1_PADDING))) {
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
*enc_len += curr_len;
}
if (0 != rest) {
if (0 > (curr_len = RSA_public_encrypt(rest , msg + i*block_size, enc + i*rsa_size, pubKey, RSA_PKCS1_PADDING))) {
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
*enc_len += curr_len;
}
if( *enc_len == -1 )
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
cout << *enc_len << endl;
return enc;
}
And it's working fine !
Now when i want decrypt it i'm using this code
int rsa_size = RSA_size(privKey);
int msg_len = encBinLen;
int block_size = rsa_size;
int blocks = msg_len/block_size;
int rest = msg_len % block_size;
unsigned char* enc = 0;
int curr_len = 0;
enc_len = 0;
int i = 0;
if (0 == rest) {
enc = (unsigned char*)malloc(blocks*rsa_size + 1);
}
else {
enc = (unsigned char*)malloc((blocks+1)*rsa_size + 1);
}
for (i = 0; i < blocks; i++) {
if (0 > (curr_len = RSA_private_decrypt(block_size , msg + i*block_size, enc + i*rsa_size, privKey, RSA_PKCS1_PADDING))) {
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
enc_len += curr_len;
}
if (0 != rest) {
if (0 > (curr_len = RSA_private_decrypt(rest , msg + i*block_size, enc + i*rsa_size, privKey, RSA_PKCS1_PADDING))) {
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
}
enc_len += curr_len;
}
if( enc_len == -1 )
printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
cout << enc;
Anyway when i run that some of the data got decrypted but i still see some weird chars as in seen in this picture
So i just want understand what i'm doing wrong ?
The solution is to use hybrid encryption !
Thnks to Artjom B. & zaph
I think you should use enc_len instead of i*rsa_size as shifter for output in RSA_private_decrypt(block_size , msg + i*block_size, enc + i*rsa_size, privKey, RSA_PKCS1_PADDING) call.

fgetwc EOF loop test fails, but 65535 OK

VS10 & MCBS:
For this I have created a file called c:\eoftest containing the text "test". The value of ch on the 5th pass in the following code is 65535 returned by fgetwc, but it does not equate to EOF, which we all know is defined in stdio.h as (-1):
#include <stdio.h>
#include <windows.h>
int main()
{
int ch;
FILE *stream = NULL;
wchar_t buf[5];
memset (buf, '\0', sizeof(buf));
stream = _wfopen(L"C:\\eoftest.txt", L"r");
for (int i = 0; (i < (sizeof(buf) - 1) && ((ch = fgetwc(stream)) != EOF) && (ch != '\0')); i++) //we are reading so last null condition mandatory
{
ungetwc(ch, stream);
buf[i] = (wchar_t)(ch = fgetwc(stream));
}
}
Replacing the condition (sic) with (ch = fgetwc(stream)) != 65535) works in this case, but what is not done to ensure the EOF test can succeed?
From MSDN documentation for fgetc, fgetwc
fgetc returns the character read as an int or returns EOF to indicate an error or end of file. fgetwc returns, as a
wint_t, the wide character that corresponds to the character read or
returns WEOF to indicate an error or end of file.
WEOF is defined as 0xFFFF which is what you substituted earlier 65535
#define WEOF ((wint_t)(0xFFFF))
So the EOF test for wide char should be changed to
if ((ch = fgetwc(stream)) != WEOF) ...
Edit
int main()
{
wchar_t buf[5];
memset(buf, '\0', sizeof(buf));
wcscpy(buf, L"1234");
FILE *stream = _wfopen(L"C:\\eoftest.txt", L"rb");
if (!stream)
{
stream = _wfopen(L"C:\\eoftest.txt", L"w+b");
if (!stream)
{
printf("cannot create file\n");
return 0;
}
fwrite((char*)buf, sizeof(buf[0]), wcslen(buf), stream);
fseek(stream, 0, 0);
}
int len = sizeof(buf) / sizeof(buf[0]);
for (int i = 0; i < len; i++)
{
wchar_t ch = fgetwc(stream);
if (ch == WEOF) break;
buf[i] = ch;
}
wprintf(L"result = %s\n", buf);
return 0;
}
Edit 2: This will print content of unicode file line by line:
int main()
{
FILE *stream = _wfopen(L"c:\\test\\test.txt", L"rb");
if (!stream) return 0;
int buflen = 256;
wchar_t* buf = (wchar_t*)malloc(buflen * sizeof(wchar_t));
if (fread(buf, 2, 1, stream))
{
if (buf[0] != 0xFEFF)
{
//BOM not detected, go back to start of file
rewind(stream);
}//else, skip the first 2 bytes
}
int i = 0, line = 0;
wint_t ch = 0;
while (ch != WEOF)
{
ch = fgetwc(stream);
if (ch == L'\n' || ch == WEOF)
{
//null-terminate the buffer at i
buf[i] = L'\0';
//trim the '\r' at the end, if any
if (i > 0 && buf[i - 1] == '\r') buf[i - 1] = L'\0';
wprintf(L"%3d %s\n", ++line, buf);
//start a new line for the next pass
i = 0;
}
else
{
buf[i] = ch;
i++;
if (i == buflen)
{
//increase buffer:
buflen += 256;
buf = (wchar_t*)realloc(buf, buflen * sizeof(wchar_t));
}
}
}
free(buf);
return 0;
}

c++ project wont connect to socket with error 10093

Why can't this program connect to the socket?
I know that WSAStartup fails, but I can't figure out how to use it.
#include "StdAfx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <string.h>
#include <errno.h>
#pragma comment(lib, "ws2_32.lib")
int sockd;
#define SocketErrno (WSAGetLastError())
#define bcopy(src,dest,len) memmove(dest,src,len)
typedef signed char int8;
typedef signed long int32;
inline int WriteInt8(char *buf, int pos, int8 value) { buf[pos] = (int8)(value); return 1; }
inline int WriteInt32(char *buf, int pos, int32 value) { buf[pos] = (int8)(value >> 24); buf[pos+1] = (int8)(value >> 16); buf[pos+2] = (int8)(value >> 8); buf[pos+3] = (int8)(value); return 4; }
inline int WriteASCII(char *start_buf, int pos, const char *start, int length) { int startPos = 0; char *buf = &start_buf[pos]; for (int i = 0; i < length; ++i) { buf[i] = start[startPos]; if (start[startPos]) ++startPos; } return length; }
size_t writen(int fd, const char *vptr, size_t n)
{
size_t nleft;
size_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0)
{
if ( (nwritten = writen(fd, ptr, nleft)) <= 0)
{
if (errno == EINTR)
nwritten = 0;
else
return(-1);
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
bool login(char *Username, char *Password, int characterID)
{
char buffer[8192];
int pos = 0;
pos += WriteInt8(buffer, pos, 0x91u);
pos += WriteInt8(buffer, pos, 58);
pos += WriteInt8(buffer, pos, 0xFFu);
pos += WriteInt8(buffer, pos, 55);
pos += WriteInt8(buffer, pos, 40);
pos += WriteASCII(buffer, pos, Username, 30);
pos += WriteASCII(buffer, pos, Password, 30);
if( writen(sockd, buffer, 65) < 65)
return false;
WriteInt8(buffer, 0, 0x5D);
WriteInt32(buffer, 65, characterID);
if( writen(sockd, buffer, 73) < 73)
return false;
return true;
}
bool connect(char *ServerAddress, int ServerPort)
{
struct sockaddr_in servaddr;
if ( (sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
return false;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(ServerPort);
if ( inet_pton(AF_INET, ServerAddress, &servaddr.sin_addr) <= 0 )
return false;
if ( connect(sockd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 )
return false;
char seed[4] = { 0x3au, 0xFFu, 55, 40 };
if( writen(sockd, seed, 4) < 0)
return false;
return true;
}
int main(int argc, char * argv[])
{
bool wArgs = true;
if (argc == 1)
{
wArgs = false;
}
else if (argc != 4)
{
printf("USAGE: %s User Password CharacterNumber\n", argv[0]);
return 51;
}
printf("stuff");
char *user = new char[20];
char *pass = new char[20];
int pg;
if (wArgs)
{
user = argv[1];
pass = argv[2];
pg = atoi(argv[3]);
}
else
{
printf("*****************************************\n\nUser: ");
scanf("%s", user);
printf("Pass: ");
scanf("%s", pass);
printf("Character Number: ");
scanf("%d", &pg);
printf("\n*****************************************\n");
}
if (!connect("ip hidden,port hidden))
{
printf("Error at socket(): %ld\n", WSAGetLastError());
return 1;
}
if (!login(user, pass, pg))
return 103;
char version[12] = { 0xBDu, 0x00u, 0x0Cu, 0x36u, 0x2Eu, 0x30u, 0x2Eu, 0x31u, 0x2Eu, 0x31u, 0x30u, 0x00 };
if ( writen(sockd, version, 12) < 0 )
return 105;
for(;;)
{
//12 00 09 24 32 31 20 30 00 ...l.....$21 0.
char refresh[9] = { 0x12, 0x00, 0x09, 0x24, 0x32, 0x31, 0x20, 0x30, 0x00 };
if( writen(sockd, refresh, 9) < 0)
return 104;
Sleep(40);
}
return 1;
}
10093 is WSANOTINITIALISED, which means WSAStartup() has not been called yet. The documentation for WSAStartup is pretty clear, if a bit verbose, and even includes a fairly complete example.
You must call WSAStartup before using any other Winsock functions:
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
You may also want to checkout out the WinSock FAQ when learning to do WinSock programming.