I genuinely can't figure this out. When I run this program in the debugger, it all works until the final line, which contains return 0;
. For some reason I can't figure out, it causes an exception in the Visual Studio debugger when going past a breakpoint I put on it. When running the executable from the command line without VS, a vague assertion is triggered. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "..\sui.h"
typedef struct {
char* data;
} string;
string GetDataFromDictionary(char* dict, char* dividor, int index) {
char* r1 = calloc(20, 1);
if (!r1) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
r1 = strstr(dict, dividor);
for (int i = 0; i < index - 1; i++) {
r1 = strstr(&r1[1], dividor);
}
char* r2 = calloc(20, 1);
if (!r2) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
strcpy(r2, strstr(dict, dividor));
for (int i = 0; i < index - 1 + 1; i++) {
strcpy(r2, strstr(&r2[1], dividor));
}
int len = strlen(r1) - strlen(r2) - 1;
string r;
r.data = calloc(30, 1);
if (!r.data) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
strncpy(r.data, &r1[1], len);
return r;
}
int GetCountOfDictionaryValues(char* dict) {
int charcount;
charcount = 0;
for (int i = 0; dict[i]; i++) {
if (dict[i] == '~') {
charcount++;
}
}
return charcount - 1;
}
int main(int argc, char* argv[]) {
// Read file
char ch;
FILE* fp = fopen(argv[1], "r"); // Nice
if (argc != 2) {
printf("Invalid argument count! Expected 1 argument, got %i", argc - 1);
exit(EXIT_FAILURE);
}
if (fp == NULL) {
printf("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int i = 0;
char* buf = calloc(20000, 1);
if (!buf) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
while ((ch = fgetc(fp)) != EOF) {
buf[i] = ch;
i++;
}
fclose(fp);
// Organise data
char* parsedata = calloc(10000, 2);
if (parsedata == NULL) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
parsedata[0] = '~';
for (int x = 1, o = 1; x < (int)strlen(buf); x++) {
if (buf[x-o] == ' ') {
parsedata[x] = '~';
} else if (buf[x - o] == ';') {
parsedata[x] = '~';
} else if (buf[x - o] == '\n') {
o--;
x--;
} else {
if (buf[x - o] < 91 && buf[x - o] > 64) {
parsedata[x] = buf[x - o] + ' ';
} else {
parsedata[x] = buf[x - o];
}
}
}
// Execute stuff :D
SUIInit(INPUT_KEYBOARD);
string rip;
rip.data = calloc(30, 1);
if (!rip.data) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
for (int i = 1; i < GetCountOfDictionaryValues(parsedata) + 1; i++) {
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
if (!strcmp(rip.data, "movecursor")) {
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);
int x = 0;
int y = 0;
char* e;
int index = 0;
e = strchr(rip.data, 'x');
index = (int)(e - rip.data);
e = calloc(30, 1);
if (!e) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
strncpy(e, rip.data, index);
e[19] = 0;
x = atoi(e);
free(e);
e = calloc(30, 1);
if (!e) {
printf("Calloc() failed!");
exit(EXIT_FAILURE);
}
for (int i = 0; i < 4; i++) {
e[i] = 0;
}
strncpy(e, &rip.data[index + 1], strlen(rip.data));
e[19] = 0;
y = atoi(e);
SUIInit(INPUT_MOUSE);
SUIMoveCursor(x, y);
SUIInit(INPUT_KEYBOARD);
free(e);
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
} else if (!strcmp(rip.data, "presskey")) {
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);
char key = atoi(rip.data) - 32;
if (rip.data[0] > 65) {
key = rip.data[0];
if (key > 96 && key < 123) {
key -= 32;
}
}
SUIPressKey(key);
// 200 lines D:
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
} else if (!strcmp(rip.data, "click")) {
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i + 1).data);
SUIInit(INPUT_MOUSE);
if (!strcmp(rip.data, "left")) {
SUIClickMouse(MOUSE_LEFT_CLICK);
} else if (!strcmp(rip.data, "right")) {
SUIClickMouse(MOUSE_RIGHT_CLICK);
} else {
printf("Invalid mouse button \"%s\"! Terminating program...", rip.data);
exit(EXIT_FAILURE);
}
SUIInit(INPUT_KEYBOARD);
strcpy(rip.data, GetDataFromDictionary(parsedata, "~", i).data);
}
}
free(rip.data);
free(buf);
free(parsedata);
return 0;
}
SUI.h:
// Single-Header Library for Simulating user input
// Putting it on GitHub so i can always download
// it if I get a new computer
#pragma once
// Defines so you dont have to remember left and right click are 1 and 2
#define MOUSE_LEFT_CLICK 1
#define MOUSE_RIGHT_CLICK 2
// Include Windows.h, wont work on unix systems ¯\_(ツ)_/¯
#ifndef _WINDOWS_
#include <Windows.h>
#endif
#ifdef __cplusplus
class SUI {
private:
// Input variable, private so nobody changes it without Init().
INPUT _input;
public:
// Function for initializing SUI
void Init(int mode) {
if (mode > 1) {
return;
}
_input.type = mode;
if (mode == 0) {
_input.mi.time = 0;
_input.mi.mouseData = 0;
_input.mi.dwExtraInfo = 0;
}
if (mode == 1) {
_input.ki.wScan = 0;
_input.ki.time = 0;
_input.ki.dwExtraInfo = 0;
}
}
// Moving cursor pos. its just SetCursorPos, but it would have been weird if we didnt have something for this ¯\_(ツ)_/¯
void MoveCursor(int x, int y) {
SetCursorPos(x, y);
}
// Click mouse button
void ClickMouse(int button) {
if (button == 1) {
_input.mi.dwFlags = 2;
SendInput(1, &_input, sizeof(INPUT));
_input.mi.dwFlags = 4;
SendInput(1, &_input, sizeof(INPUT));
} else
if (button == 2) {
_input.mi.dwFlags = 8;
SendInput(1, &_input, sizeof(INPUT));
_input.mi.dwFlags = 10;
SendInput(1, &_input, sizeof(INPUT));
} else {
return;
}
}
// Keyboard input
void PressKey(int keycode) {
if (_input.type == 0) {
return;
}
_input.ki.wVk = keycode;
_input.ki.dwFlags = 0;
SendInput(1, &_input, sizeof(INPUT));
_input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &_input, sizeof(INPUT));
}
};
#else
// Input variable
INPUT _input;
// Function for initializing SUI
void SUIInit(int mode) {
if (mode > 1) {
return;
}
_input.type = mode;
if (mode == 0) {
_input.mi.time = 0;
_input.mi.mouseData = 0;
_input.mi.dwExtraInfo = 0;
}
if (mode == 1) {
_input.ki.wScan = 0;
_input.ki.time = 0;
_input.ki.dwExtraInfo = 0;
}
}
// Moving cursor pos. its just SetCursorPos, but it would have been weird if we didnt have something for this ¯\_(ツ)_/¯
void SUIMoveCursor(int x, int y) {
SetCursorPos(x, y);
}
// Click mouse button
void SUIClickMouse(int button) {
if (button == 1) {
_input.mi.dwFlags = 2;
SendInput(1, &_input, sizeof(INPUT));
_input.mi.dwFlags = 4;
SendInput(1, &_input, sizeof(INPUT));
} else
if (button == 2) {
_input.mi.dwFlags = 8;
SendInput(1, &_input, sizeof(INPUT));
_input.mi.dwFlags = 10;
SendInput(1, &_input, sizeof(INPUT));
} else {
return;
}
}
// Keyboard input
void SUIPressKey(int keycode) {
if (_input.type == 0) {
return;
}
_input.ki.wVk = keycode;
_input.ki.dwFlags = 0;
SendInput(1, &_input, sizeof(INPUT));
_input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &_input, sizeof(INPUT));
}
#endif
And here is the exception caused:
Exception thrown at 0x779C8215 (ntdll.dll) in Macrotool32.exe: 0xC0000005: Access violation reading location 0x66656C7E.