Format
This commit is contained in:
@@ -7,42 +7,41 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
ssize_t read_keyboard_misc_device(struct file *file, char __user *buf, size_t count, loff_t *ppos);
|
||||
ssize_t read_keyboard_misc_device(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
irqreturn_t key_logger_isr(int i, void *dummy);
|
||||
|
||||
enum state {
|
||||
PRESSED = true,
|
||||
RELEASED = false,
|
||||
PRESSED = true,
|
||||
RELEASED = false,
|
||||
};
|
||||
|
||||
struct KeyboardCaptureData {
|
||||
uint64_t code;
|
||||
char *key_name;
|
||||
enum state state;
|
||||
char ascii_value;
|
||||
uint64_t code;
|
||||
char *key_name;
|
||||
enum state state;
|
||||
char ascii_value;
|
||||
};
|
||||
|
||||
struct linked_list_node {
|
||||
struct KeyboardCaptureData key;
|
||||
struct timespec64 when;
|
||||
size_t size;
|
||||
struct list_head list;
|
||||
struct KeyboardCaptureData key;
|
||||
struct timespec64 when;
|
||||
size_t size;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct logger {
|
||||
char shifted;
|
||||
char capslocked;
|
||||
char shifted;
|
||||
char capslocked;
|
||||
};
|
||||
|
||||
|
||||
#ifndef EXTERN
|
||||
# define EXTERN extern
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
extern struct list_head keyboard_log;
|
||||
extern struct mutex lock;
|
||||
|
||||
|
||||
void print_keyboard_line(struct KeyboardCaptureData data);
|
||||
size_t calc_node_size(struct linked_list_node *node);
|
||||
void print_keyboard_line(struct KeyboardCaptureData data);
|
||||
size_t calc_node_size(struct linked_list_node *node);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
74
src/main.c
74
src/main.c
@@ -12,60 +12,62 @@
|
||||
#define KEYBOARD_IRQ 1
|
||||
|
||||
static const struct file_operations fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = read_keyboard_misc_device,
|
||||
.owner = THIS_MODULE,
|
||||
.read = read_keyboard_misc_device,
|
||||
};
|
||||
|
||||
static struct miscdevice device = {
|
||||
.fops = &fops,
|
||||
.name = "drivers_and_interrupts",
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.mode = 0444,
|
||||
.fops = &fops,
|
||||
.name = "drivers_and_interrupts",
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.mode = 0444,
|
||||
};
|
||||
|
||||
struct mutex lock = __MUTEX_INITIALIZER(lock);
|
||||
static struct logger key_logger = { 0, 0 };
|
||||
static struct logger key_logger = { 0, 0 };
|
||||
|
||||
static int __init m_init(void) {
|
||||
struct linked_list_node *ptr, *tmp;
|
||||
int err = 0;
|
||||
static int __init m_init(void)
|
||||
{
|
||||
struct linked_list_node *ptr, *tmp;
|
||||
int err = 0;
|
||||
printk(KERN_INFO "Drivers and Interrupts (init)\n");
|
||||
|
||||
if (request_irq(1, key_logger_isr, IRQF_SHARED, "i8042", &key_logger)) {
|
||||
err = -EBUSY;
|
||||
goto err_free_linked_list;
|
||||
}
|
||||
if (misc_register(&device)) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_keyboard_notifier;
|
||||
if (request_irq(1, key_logger_isr, IRQF_SHARED, "i8042", &key_logger)) {
|
||||
err = -EBUSY;
|
||||
goto err_free_linked_list;
|
||||
}
|
||||
mutex_init(&lock);
|
||||
if (misc_register(&device)) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_keyboard_notifier;
|
||||
}
|
||||
mutex_init(&lock);
|
||||
return 0;
|
||||
|
||||
err_free_keyboard_notifier:
|
||||
free_irq(1, &key_logger);
|
||||
free_irq(1, &key_logger);
|
||||
err_free_linked_list:
|
||||
list_for_each_entry_safe(ptr, tmp, &keyboard_log, list) {
|
||||
list_del(&ptr->list);
|
||||
kfree(ptr);
|
||||
}
|
||||
return err;
|
||||
list_for_each_entry_safe(ptr, tmp, &keyboard_log, list) {
|
||||
list_del(&ptr->list);
|
||||
kfree(ptr);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit m_exit(void) {
|
||||
struct linked_list_node *ptr, *tmp;
|
||||
static void __exit m_exit(void)
|
||||
{
|
||||
struct linked_list_node *ptr, *tmp;
|
||||
|
||||
misc_deregister(&device);
|
||||
size_t len = 0;
|
||||
misc_deregister(&device);
|
||||
size_t len = 0;
|
||||
|
||||
list_for_each_entry_safe(ptr, tmp, &keyboard_log, list){
|
||||
len++;
|
||||
list_del(&ptr->list);
|
||||
kfree(ptr);
|
||||
}
|
||||
printk(KERN_INFO "Captured %zu Keyboard inputs", len);
|
||||
free_irq(1,&key_logger);
|
||||
mutex_destroy(&lock);
|
||||
list_for_each_entry_safe(ptr, tmp, &keyboard_log, list) {
|
||||
len++;
|
||||
list_del(&ptr->list);
|
||||
kfree(ptr);
|
||||
}
|
||||
printk(KERN_INFO "Captured %zu Keyboard inputs", len);
|
||||
free_irq(1, &key_logger);
|
||||
mutex_destroy(&lock);
|
||||
printk(KERN_INFO "Drivers and Interrupts (exit)\n");
|
||||
}
|
||||
|
||||
|
@@ -4,72 +4,84 @@
|
||||
|
||||
#include "drivers_and_interrupts.h"
|
||||
|
||||
size_t calc_node_size(struct linked_list_node *node) {
|
||||
size_t size = 14;
|
||||
if (node->key.state == PRESSED) {
|
||||
size += 7;
|
||||
} else {
|
||||
size += 8;
|
||||
}
|
||||
if (node->key.ascii_value) {
|
||||
size += 6;
|
||||
}
|
||||
size += strlen(node->key.key_name);
|
||||
node->size = size;
|
||||
return size;
|
||||
size_t calc_node_size(struct linked_list_node *node)
|
||||
{
|
||||
size_t size = 14;
|
||||
if (node->key.state == PRESSED) {
|
||||
size += 7;
|
||||
} else {
|
||||
size += 8;
|
||||
}
|
||||
if (node->key.ascii_value) {
|
||||
size += 6;
|
||||
}
|
||||
size += strlen(node->key.key_name);
|
||||
node->size = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t read_keyboard_misc_device(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct linked_list_node *tmp;
|
||||
loff_t node_offset = *ppos;
|
||||
|
||||
ssize_t read_keyboard_misc_device(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
|
||||
struct linked_list_node *tmp;
|
||||
loff_t node_offset = *ppos;
|
||||
mutex_lock(&lock);
|
||||
list_for_each_entry(tmp, &keyboard_log, list) {
|
||||
if (node_offset < tmp->size) {
|
||||
break;
|
||||
}
|
||||
node_offset -= tmp->size;
|
||||
}
|
||||
if (node_offset > tmp->size) {
|
||||
mutex_unlock(&lock);
|
||||
return 0;
|
||||
}
|
||||
// if (count > len - *ppos) {
|
||||
// count = len - *ppos;
|
||||
// }
|
||||
|
||||
mutex_lock(&lock);
|
||||
list_for_each_entry(tmp, &keyboard_log, list) {
|
||||
if (node_offset < tmp->size) {
|
||||
break;
|
||||
}
|
||||
node_offset -= tmp->size;
|
||||
}
|
||||
if (node_offset > tmp->size) {
|
||||
printk("early exit\n");
|
||||
return 0;
|
||||
}
|
||||
// if (count > len - *ppos) {
|
||||
// count = len - *ppos;
|
||||
// }
|
||||
size_t user_offset = 0;
|
||||
for (; !list_entry_is_head(tmp, &keyboard_log, list);
|
||||
tmp = list_next_entry(tmp, list)) {
|
||||
char sec =
|
||||
(tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) % 60;
|
||||
char min = (tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) /
|
||||
60 % 60;
|
||||
char hour = (tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) /
|
||||
60 / 60 % 24;
|
||||
char *buffer = kmalloc(sizeof(char) * tmp->size, GFP_KERNEL);
|
||||
if (!buffer) {
|
||||
mutex_unlock(&lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(buffer, 0, tmp->size);
|
||||
snprintf(buffer, tmp->size, "%02d:%02d:%02d \"%s\"", hour, min,
|
||||
sec, tmp->key.key_name);
|
||||
if (tmp->key.ascii_value) {
|
||||
snprintf(buffer + strlen(buffer),
|
||||
tmp->size - strlen(buffer), "(0x%02x) ",
|
||||
tmp->key.ascii_value);
|
||||
}
|
||||
if (tmp->key.state == PRESSED) {
|
||||
snprintf(buffer + strlen(buffer),
|
||||
tmp->size - strlen(buffer), "PRESSED\n");
|
||||
} else {
|
||||
snprintf(buffer + strlen(buffer),
|
||||
tmp->size - strlen(buffer), "RELEASED\n");
|
||||
}
|
||||
|
||||
size_t user_offset = 0;
|
||||
for (; !list_entry_is_head(tmp, &keyboard_log, list); tmp = list_next_entry(tmp, list)) {
|
||||
char sec = (tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) % 60;
|
||||
char min = (tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) / 60 % 60;
|
||||
char hour = (tmp->when.tv_sec - (sys_tz.tz_minuteswest * 60)) / 60 / 60 % 24;
|
||||
char *buffer = kmalloc(sizeof(char) * tmp->size, GFP_KERNEL);
|
||||
if (!buffer) {
|
||||
mutex_unlock(&lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(buffer, 0, tmp->size);
|
||||
snprintf(buffer, tmp->size, "%02d:%02d:%02d \"%s\"", hour, min, sec, tmp->key.key_name);
|
||||
if (tmp->key.ascii_value) {
|
||||
snprintf(buffer + strlen(buffer), tmp->size - strlen(buffer), "(0x%02x) ", tmp->key.ascii_value);
|
||||
}
|
||||
if (tmp->key.state == PRESSED) {
|
||||
snprintf(buffer + strlen(buffer), tmp->size - strlen(buffer), "PRESSED\n");
|
||||
} else {
|
||||
snprintf(buffer + strlen(buffer), tmp->size - strlen(buffer), "RELEASED\n");
|
||||
}
|
||||
|
||||
if (copy_to_user(buf + user_offset, buffer + node_offset, tmp->size - node_offset)) {
|
||||
kfree(buffer);
|
||||
mutex_unlock(&lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(buffer);
|
||||
user_offset += tmp->size - node_offset;
|
||||
node_offset = 0;
|
||||
}
|
||||
*ppos += (long long)user_offset;
|
||||
mutex_unlock(&lock);
|
||||
return (long long)user_offset;
|
||||
}
|
||||
if (copy_to_user(buf + user_offset, buffer + node_offset,
|
||||
tmp->size - node_offset)) {
|
||||
kfree(buffer);
|
||||
mutex_unlock(&lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(buffer);
|
||||
user_offset += tmp->size - node_offset;
|
||||
node_offset = 0;
|
||||
}
|
||||
*ppos += (long long)user_offset;
|
||||
mutex_unlock(&lock);
|
||||
return (long long)user_offset;
|
||||
}
|
||||
|
Reference in New Issue
Block a user