⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ozerocdoff.c

📁 udev是一种工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Option Zero-CD Disabler or simple turn off hack  Copyright (C) 2008  Peter Henn (support@option.com)  Note, most of the part coming from  Josua Dietze usb_modeswitch  We use this way to disable the ZeroCD device, because we have seen some  problems during the USB-SCSI device "unplug" and "SCSI disconnect", which  may result into a complete aystem freezes. Although this disabling of the  Zero-CD device is a simple SCSI rezero command, the WWAN-modem firmware  does sometimes not correctly do a "SCSI discnnection" to the USB SCSI  driver, before it just plug off from the SCSI bus and does require a  USB reenumeration with the WWAN-modem USB interfaces instead of the USB  SCSI CD-ROM device.  Unbinding the USB SCSI driver and sending the USB rezero command simple by  the usage of the libusb directly from user space solve this time critical  handling between the SCSI driver and the firmware.  History:  0.1, 2008/04/10 P.Henn       - Initial version with usage of code example from usb_modeswitch  0.2, 2008/04/14 P.Henn       - several bugfixes       - autosetup endpoint address       - ensure support for three firmware classes  0.3, 2008/04/15 P.Henn       - first optional filename compare support  0.4, 2008/06/09 P-Henn       - add log file functionality       - add harder Zero-CD device search phase, if /sys/class/usb_device         is not supported       - add search try option  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details:  http://www.gnu.org/licenses/gpl.txt*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <assert.h>#include <signal.h>#include <ctype.h>#include <stdarg.h>#include <getopt.h>#include <usb.h>#include <dirent.h>#define VERSION "0.4"#define TARGET_VENDOR 0x0af0#define BUFFER_SIZE 65535// some defines lend from the /usr/include/linux/usb/ch9.h#define USB_ENDPOINT_XFERTYPE_MASK      0x03    /* in bmAttributes */#define USB_ENDPOINT_XFER_BULK          2#define USB_ENDPOINT_DIR_MASK           0x80#define USB_DIR_OUT                     0       /* to device */#define USB_DIR_IN                      0x80    /* to host */#define UDEV_POLL_PERIOD                100     /* in ms, must be > UDEV_POLL_PERIOD_MIN, should be > 55ms and <= 100ms */#define UDEV_POLL_PERIOD_MIN            10      /* in ms, should be > 5ms and <= 10ms */static struct option long_options[] ={    {"help",	       	no_argument,       NULL, 'h'},    {"device_id",	required_argument, NULL, 'i'},    {"usb_filename",	optional_argument, NULL, 'f'},    {"namelen",         optional_argument, NULL, 'n'},    {"quiet",		no_argument,       NULL, 'q'},    {"debug",           no_argument,       NULL, 'd'},    {"warn_only",       no_argument,       NULL, 'w'},    {"version",		no_argument,       NULL, 'v'},    {"test",            no_argument,       NULL, 't'},    {"log",             required_argument, NULL, 'l'},    {"searchtime",      required_argument, NULL, 's'},    {NULL, 0, NULL, 0}};int debug = 0;                   /* commandline switch print debug output */int namelength = 1;              /* commandline switch of prefered name length */struct usb_dev_handle *usb_hd;   /* global for usage in signal handler *//* Function Protortype */void release_usb_device(int);struct usb_device* search_devices(int, int, const char*);int search_message_endp(struct usb_device *);int search_response_endp(struct usb_device *);void print_usage(void);const char *strrcut(const char *, int);int strrcmp(const char *, const char *);FILE *errlog;FILE *outlog;/** * print usage * prints just the help text to sreen, for all the nice options, which may be used */void print_usage(void) {        printf ("Usage: ozerocdoff [-hqwqv] -i <DeviceID> [-f <name>] [-n <len>]\n\n");	printf (" -h, --help               this help\n");	printf (" -i, --device_id <n>      target USB device id, required option\n");	printf (" -f, --usb_filename <str> target USB file name\n");	printf (" -n, --namelen <n>        target USB file name len (default %d)\n", namelength);	printf (" -w, --warn_only          print warnings instead of errors without program abort\n");	printf (" -q, --quiet              don't show messages\n");	printf (" -t, --test               test only, nothing send\n");	printf (" -l, --log                write message into log file instead of stderr\n");	printf (" -s, --searchtime <n> ms  tries to search at least <n> ms for the Zero-CD device\n");	printf (" -d, --debug              output some debug messages\n");	printf (" -v, --version            show version string\n\n");	printf ("Examples:\n");	printf ("   ozerocdoff -i 0xc031\n");	printf ("   ozerocdoff -i 0xc031 -f usbdev5.28 -n 2\n");}int main(int argc, char **argv) {	struct usb_device *usb_dev;	int quiet = 0;            /* commandline switch be quiet, no output */	int warno = 0;            /* commandline switch do only warn and do no program abort */	int test = 0;             /* commandline switch for testing, no rezero will be send */	int count;                /* retry counter */	int ret;                  /* general return value checker */	int searchtime;           /* search time in ms to the Zero-CD device */	DIR *usb_dev_dir;         /* just for testing, if directory exists */	const char *filename="";  /* filename of this USB device */        const char *logname=(char *)NULL;/* filename of log file */	char buffer[BUFFER_SIZE];	int TargetProduct=0;      /* has not to be zero */	const char const MessageContent[]={	  0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12,	  0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x01,	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	};		int c, option_index = 0;	usb_dev_dir = opendir ("/sys/class/usb_device/");	if (usb_dev_dir != NULL) {	      closedir (usb_dev_dir);	      searchtime = 0;    /* no search time needed */	} else {	      searchtime = 800;  /* set search time to 800 ms */	}	while (1){                c = getopt_long (argc, argv, "hvwdtqi:n:f:l:s:",                        long_options, &option_index);		if (c == -1) {		        break;		}		switch (c) {		case 'i': TargetProduct = strtol(optarg, NULL, 0); break;		case 'n': namelength = strtol(optarg, NULL, 0); break;		case 'f': filename = optarg; break;		case 'l': logname = optarg; break;		case 's': searchtime = strtol(optarg, NULL, 0); break;	        case 'q': quiet=1; break;		case 'd': debug=1; break;	        case 'w': warno=1; break;	        case 't': test=1; break;		case 'v': printf("ozerocdoff version: %s\n", VERSION); exit(0);		case 'h': print_usage(); exit(0);		default:  print_usage(); exit(1);		}	}	if (  (logname == (char *)NULL)	    ||((outlog = errlog = fopen(logname, "a")) == NULL)) {	        outlog = stdout;	        errlog = stderr;	} else {	      fprintf(outlog, "\n");	      for(count=0; count < argc; count++) {	              fprintf(outlog, "%s ", argv[count]);	      }	      fprintf(outlog, "\n");	}	/* check argument */	if (TargetProduct==0) {	        fprintf(errlog, "ERROR: Device ID missing\n");		exit(1);	}	if (debug) quiet=0;	if (searchtime < 0) {	        searchtime = 0; /* search at least one time */	}       	/* general USB-Lib init stuff */	usb_init();        /* if the searchtime is < UDEV_POLL_PERIOD_MIN, we will search only once for the device node, but           we will wait that searchtime just before we do the first test!           if the searchtime is > UDEV_POLL_PERIOD, we will repeat the test and do a retest after this time           period. If the rest of the time is < UDEV_POLL_PERIOD_MIN, we will simple skip the last test,           otherwise we do a last test after the rest wait time */	if ((searchtime < UDEV_POLL_PERIOD_MIN) && (searchtime > 0)) {	        usleep(searchtime*1000);	}	for (count=searchtime, ret=1; count>=(UDEV_POLL_PERIOD_MIN - UDEV_POLL_PERIOD); count-=UDEV_POLL_PERIOD, ret++) {	        (void)usb_find_busses();		(void)usb_find_devices();		if (debug) {		        fprintf(outlog, "%d. Search Zero-CD device\n", ret);		}		/* we use currently only the given device ID from the command line to detect the device */		/* that will be bad, if we want to distingush between multiple WWAN-modems, to take care! */		usb_dev = search_devices(TARGET_VENDOR, TargetProduct, strrcut(filename, namelength));		if (usb_dev != NULL) {		        break;		} else {		        if ((count >= UDEV_POLL_PERIOD_MIN) && (count < UDEV_POLL_PERIOD)) {			      usleep(count*1000);			} else if (count > UDEV_POLL_PERIOD) {			      usleep(UDEV_POLL_PERIOD*1000);			}		}	}	if (usb_dev == NULL) {	        if(!quiet) fprintf(errlog, "ERROR: No Zero-CD device found\n");		      exit(2);		}	usb_hd = usb_open(usb_dev);	if (usb_hd == NULL) {		if(!quiet) fprintf(errlog, "ERROR: device access not possible\n");		exit(4);	}    	/* detach running default driver */	signal(SIGTERM, release_usb_device);	ret = usb_get_driver_np(usb_hd, 0, buffer, sizeof(buffer));	if (ret == 0) {	        if (debug) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -