How to capture raw keyboard input on Windows - c

I have a device that acts like a HID (keyboard). I was able to capture and grab the raw input of the device on Linux. I needed to get exclusive rights to the device so that no other application could receive input from it. I accomplished this using ioctl and EVIOCGRAB
But it doesn't compile under Windows. I have found that there is a RegisterRawInputDevices function but it doesn't seem to provide exclusive rights to the device. What could be used on Windows to achieve the same effect?
Here is my code that works on Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
int main(int argc, char* argv[])
{
struct input_event ev[64];
int fevdev = -1;
int result = 0;
int size = sizeof(struct input_event);
int rd;
int value;
char name[256] = "Unknown";
char *device = "/dev/input/event16";
fevdev = open(device, O_RDONLY);
ioctl(fevdev, EVIOCGRAB, 1);
while (1)
{
read(fevdev, ev, size * 64);
value = ev[0].value;
printf ("code - %d \n", ev[1].code);
}
ioctl(fevdev, EVIOCGRAB, 0);
close(fevdev);
}

Related

Not able to pass strings through named pipes (FIFOs) in multithreaded processes

I am trying to use 'FIFOs' and 'popen()' function for communication between multiple processes. Also, the first process is multithreaded for reading and writing operations.
Following is the C code for the processes:
P1 process (Q1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
void* reader()
{
char string[64];
int rfd = open("FIFO",O_RDONLY);
while(1)
{
read(rfd,string,sizeof(string));
sleep(10);
printf("%s\n",string);
}
}
void* writer()
{
char string[64];
FILE *wfd = popen("./Q1_1","w");
int fd = fileno(wfd);
while(1)
{
scanf("%s",string);
write(fd,string,sizeof(string));
}
pclose(wfd);
}
int main()
{
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
pthread_t r_thread,s_thread;
pthread_create(&r_thread,NULL,reader,NULL);
pthread_create(&s_thread,NULL,writer,NULL);
pthread_join(r_thread,NULL);
pthread_join(s_thread,NULL);
return 0;
}
P2 Process (Q1_1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
FILE *fd = popen("./Q1_2","w");
char string[64];
int ffd = fileno(fd);
printf("P2Check");
while(1)
{
scanf("%s",string);
write(ffd,string,sizeof(string));
}
return 0;
}
P3 Process (Q1_2.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
char string[64];
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
int wfd = open("FIFO",O_WRONLY);
printf("P3Check");
while(1)
{
scanf("%s",string);
write(wfd,string,sizeof(string));
}
}
However, after executing process P1 and providing input, there is no output as if the process is stuck. I suspect there is some issue with the multithreading but not sure.

Reading huge amount of data throught i2c

I am trying to receive huge amount of data throught i2c. Here is my code. The main problem is that it takes more than 2 seconds when i need to let it be done in less than 0.5 sec. Here is the device: https://www.st.com/resource/en/datasheet/lsm6ds33.pdf
image with i2c interface
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <time.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdint.h>
#include <stddef.h>
#define FIFO_DATA_OUT_L 0x3E
#define FIFO_DATA_OUT_H 0X3F
struct timeval stop, start;
int main()
{
uint8_t addressL = FIFO_DATA_OUT_L;
uint8_t addressH = FIFO_DATA_OUT_H;
uint8_t resultL;
uint8_t resultH;
int16_t result;
gettimeofday(&start,NULL);
int fd;
if ((fd = open("/dev/i2c-0",O_RDWR))< 0)
{
perror("failed to connect to i2c");
exit(0);
}
ioctl(fd,I2C_SLAVE,0x6b);// Setting slave address
long i;
for (i=0; i< 2499; i++)
{
write(fd,&addressL,1);
read(fd,&resultL,1);
write(fd,&addressH,1);
read(fd,&resultH,1);
result = (resultH << 8) | resultL;
}
gettimeofday(&stop,NULL);
printf("Time elapsed: %d \n",stop.tv_sec-start.tv_sec);
return;
}
I am wondering if there is some possibility to make things faster. Cheers.
I think your FIFO size is 2 Byte then you can write/read 2 Byte each time instead of 1.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <time.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdint.h>
#include <stddef.h>
#define FIFO_DATA_OUT_L 0x3E
#define FIFO_DATA_OUT_H 0X3F
struct timeval stop, start;
int main()
{
uint8_t addressL = FIFO_DATA_OUT_L;
uint8_t addressH = FIFO_DATA_OUT_H;
uint16_t result;
gettimeofday(&start,NULL);
int fd;
if ((fd = open("/dev/i2c-0",O_RDWR))< 0)
{
perror("failed to connect to i2c");
exit(0);
}
ioctl(fd,I2C_SLAVE,0x6b);// Setting slave address
long i;
for (i=0; i< 1250; i++)
{
write(fd,&addressL,2);
read(fd,&result,2);
}
gettimeofday(&stop,NULL);
printf("Time elapsed: %d \n",stop.tv_sec-start.tv_sec);
return;
}

C - Scanf not blocking for named pipe / FIFO

Usually when a program call a scanf it waits until something is available in stdin to read from it. I am currently making a fifo for input and another one for output that will be used by another process to write an read from a background proccess. But, the background process seem not to wait for any scanf in it, does anyone know why?
Here is the code:
Background:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in, err;
char *cFifo = "/tmp/out";
char *cInFifo = "/tmp/in";
mkfifo(cFifo, S_IRUSR|S_IWUSR);
mkfifo(cInFifo, S_IRUSR|S_IWUSR);
out = open(cFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
in = open(cInFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
dup2(out, STDOUT_FILENO);
dup2(out, STDERR_FILENO);
dup2(in, STDIN_FILENO);
scanf("%*c");
while(1)
{
scanf("%*c");
printf("Hello\n");
fflush(stdout);
}
return 0;
}
Foreground:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in;
size_t i = 0;
char bufOut[1024];
char *cFifo = "/tmp/out";
char *cFifoIn = "/tmp/in";
out = open(cFifo, O_RDONLY);
in = open(cFifoIn, O_WRONLY);
while(1)
{
i =0;
while(!i)
{
i = read(out, bufOut, 1024);
}
if(i)
write(STDOUT_FILENO, bufOut, i);
}
return 0;
}
I have already tried to force write on the new input fifo but the result is the same.
I already checked for errors, and everything return the expected values, no -1 or any other errors associated with each function

Kill() function between two processes

Can I use the kill() function to send a signal to another process? It should be possible, but kill() fails and I can't understand why.
I have two programs (process_1 and process_2). The first one should set a signal handler to increase a variable, than create a child that uses execve and loads process_2. The other program should send the signal using kill(). I used the shared memory to share process_1's pid through a struct (because I have other variables to share). The code of the first program is as follows:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
static int value_to_change=0;
typedef struct keys{
pid_t pid_process;
}keynote;
static void test_handler(int signo){
if(signo=SIGUSR1){
printf("received SIGUSR1\n");
value_to_change++;
}
}
int main(){
if((signal(SIGUSR1, test_handler))==SIG_ERR) perror("Errore allocazione SIGUSR1");
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
chv->pid_process=getpid();
printf("%d\n",chv->pid_process);
int process_2;
process_2=fork();
if(process_2==0){
char* argv[]={"process_1", "process_2", NULL};
if((execve("process_2", argv, NULL))<0) perror("execve error");
exit(0);
}else if(process_2<0)perror("fork error");
return 0;
}
The second program code is:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
typedef struct keys{
pid_t pid_process;
}keynote;
static void signal_to_send(pid_t process){
int ret=kill(process, SIGUSR1);
printf("%d", ret);
}
}
int main(int argc, char **argv){
int pid_of_process_1;
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
signal_to_send(chv->pid_process);
return 0;
}
process_1 does not wait for process_2. It just exits immediately. At which point process_2 may not even have started. So when process_2 sends the signal, process_1 is likely to not exist anymore.
– kaylum

usage of lsetxattr and lgetxattr functions

I wrote a simple program to test lsetxattr() and lgetxattr() functions.
I just wanted to add an extended property to this file, and get the value again.
But I can't get the result as expected.
So what's the right way to use these two methods?
Thanks!
#define _GNU_SOURCE
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <time.h>
#include <unistd.h>
int main()
{
char *path = "/tmp/abc.txt";
FILE *file = fopen(path, "w");
int id = 101;
if (lsetxattr(path, "user.id", &id, sizeof(int), 0) < 0)
printf("lsetxattr wrong\n");
int result;
if (lgetxattr(path, "user.id", &result, sizeof(int)) != sizeof(int)) {
printf("lgetxattr wrong\n");
}
printf("%d\n", result);
return 0;
}
This is likely because your /tmp mount does not support extended attributes. Looking at the man page:
ENOTSUP
Extended attributes are not supported by the file system, or are
disabled, errno is set to ENOTSUP.
You can verify this by changing the path to be outside of that mount, such as in the current directory (assuming it's outside of that mount of course):
char *path = "abc.txt";
Assuming your other mounts do support extended attributes of course (this is more likely). If you have to do it on /tmp, then you'll have to look at some manuals to figure out how to enable it on /tmp (tmpfs).
Looks like both lsetxattr() and lgetxatter() return -1 by default:
#include <errno.h>
#include <sys/xattr.h>
ssize_t
lgetxattr (const char *__path, const char *__name,
void *__value, size_t __size)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (lgetxattr)
#include <stub-tag.h>
I found this on glibc's source code: lgetxattr.c and lsetxattr.c

Resources