Initial commit
This commit is contained in:
commit
d47ef530f0
|
@ -0,0 +1,9 @@
|
||||||
|
attic/
|
||||||
|
.ccls-cache/
|
||||||
|
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
*.o
|
||||||
|
|
||||||
|
actionpro
|
||||||
|
config.h
|
|
@ -0,0 +1,34 @@
|
||||||
|
# ACTIONPRO Makefile
|
||||||
|
|
||||||
|
include config.mk
|
||||||
|
|
||||||
|
PRG = actionpro
|
||||||
|
SRC = main.c
|
||||||
|
OBJ = ${SRC:.c=.o}
|
||||||
|
BIN = ${OBJ:.o=}
|
||||||
|
|
||||||
|
all: options ${PRG}
|
||||||
|
|
||||||
|
options:
|
||||||
|
@echo ${PRG} compile options:
|
||||||
|
@echo "CFLAGS = ${CFLAGS}"
|
||||||
|
@echo "LDFLAGS = ${LDFLAGS}"
|
||||||
|
@echo "CC = ${CC}"
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
@${CC} -c ${CFLAGS} $<
|
||||||
|
|
||||||
|
${OBJ}: config.h config.mk
|
||||||
|
|
||||||
|
config.h:
|
||||||
|
@echo creating $@ from config.def.h
|
||||||
|
@cp config.def.h $@
|
||||||
|
|
||||||
|
${PRG}: ${OBJ}
|
||||||
|
${CC} -o ${PRG} ${OBJ} ${LDFLAGS}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo cleaning
|
||||||
|
@rm -f ${BIN} ${OBJ}
|
||||||
|
|
||||||
|
.PHONY: all options clean
|
|
@ -0,0 +1,124 @@
|
||||||
|
# ACTIONPRO X7
|
||||||
|
|
||||||
|
## Research
|
||||||
|
|
||||||
|
## Research: File/Drive Access by Action Manager 1.3
|
||||||
|
|
||||||
|
Opening Drive/Device:
|
||||||
|
```
|
||||||
|
CreateFile():
|
||||||
|
Desired Access: Generic Read/Write
|
||||||
|
Disposition: Open
|
||||||
|
Options: Synchronous IO Non-Alert, Non-Directory File
|
||||||
|
Attributes: n/a
|
||||||
|
ShareMode: Read, Write
|
||||||
|
AllocationSize: n/a
|
||||||
|
OpenResult: Opened
|
||||||
|
```
|
||||||
|
|
||||||
|
Sending Command:
|
||||||
|
Windows Application sends `IOCTL_SCSI_PASS_THROUGH` with `DeviceIoControl()`.
|
||||||
|
|
||||||
|
|
||||||
|
### Research: Code Snippets using ioctl()
|
||||||
|
|
||||||
|
Code example #1:
|
||||||
|
```
|
||||||
|
#define DEF_TIMEOUT 5000 // 5 seconds
|
||||||
|
char cDiskName[] = "/dev/sg3";
|
||||||
|
int fd = open(cDiskName, O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("Open error: %s, errno=%d (%s)\n", cDiskName, errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char turCmbBlk[] = {0x00, 0, 0, 0, 0, 0};
|
||||||
|
struct sg_io_hdr io_hdr;
|
||||||
|
|
||||||
|
unsigned char cIOBuffer[100];
|
||||||
|
|
||||||
|
// buffer initialization code omitted
|
||||||
|
|
||||||
|
memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
|
||||||
|
io_hdr.interface_id = 'S';
|
||||||
|
io_hdr.cmd_len = sizeof(turCmbBlk);
|
||||||
|
io_hdr.mx_sb_len = sizeof(cIOBuffer);
|
||||||
|
io_hdr.dxfer_direction = SG_DXFER_NONE;
|
||||||
|
io_hdr.cmdp = turCmbBlk;
|
||||||
|
io_hdr.sbp = cIOBuffer;
|
||||||
|
io_hdr.timeout = DEF_TIMEOUT;
|
||||||
|
if (ioctl(fd, SG_IO, &io_hdr) < 0)
|
||||||
|
{
|
||||||
|
printf("ioctl error: errno=%d (%s)\n", errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returned here without any errors but cIOBuffer remains unchanged.
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/usbdevice_fs.h>
|
||||||
|
|
||||||
|
void main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
|
fd = open(filename, O_WRONLY);
|
||||||
|
ioctl(fd, USBDEVFS_RESET, 0);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#define BUFF_SIZE 100 // - Buffersize
|
||||||
|
|
||||||
|
#define DEF_TIMEOUT 5000 // 5 seconds
|
||||||
|
char cDiskName[] = "/dev/sg3";
|
||||||
|
int fd = open(cDiskName, O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("Open error: %s, errno=%d (%s)\n", cDiskName, errno, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char turCmbBlk[] = {0x00, 0, 0, 0, 0, 0};
|
||||||
|
struct sg_io_hdr *p = (struct sg_io_hdr *) malloc(sizeof(struct sg_io_hdr)); // - dynamic memory allocation - free() required somewhere
|
||||||
|
|
||||||
|
unsigned char cIOBuffer[BUFF_SIZE];
|
||||||
|
unsigned char replyBuffer[BUFF_SIZE]; // - dxfer buffer
|
||||||
|
|
||||||
|
// buffer initialization code omitted
|
||||||
|
|
||||||
|
memset(p, 0, sizeof(struct sg_io_hdr));
|
||||||
|
p->interface_id = 'S';
|
||||||
|
p->cmd_len = sizeof(turCmbBlk);
|
||||||
|
p->mx_sb_len = BUFF_SIZE;
|
||||||
|
p->dxfer_direction = SG_DXFER_NONE;
|
||||||
|
p->cmdp = turCmbBlk;
|
||||||
|
p->sbp = cIOBuffer;
|
||||||
|
p->timeout = DEF_TIMEOUT;
|
||||||
|
p->flags = SG_FLAG_DIRECT_IO; // - Does this help?
|
||||||
|
p->dxferp = replyBuffer; // - Set dxferp buffer - (A)
|
||||||
|
p->dxfer_len = BUFF_SIZE; // - buffersize
|
||||||
|
|
||||||
|
if (ioctl(fd, SG_IO, p) < 0)
|
||||||
|
{
|
||||||
|
printf("ioctl error: errno=%d (%s)\n", errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returned here without any errors but cIOBuffer remains unchanged.
|
||||||
|
```
|
||||||
|
|
||||||
|
Use for `scsi/sg.h` and `ioctl`.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef config_h
|
||||||
|
#define config_h
|
||||||
|
|
||||||
|
/* defaults */
|
||||||
|
|
||||||
|
/* device information */
|
||||||
|
#define VENDOR_ID 0x4255
|
||||||
|
#define PRODUCT_ID 0x1000
|
||||||
|
|
||||||
|
#endif /* config_h */
|
|
@ -0,0 +1,10 @@
|
||||||
|
# includes and libs
|
||||||
|
INCS = -I. -I/usr/include
|
||||||
|
LIBS = -L/usr/lib -lusb-1.0
|
||||||
|
|
||||||
|
# flags
|
||||||
|
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS}
|
||||||
|
LDFLAGS = -s ${LIBS}
|
||||||
|
|
||||||
|
# compiler and linker
|
||||||
|
CC = cc
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libusb-1.0/libusb.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static struct libusb_device_handle *devh = NULL;
|
||||||
|
|
||||||
|
static libusb_device_handle *open_actionpro()
|
||||||
|
{
|
||||||
|
ssize_t devc;
|
||||||
|
libusb_device **dev_list;
|
||||||
|
static libusb_device *dev = NULL;
|
||||||
|
struct libusb_device_descriptor dev_desc;
|
||||||
|
struct libusb_config_descriptor *dev_conf = NULL;
|
||||||
|
const struct libusb_interface *iface = NULL;
|
||||||
|
const struct libusb_interface_descriptor *iface_desc = NULL;
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
devc = libusb_get_device_list(NULL, &dev_list);
|
||||||
|
if (devc < 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < devc; i++) {
|
||||||
|
dev = dev_list[i];
|
||||||
|
if (libusb_get_device_descriptor(dev, &dev_desc)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dev_desc.idVendor != VENDOR_ID || dev_desc.idProduct != PRODUCT_ID)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = libusb_open(dev, &devh);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("libusb_open");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < dev_desc.bNumConfigurations; j++) {
|
||||||
|
if (libusb_get_config_descriptor(dev, j, &dev_conf)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < dev_conf->bNumInterfaces; k++) {
|
||||||
|
iface = &dev_conf->interface[k];
|
||||||
|
for (int l = 0; l < iface->num_altsetting; l++) {
|
||||||
|
iface_desc = &iface->altsetting[l];
|
||||||
|
if (libusb_kernel_driver_active(devh, iface_desc->bInterfaceNumber)) {
|
||||||
|
libusb_detach_kernel_driver(devh, iface_desc->bInterfaceNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_set_configuration(devh, dev_conf->bConfigurationValue);
|
||||||
|
libusb_claim_interface(devh, iface_desc->bInterfaceNumber);
|
||||||
|
|
||||||
|
int e = 0;
|
||||||
|
while (libusb_claim_interface(devh, iface_desc->bInterfaceNumber) && (e < 10)) {
|
||||||
|
sleep(1);
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_free_config_descriptor(dev_conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return devh;
|
||||||
|
}
|
||||||
|
|
||||||
|
devh = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
res = libusb_init(NULL);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("libusb_init");
|
||||||
|
fprintf(stderr, "Error: %s\n", libusb_strerror(res));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!open_actionpro()) {
|
||||||
|
fprintf(stderr, "Error opening device, no ACTIONPRO X7 found!\n");
|
||||||
|
libusb_exit(NULL);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_exit(NULL);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
Loading…
Reference in New Issue