1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495 |
- Subject: All upstream commits until r59 combined
- Author: Daviedev <daviedev@users.sourceforge.net>
- --- a/ChangeLog
- +++ b/ChangeLog
- @@ -1,4 +1,13 @@
- -0.3:
- +1.0 Daniel J Blueman <daniel@quora.org>
- + - Fix behaviour with newer U3 devices
- + - Printing fixes
- + - Detach mass-storage prior to USB access
- + - Gracefully quit with Ctrl-C
- + - Print data partition size when too small
- + - Limit update printing rate
- + - Fix linking to libusb; recommended over SG
- +
- +0.3
- - Detect correct subsystem from configure.
- - Use MinGW/MSYS to build on MS Windows
- - Hide password input under MS Windows
- --- a/TODO
- +++ b/TODO
- @@ -1,6 +1,5 @@
- Major:
- - If possible open sg subsystem Read-only to work around NOMEDIUM error with encrypted partition
- - - Handle ctrl-c
- - Documentation
- - Further documentation of U3 features
- - Document which options are destructive
- --- a/configure.ac
- +++ b/configure.ac
- @@ -37,11 +37,11 @@
-
- # Checks for libraries.
- #FIXME: PKG_CHECK_MODULES not provided on MinGW
- -#AS_IF([ test x$subsystem = xlibusb ],
- -# [ PKG_CHECK_MODULES([LIBUSB], [libusb],
- -# [ ],
- -# [ AC_MSG_FAILURE([libusb is required but not found.]) ])
- -# ])
- +AS_IF([ test x$subsystem = xlibusb ],
- + [ PKG_CHECK_MODULES([LIBUSB], [libusb],
- + [ ],
- + [ AC_MSG_FAILURE([libusb is required but not found.]) ])
- + ])
-
- # Checks for header files.
- AC_HEADER_STDC
- --- /dev/null
- +++ b/doc/commands.txt
- @@ -0,0 +1,579 @@
- +
- +---
- +
- +>> 0x00
- +description:
- + Read a page with some sort of device info
- +
- +type: request
- +
- +command:
- +
- + CBWCB = 0xFF 0x00 0x00 0x03 0x00 0x27 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 0xFF SCSI opcode
- + 1-2 0x0000 command
- + 3-4 0x0003 Page number
- + 5-6 0x27 Request data length
- + 9 0x0 ??? sofware update tool also uses 0x01 here
- +
- + valid page numbers according to bCSWStatus:
- + verbatime: 0x3, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x13, 0x14
- +
- +data:
- + 6+ bytes
- +
- + 0000 03 00 01 00 27 00 |....'. |
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-1 0x0003 page number
- + 2-3 0x0001 ??? mostly 0x01, once 0x03
- + 4-5 0x0027 total usefull data length (including 6 byte header)
- +
- +
- +page 0x03:
- +
- + 0000 03 00 01 00 27 00 77 00 00 00 03 81 07 06 54 30 |....'.w.......T0|
- + 0016 30 30 30 31 31 41 31 41 41 31 31 41 41 41 31 81 |00011A1AA11AAA1.|
- + 0032 07 06 54 91 4e 0f 00 |..T.N..|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-5 header(see above)
- + 6 Real size of full record...????
- + 7-11 ??? same for both verbatime and sandisk
- + 11-14 0x54060781 ??? same as @ byte 31 (actual value different on verbatim)
- + 15-30 "000011A1AA11AAA1" Serial number
- + 31-34 0x54060781 ??? same as @ byte 11
- + 35-38 0x000f4e91 Device size in 512-byte blocks
- +
- +page 0x0c:
- +
- + 0000 0c 00 01 00 0a 00 10 27 00 00 |.......'.. |
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-5 header(see above)
- + 6-9 0x00002710 Maximum wrong password try for secure zone.
- +
- +---
- +
- +>> 0x20
- +description:
- + Round CD size to a value the device likes
- +
- +type: action
- +
- +command:
- + CBWCB = 0xFF 0x20 0x00 0x02 0xFF 0x03 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 0xFF scsi opcode
- + 1-2 0x0020 command
- + 3 0x02 ??? can atleast be 0x02 and 0x03 but not 0, 1, 4, is
- + this some sort of domain id to select the partition,
- + like in 0x21, byte 3??? the verbatim is less picky and
- + accepts all values...
- + 4-7 0x3FF Value to round (in 512-byte sectors)
- + 8 0x0 Direction to round(0x00 = down, 0x01 = up)
- +
- +data:
- + 4 bytes
- +
- + 0000 00 02 00 00 |....|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-3 0x200 Rounded value
- +
- +---
- +
- +>> 0x21
- +description:
- + get information about the partition configuration
- +
- +type: request
- +
- +command:
- + CBWCB = 0xFF 0x21 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- + 0000 02 02 00 00 00 91 1e 0f 00 03 01 00 00 00 30 00 |..............0.|
- + can be read in any multiple of 8 all dat beyond the above data is zero(0)
- +
- + u3-remover uses the following data(IIRC), (0x0f4e91 == full drive size):
- + 0000 01 02 00 00 00 91 4e 0f 00 |......... |
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 02 amount of available records, where 1 record = 8 byte???
- + 1 02 ??? some sort of domain id???
- + 3-4 00 00 00 ??
- + 5-8 0x000F1E91 size of data partition in 512-byte sectors
- + 9 0x03 ?? some sort of domain id????
- + 10 0x01 ?? WARNING: If set to 0 on Sandisk cruzer, cd drive
- + will show up as direct-access, but can't be used, also
- + drive doesn't react to command 0x00, page 3 and you
- + won't be able to re-partition device!!!!
- + 11-12 00 00 ??
- + 13-15 0x003000 size of cdrom partitoin in 512-byte sectors
- +
- +---
- +
- +>> 0x22
- +description:
- + Repartition device
- +
- +type: action
- +
- +command:
- + CBWCB = 0xFF 0x22 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 0000 02 02 00 00 00 91 1e 0f 00 03 01 00 00 00 30 00 |..............0.|
- + 0016 00 |. |
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 0x02 amount of dword of data(+1byte+1dword=packet_size)
- + 1-4 0x00000002 ???
- + 5-8 0x000f1e91 Size of data partition in 512-byte sectors
- + 9-12 0x00000103 ??? 0x0003 make's it a direct access partition.(but can't partition afterwards, and page 3 of command 0x0000 isn't accessible anymore...)
- + 13-16 0x00003000 Size of CD partition in 512-byte sectors
- +
- +---
- +
- +>> 0x42
- +description:
- + Write block of data to CD-rom partition
- +
- +type: action
- +
- +command:
- + CBWCB = 0xFF 0x42 0x00 0x01 0x00 0x00 0x01 0x1D 0x00 0x00 0x00 0x01
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 0xFF scsi opcode
- + 1-2 0x42 command
- + 3 0x01 ???
- + 4-7 0x0000011D Block Address (Big Endian!!!!!!!)
- + 8-11 0x01 ??? (Big Endian?)
- +
- +data:
- + A 2048 byte block
- +
- +---
- +
- +>> 0x61
- +description:
- + read out hidden data/config storage. Looks the same as with mDrive.
- +
- +type: request
- +
- +command:
- + CBWCB = 0xFF 0x61 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +---
- +
- +>> 0x63
- +description:
- + read out hidden data/config storage. Looks the similar as with mDrive.
- +
- +type: request
- +
- +command:
- + CBWCB = 0xFF 0x63 0x00 0x00 0x00 0x55 0x33 0x49 0x4E 0x50 0x52 0x50
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +---
- +
- +>> 0xA0
- +description:
- + get some sort of data partition information
- +
- +type: request
- +
- +command:
- +
- + CBWCB = 0xFF 0xA0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 16 byte
- +
- + 0000 40 ab 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............|
- +
- + 0000 40 ab 1d 00 40 ab 1d 00 01 00 00 00 00 00 00 00 |@...@...........| (secured)
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-3 0x001dab40 Total data partition size
- + 4-7 0x001dab40 Amount of data partition encrypted????
- + 8-11 0x00000001 Lock(=0) or Unlocked(=1)
- + 12-15 0x00000000 Wrong password try counter
- +
- +---
- +
- +>> 0xA1
- +description:
- + FUZED
- +
- +type: Request?
- +
- +command:
- +
- + CBWCB = 0xFF 0xA1 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 scsi opcode
- + 1-2 command
- + 3 0 Failes on Sandisk if != 0
- + 4- changing these doesn't seem to have any effect
- +
- +data:
- +
- + data is random, and changes due to executing commands
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +
- +---
- +
- +>> 0xA2
- +description:
- + Secure data partition
- +
- + Password hash is a md5 sum of the unicode password including the terminating
- + null. So for a password of 'a' the following byte stream is fead to the md5
- + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
- +
- + It seems that if the whole of the data partition is made secure zone, then
- + the data currently on the data partition is accessible in the secure zone.
- + If only a part of the data partition is made secure zone than the first part
- + of the data on the partition is retained and the rest isn't accessible. In
- + this case the secure zone will contain garbage(the data on that was on that
- + part of the data partition but decrypted with an other key).
- +
- + If the device is already secured and this command is issued again, the current
- + data on the device is lost(if secure zone == 100%).
- +
- +type: action
- +
- +command:
- +
- + CBWCB = 0xFF 0xA2 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 20 byte
- +
- + 0000 40 ab 1d 00 33 2c e7 85 e9 73 57 4a 1c 5f da f3 |@...3,...sWJ._..|
- + 0016 ee e3 f0 83 |....|
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-3 0x001dab40 Size of private zone????
- + 4-19 ... Password hash ( pass='a')
- +
- +
- +---
- +
- +>> 0xA3
- +description:
- + value rounding for data partition securing
- +
- +type: request
- +
- +command:
- + CBWCB = 0xFF 0xA3 0x00 0x00 0x40 0xAB 0x1D 0x00 0x01 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0 0xFF scsi opcode
- + 1-2 0x00A3 Command
- + 3 0x00 ???
- + 4-7 0x001DAB40 Value to round (in 512-byte sectors)
- + 8 0x01 Direction to round(0x00 = down, 0x01 = up)
- +
- +
- +data:
- + 4 byte
- +
- + 0000 40 ab 1d 00 |@...|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-3 0x001DAB40 Rounded value
- +
- +---
- +
- +>> 0xA4
- +description:
- + unlock device
- +
- + Password hash is a md5 sum of the unicode password including the terminating
- + null. So for a password of 'a' the following byte stream is fead to the md5
- + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
- +
- +type: action
- +
- +command:
- +
- + CBWCB = 0xFF 0xA4 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 16 byte
- +
- + 0000 33 2c e7 85 e9 73 57 4a 1c 5f da f3 ee e3 f0 83 |3,...sWJ._......|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-15 ... password hash (pass='a')
- +
- +---
- +
- +>> 0xA6
- +description:
- + change password
- +
- + Password hash is a md5 sum of the unicode password including the terminating
- + null. So for a password of 'a' the following byte stream is fead to the md5
- + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
- +
- +type: action
- +
- +command:
- +
- + CBWCB = 0xFF 0xA6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- + 0000 33 2c e7 85 e9 73 57 4a 1c 5f da f3 ee e3 f0 83 |3,...sWJ._......|
- + 0016 c0 51 c1 bb 98 b7 1c cb 15 b0 cf 9c 67 d1 43 ee |.Q..........g.C.|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-15 ... Old password hash ( pass='a')
- + 16-31 ... New password hash ( pass='b')
- +
- +---
- +
- +>> 0xA7
- +description:
- + Remove security
- +
- + Password hash is a md5 sum of the unicode password including the terminating
- + null. So for a password of 'a' the following byte stream is fead to the md5
- + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
- +
- + hmm... if security zone size != size of data partition, then this fails!!!
- + it returns a failed status but doesn't increase the password try counter,
- + even if password was incorrect.... to remove the secure zone if it doesn't
- + fully occupy the data partition, recreate the secure zone with maximum size.
- + > Possible cause: If this command is issued the secure zone becomes the public
- + zone, and thus all data on the disk will be retained. It is suspected that all
- + partitions/zones are stored encrypted on the flash device(Yes, even the public
- + zone). So, if this command is issued the secure zone key is decrypted(if
- + encrypted at all) and the zone is marked as public. Logically this would not
- + work if there is a public and secure zone. Then you would end up with two
- + public zone's with different encryptions keys.
- +
- + Byte 3 of command does something... but still doesn't allow for removing half
- + secure zones.
- +
- +type: action
- +
- +command:
- +
- + CBWCB = 0xFF 0xA7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- + 0000 c0 51 c1 bb 98 b7 1c cb 15 b0 cf 9c 67 d1 43 ee |.Q..........g.C.|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-15 ... Password hash (in this case 'b')
- +
- +---
- +
- +>> 0x100
- +description:
- + seen used after a 0xA4(with some normal scsi stuff in between...).
- + generate reset some sort of reset or insert condition on data disk. Linux old 2.4
- + usb-storage sees it as a disconnect of the drive.
- +
- +type:
- +
- +command:
- +
- + CBWCB = 0xFF 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + No data....
- +
- +
- +---
- +
- +>> 0x101
- +description:
- + disconnect's and possibly reconnects device
- +
- +type: action
- +
- +command:
- +
- + CBWCB = 0xFF 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 12 bytes
- +
- + 0000 50 00 00 00 40 9c 00 00 01 00 00 00 |P...@.......|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 8 0x01 If 1 reconnect after disconnect, else not
- + all other byte's dont seem to have any effect...
- +
- +---
- +
- +>> 0x103
- +description:
- +Get chip maker and version
- +
- +type: request
- +
- +command:
- +
- + CBWCB = 0xFF 0x03 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- + 24 bytes
- +
- + 0000 33 2e 32 31 00 00 00 00 53 61 6e 44 69 73 6b 20 |3.21....SanDisk |
- + 0016 00 00 00 00 00 00 00 00 |........|
- +
- + byte data description
- + ------------------------------------------------------------------------------
- + 0-7 "3.21" Chip version
- + 8-23 "SanDisk" Chip maker
- +
- +
- +
- +
- +
- +
- +
- +possible read commands:
- +0x20
- +0x21
- +0x61
- +0x63
- +0x68
- +0x6b 512?
- +0x81 128-byte
- +0x84 64-byte
- +0x85 64-byte
- +0x88 64-byte
- +0xa1 4-byte
- +0xc1
- +0xe2 = read random?, 64-byte
- +
- +0x102 512-byte
- +
- +Write:
- +0x01 -> 0x1f
- +0x22 -> 0x40
- +0x42
- +0x60
- +0x62
- +0x6a
- +0x6c
- +0x6d
- +0x6e
- +0x82 128 byte
- +0x83 64 byte?
- +0x86
- +0x87
- +0xc0
- +0xc2
- +
- +
- +
- +
- +---
- +
- +>>
- +description:
- +
- +type:
- +
- +command:
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +data:
- +
- +
- + byte data description
- + ------------------------------------------------------------------------------
- +
- +
- --- a/src/display_progress.c
- +++ b/src/display_progress.c
- @@ -20,17 +20,18 @@
- #include <stdio.h>
-
- void display_progress(unsigned int cur, unsigned int total) {
- - unsigned int procent;
- - unsigned int bar_len;
- - int i;
- + static unsigned int last = 0;
- + unsigned int percent;
- + unsigned int bar_len, i;
-
- if (total == 0) return;
-
- - procent = (cur * 100) / total;
- + percent = (cur * 100) / total;
- + if (percent == last) return;
-
- putchar('|');
- bar_len = (cur * PROGRESS_BAR_WIDTH) / total;
- - for (i =0; i < bar_len; i++) {
- + for (i = 0; i < bar_len; i++) {
- putchar('*');
- }
- for (i = bar_len; i < PROGRESS_BAR_WIDTH; i++) {
- @@ -38,6 +39,8 @@
- }
- putchar('|');
-
- - printf(" %d%%\r", procent);
- + printf(" %d%%\r", percent);
- fflush(stdout);
- +
- + last = percent;
- }
- --- a/src/main.c
- +++ b/src/main.c
- @@ -24,6 +24,8 @@
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- +#include <signal.h>
- +#include <assert.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- @@ -42,10 +44,11 @@
- #define MAX_FILENAME_STRING_LENGTH 1024
- #define MAX_PASSWORD_LENGTH 1024
-
- -char *version = VERSION;
- +static char *version = VERSION;
-
- int debug = 0;
- -int batch_mode = 0;
- +static int batch_mode = 0;
- +static int quit = 0;
-
- enum action_t { unknown, load, partition, dump, info, unlock, change_password,
- enable_security, disable_security, reset_security };
- @@ -57,7 +60,7 @@
- *
- * @returns TRUE if user wants to continue else FALSE to abort.
- */
- -int confirm() {
- +static int confirm(void) {
- char c;
- int retval;
- int done;
- @@ -93,24 +96,24 @@
- /**
- * Symbols of size multiplication factors.
- */
- -char factor_symbols[] = "kMGTPE";
- +static char factor_symbols[] = " kMGTPE";
-
- /**
- * Print bytes is human readable fashion.
- *
- * @param size Data size to print
- */
- -void print_human_size(uint64_t size) {
- - float fsize = 0;
- +static void print_human_size(uint64_t size) {
- + double fsize = 0;
- unsigned int factor = 0;
-
- fsize = size;
- - while (fsize > 1024) {
- + while (fsize >= 1024) {
- fsize /= 1024;
- factor++;
- }
-
- - printf("%.2f %cB", fsize, factor_symbols[factor-1]);
- + printf("%.2f %cB", fsize, factor_symbols[factor]);
- }
-
- /**
- @@ -122,7 +125,7 @@
- * @returns U3_SUCCESS if successful, else U3_FAILURE and
- * an error string can be obtained using u3_error()
- */
- -int get_tries_left(u3_handle_t *device, int *tries) {
- +static int get_tries_left(u3_handle_t *device, int *tries) {
- struct dpart_info dpinfo;
- struct property_0C security_properties;
-
- @@ -151,10 +154,10 @@
-
- /********************************** Actions ***********************************/
-
- -int do_load(u3_handle_t *device, char *iso_filename) {
- +static int do_load(u3_handle_t *device, char *iso_filename) {
- struct stat file_stat;
- struct part_info pinfo;
- - uint32_t cd_size;
- + off_t cd_size;
- FILE *fp;
- uint8_t buffer[U3_BLOCK_SIZE];
- unsigned int bytes_read=0;
- @@ -171,10 +174,10 @@
- return EXIT_FAILURE;
- }
-
- - cd_size = file_stat.st_size / U3_SECTOR_SIZE;
- + cd_size = ((uintmax_t) file_stat.st_size) / U3_SECTOR_SIZE;
- if (file_stat.st_size % U3_SECTOR_SIZE)
- cd_size++;
- - block_cnt = file_stat.st_size / U3_BLOCK_SIZE;
- + block_cnt = ((uintmax_t) file_stat.st_size) / U3_BLOCK_SIZE;
- if (file_stat.st_size % U3_BLOCK_SIZE)
- block_cnt++;
-
- @@ -186,10 +189,10 @@
- }
-
- if (cd_size > pinfo.cd_size) {
- - fprintf(stderr, "CD image(%lu byte) is to big for current cd "
- - "partition(%u byte), please repartition device.\n",
- - file_stat.st_size,
- - U3_SECTOR_SIZE * pinfo.cd_size);
- + fprintf(stderr, "CD image (%ju bytes) is to big for current CD "
- + "partition (%llu bytes)\n",
- + (uintmax_t) file_stat.st_size,
- + 1ll * U3_SECTOR_SIZE * pinfo.cd_size);
- return EXIT_FAILURE;
- }
-
- @@ -228,7 +231,7 @@
- }
-
- block_num++;
- - } while (!feof(fp));
- + } while (!feof(fp) && !quit);
- display_progress(block_num, block_cnt);
- putchar('\n');
-
- @@ -238,7 +241,7 @@
- return EXIT_SUCCESS;
- }
-
- -int do_partition(u3_handle_t *device, char *size_string) {
- +static int do_partition(u3_handle_t *device, char *size_string) {
- uint64_t size;
- uint32_t cd_sectors;
-
- @@ -263,7 +266,7 @@
- return EXIT_SUCCESS;
- }
-
- -int do_unlock(u3_handle_t *device, char *password) {
- +static int do_unlock(u3_handle_t *device, char *password) {
- int result=0;
- int tries_left=0;
-
- @@ -297,7 +300,7 @@
- }
- }
-
- -int do_change_password(u3_handle_t *device, char *password,
- +static int do_change_password(u3_handle_t *device, char *password,
- char *new_password)
- {
- int result=0;
- @@ -335,7 +338,7 @@
- }
- }
-
- -int do_enable_security(u3_handle_t *device, char *password) {
- +static int do_enable_security(u3_handle_t *device, char *password) {
- if (u3_enable_security(device, password) != U3_SUCCESS) {
- fprintf(stderr, "u3_enable_security() failed: %s\n",
- u3_error_msg(device));
- @@ -345,7 +348,7 @@
- return EXIT_SUCCESS;
- }
-
- -int do_disable_security(u3_handle_t *device, char *password) {
- +static int do_disable_security(u3_handle_t *device, char *password) {
- int result=0;
- int tries_left=0;
-
- @@ -380,7 +383,7 @@
- }
- }
-
- -int do_reset_security(u3_handle_t *device) {
- +static int do_reset_security(u3_handle_t *device) {
- int result=0;
-
- // the enable security command is always possible without the correct
- @@ -408,7 +411,7 @@
- }
- }
-
- -int do_info(u3_handle_t *device) {
- +static int do_info(u3_handle_t *device) {
- struct part_info pinfo;
- struct dpart_info dpinfo;
- struct chip_info cinfo;
- @@ -484,8 +487,8 @@
- return EXIT_SUCCESS;
- }
-
- -int do_dump(u3_handle_t *device) {
- - int retval = EXIT_SUCCESS;
- +static int do_dump(u3_handle_t *device) {
- + int retval;
-
- struct part_info pinfo;
- struct dpart_info dpinfo;
- @@ -595,12 +598,12 @@
- }
- }
-
- - return EXIT_SUCCESS;
- + return retval;
- }
-
- /************************************ Main ************************************/
-
- -void usage(const char *name) {
- +static void usage(const char *name) {
- printf("u3-tool %s - U3 USB stick manager\n", version);
- printf("\n");
- printf("Usage: %s [options] <device name>\n", name);
- @@ -622,7 +625,7 @@
- printf("For the device name use:\n %s\n", u3_subsystem_help);
- }
-
- -void print_version() {
- +static void print_version(void) {
- printf("u3-tool %s\n", version);
- printf("subsystem: %s\n", u3_subsystem_name);
- printf("\n");
- @@ -632,6 +635,10 @@
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
- }
-
- +static void set_quit(int sig) {
- + quit = 1;
- +}
- +
- int main(int argc, char *argv[]) {
- u3_handle_t device;
-
- @@ -711,6 +718,9 @@
- }
- device_name = argv[optind];
-
- + assert(signal(SIGINT, set_quit) != SIG_ERR);
- + assert(signal(SIGTERM, set_quit) != SIG_ERR);
- +
- //
- // open the device
- //
- @@ -772,9 +782,9 @@
- case partition:
- printf("\n");
- printf("WARNING: Loading a new cd image causes the ");
- - printf("whole device to be whiped. This INCLUDES\n ");
- + printf("whole device to be wiped. This INCLUDES\n ");
- printf("the data partition.\n");
- - printf("I repeat: ANY EXCISTING DATA WILL BE LOST!\n");
- + printf("I repeat: ANY EXISTING DATA WILL BE LOST!\n");
- if (confirm())
- retval = do_partition(&device, size_string);
- break;
- --- a/src/secure_input.c
- +++ b/src/secure_input.c
- @@ -33,9 +33,9 @@
- DWORD mode;
- HANDLE ih;
- #else
- - struct termio ttymode;
- + struct termios ttymode;
- #endif
- - int pos;
- + size_t pos;
- int ch;
-
- // input checking
- @@ -51,9 +51,9 @@
- }
- SetConsoleMode(ih, mode & ~(ENABLE_ECHO_INPUT ));
- #else
- - ioctl(STDIN_FILENO, TCGETA, &ttymode);
- + tcgetattr(STDIN_FILENO, &ttymode);
- ttymode.c_lflag &= ~( ECHO | ECHOE | ECHONL );
- - ioctl(STDIN_FILENO, TCSETAF, &ttymode);
- + tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttymode);
- #endif
-
- pos=0;
- @@ -75,7 +75,7 @@
- fputc('\n', stdout);
- #else
- ttymode.c_lflag |= ECHO | ECHOE | ECHONL;
- - ioctl(STDIN_FILENO, TCSETAF, &ttymode);
- + tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttymode);
- fputc('\n', stdout);
- #endif
- }
- --- a/src/u3_commands.c
- +++ b/src/u3_commands.c
- @@ -52,10 +52,9 @@
- * U3_PASSWORD_HASH_LEN long.
- */
- void u3_pass_to_hash(const char *password, uint8_t *hash) {
- - unsigned int passlen;
- + unsigned int passlen, i;
- unsigned int unicode_passlen;
- uint8_t *unicode_pass;
- - int i;
-
- passlen = strlen(password);
- unicode_passlen = (passlen+1)*2;
- @@ -178,7 +177,7 @@
- return U3_FAILURE;
- }
- if (cd_size > device_properties.device_size) {
- - u3_set_error(device, "Requested CD size is to big for device");
- + u3_set_error(device, "Requested CD size is larger than device (%ull bytes)", device_properties.device_size << 9ULL);
- return U3_FAILURE;
- }
-
- --- /dev/null
- +++ b/src/u3_scsi_debug.c
- @@ -0,0 +1,111 @@
- +/**
- + * u3-tool - U3 USB stick manager
- + * Copyright (C) 2007 Daviedev, daviedev@users.sourceforge.net
- + *
- + * 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.
- + *
- + * You should have received a copy of the GNU General Public License along
- + * with this program; if not, write to the Free Software Foundation, Inc.,
- + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- + */
- +#include "u3_scsi.h"
- +#include "u3_error.h"
- +
- +#include <sys/types.h>
- +#include <sys/stat.h>
- +#include <sys/ioctl.h>
- +#include <stdlib.h>
- +#include <fcntl.h>
- +#include <string.h>
- +#include <unistd.h>
- +#include <errno.h>
- +
- +#include <stdio.h>
- +
- +#include "sg_err.h"
- +
- +#define U3_TIMEOUT 2000 //2000 millisecs == 2 seconds
- +
- +int u3_open(u3_handle_t *device, const char *which)
- +{
- + FILE *fp;
- +
- + u3_set_error(device, "");
- + device->dev = NULL;
- +
- + if (strcmp(which, "stdout") == 0) {
- + fp = stdout;
- + } else if (strcmp(which, "stderr") == 0) {
- + fp = stderr;
- + } else {
- + u3_set_error(device, "unknown output '%s', 'stdout' and "
- + "'stderr' only supported", which);
- + return U3_FAILURE;
- + }
- +
- + device->dev = fp;
- + return U3_SUCCESS;
- +}
- +
- +void u3_close(u3_handle_t *device)
- +{
- + FILE *fp = (FILE *)(device->dev);
- +// if (fp != stdout && fp != stderr) {
- +// fclose(fp);
- +// }
- +}
- +
- +int u3_send_cmd(u3_handle_t *device, uint8_t cmd[U3_CMD_LEN],
- + int dxfer_direction, int dxfer_length, uint8_t *dxfer_data,
- + uint8_t *status)
- +{
- + FILE *fp = (FILE *)device->dev;
- + int i;
- +
- + fprintf(fp, "---------------------------------------------------------"
- + "-----------------------\n");
- +
- + fprintf(fp, "Command block:\n");
- + for (i=0; i < U3_CMD_LEN; i++) {
- + fprintf(fp, "%.2X ", cmd[i]);
- + }
- + fprintf(fp, "\n");
- +
- + fprintf(fp, "\n");
- + switch (dxfer_direction) {
- + case U3_DATA_NONE:
- + fprintf(fp, "No data\n");
- + break;
- + case U3_DATA_TO_DEV:
- + fprintf(fp, "Sending %d bytes of data to device\n", dxfer_length);
- +
- + fprintf(fp, "Data:");
- + for (i=0; i < dxfer_length; i++) {
- + if (i % 8 == 0) fprintf(fp, "\n%.4x\t", i);
- + fprintf(fp, "%.2x ", dxfer_data[i]);
- + }
- + fprintf(fp, "\n");
- + break;
- + case U3_DATA_FROM_DEV:
- + fprintf(fp, "Reading %d bytes of data from device\n", dxfer_length);
- + memset(dxfer_data, 0, dxfer_length);
- + break;
- + }
- +
- + fprintf(fp, "---------------------------------------------------------"
- + "-----------------------\n");
- +
- + *status = 0;
- +
- + return U3_SUCCESS;
- +}
- +
- +
- --- a/src/u3_scsi_sg.c
- +++ b/src/u3_scsi_sg.c
- @@ -32,13 +32,14 @@
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- +#include <string.h>
-
- #include <linux/cdrom.h>
- #include <scsi/sg.h>
-
- #include "sg_err.h"
-
- -#define U3_TIMEOUT 2000 //2000 millisecs == 2 seconds
- +#define SG_TIMEOUT 2000 //2000 millisecs == 2 seconds
-
- const char *u3_subsystem_name = "sg";
- const char *u3_subsystem_help = "'/dev/sda0', '/dev/sg3'";
- @@ -97,6 +98,7 @@
- {
- int *sg_fd = (int *)device->dev;
- close(*sg_fd);
- + free(sg_fd);
- }
-
- int u3_send_cmd(u3_handle_t *device, uint8_t cmd[U3_CMD_LEN],
- @@ -123,23 +125,23 @@
- // Prepare command
- memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
- io_hdr.interface_id = 'S'; // fixed
- + io_hdr.dxfer_direction = dxfer_direction; // Select data direction
- io_hdr.cmd_len = U3_CMD_LEN; // length of command in bytes
- - // io_hdr.iovec_count = 0; // don't use iovector stuff
- - io_hdr.mx_sb_len = sizeof(sense_buf); // sense buffer size. do we use this???
- - io_hdr.dxfer_direction = dxfer_direction; // send data to device
- + io_hdr.mx_sb_len = 0; // sense buffer size. do we use this???
- + io_hdr.iovec_count = 0; // don't use iovector stuff
- io_hdr.dxfer_len = dxfer_length; // Size of data transfered
- io_hdr.dxferp = dxfer_data; // Data buffer to transfer
- io_hdr.cmdp = cmd; // Command buffer to execute
- io_hdr.sbp = sense_buf; // Sense buffer
- - io_hdr.timeout = U3_TIMEOUT; // timeout
- - // io_hdr.flags = 0; // take defaults: indirect IO, etc
- + io_hdr.timeout = SG_TIMEOUT; // timeout
- + io_hdr.flags = 0; // take defaults: indirect IO, etc
- // io_hdr.pack_id = 0; // internal packet. used by te program to recognize packets
- // io_hdr.usr_ptr = NULL; // user data
-
- // preform ioctl on device
- if (ioctl(*sg_fd, SG_IO, &io_hdr) < 0) {
- u3_set_error(device, "Failed executing scsi command: "
- - "SG_IO ioctl Failed");
- + "SG_IO ioctl failed with %s", strerror(errno));
- return U3_FAILURE;
- }
-
- --- a/src/u3_scsi_spt.c
- +++ b/src/u3_scsi_spt.c
- @@ -36,7 +36,7 @@
- #include <windows.h>
- #include <ddk/ntddscsi.h>
-
- -#define U3_TIMEOUT 2 // 2 seconds
- +#define SPT_TIMEOUT 2 // 2 seconds
-
- const char *u3_subsystem_name = "spt";
- const char *u3_subsystem_help = "The drive letter of the device";
- @@ -58,11 +58,11 @@
- return U3_FAILURE;
- }
-
- - //take the drive letter and put it in the format used in CreateFile
- + // Take the drive letter and put it in the format used in CreateFile
- memcpy(lpszDeviceName, (char *) "\\\\.\\*:", 7);
- lpszDeviceName[4] = which[0];
-
- - //get a handle to the device, the parameters used here must be used in order for this to work
- + // Get a handle to the device, the parameters used here must be used in order for this to work
- hDevice=CreateFile(lpszDeviceName,
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- @@ -71,7 +71,8 @@
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- - //if for some reason we couldn't get a handle to the device we will try again using slightly different parameters for CreateFile
- + // If for some reason we couldn't get a handle to the device we will try again using slightly
- + // different parameters for CreateFile
- if (hDevice==INVALID_HANDLE_VALUE)
- {
- u3_set_error(device, "Failed openning handle for %s: Error %d\n", which, GetLastError());
- @@ -118,19 +119,40 @@
- sptd.SenseInfoLength = 0; // don't use this currently...
- sptd.DataIn = dxfer_direction; // data direction
- sptd.DataTransferLength = dxfer_length; // Size of data transfered
- - sptd.TimeOutValue = U3_TIMEOUT; // timeout in seconds
- + sptd.TimeOutValue = SPT_TIMEOUT; // timeout in seconds
- sptd.DataBuffer = dxfer_data; // data buffer
- //sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, sbuf);
- memcpy(sptd.Cdb, cmd, U3_CMD_LEN);
-
- // preform ioctl on device
- - err = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
- - sizeof(sptd), &sptd, sizeof(sptd), &returned, NULL);
- + err = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
- + sizeof(sptd), &sptd, sizeof(sptd), &returned, NULL);
-
- // evaluate result
- if (!err) {
- - u3_set_error(device, "Failed executing scsi command: "
- - "Error %d", GetLastError());
- + DWORD errcode;
- + LPVOID lpMsgBuf;
- +
- + errcode = GetLastError();
- +
- + err = FormatMessage(
- + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- + NULL,
- + errcode,
- + 0,
- + (LPTSTR) &lpMsgBuf,
- + 0,
- + NULL);
- +
- + if (err != 0) {
- + u3_set_error(device, "Failed executing scsi command: "
- + "%s (Error %d)", lpMsgBuf, errcode);
- + LocalFree(lpMsgBuf);
- + } else {
- + u3_set_error(device, "Failed executing scsi command: "
- + "Unknown Error %d", errcode);
- + }
- +
- return U3_FAILURE;
- }
-
- --- a/src/u3_scsi_usb.c
- +++ b/src/u3_scsi_usb.c
- @@ -1,6 +1,6 @@
- /**
- * u3-tool - U3 USB stick manager
- - * Copyright (C) 2007 Daviedev, daviedev@users.sourceforge.net
- + * Copyright (C) 2011 Daviedev, daviedev@users.sourceforge.net
- *
- * 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
- @@ -30,34 +30,35 @@
- #include <fcntl.h>
- #include <string.h>
- #include <unistd.h>
- +#include <assert.h>
- #include <usb.h>
- #include <errno.h>
- #include <regex.h>
-
- // USB maximum packet length
- -#define USB_MAX_PACKET_LEN 256
- +#define USB_MAX_PACKET_LEN 2048
-
- // USB command block wrapper length
- #define U3_CBWCB_LEN 12
-
- -// USB MSC command/status wrapper signatures
- -#define CBW_SIGNATURE 0x43425355
- -#define CSW_SIGNATURE 0x53425355
- -
- // USB MSC command block wrapper data direction bits
- #define CBW_DATA_IN 0x80
- #define CBW_DATA_OUT 0x00
- #define CBW_DATA_NONE 0x00
- #define CBW_FLAG_DIRECTION 0x80
-
- -#define U3_DEVICE_TIMEOUT 20000 //2000 millisecs == 2 seconds
- +#define U3_DEVICE_TIMEOUT 2000 //2000 millisecs == 2 seconds
-
- -#define U3_DEV_LIST_LENGTH 4
- -uint16_t u3_dev_list[U3_DEV_LIST_LENGTH][2] = {
- +uint16_t u3_dev_list[][2] = {
- { 0x08ec, 0x0020 }, // Verbatim Store 'N Go
- { 0x0781, 0x5406 }, // Sandisk Cruzer Micro
- { 0x0781, 0x5408 }, // Sandisk Cruzer Titanium
- { 0x0781, 0x550a }, // Sandisk Cruzer Pattern
- + { 0x0781, 0x5151 }, // Sandisk Cruzer Micro Skin 8GB (Thanks to dnelson @sf)
- + { 0x0781, 0x540e }, // Sandisk Cruzer Contour
- + { 0x0781, 0x5530 }, // Sandisk Cruzer
- + { 0x0781, 0x5535 }, // Sandisk Ultra Backup
- + { 0, 0 },
- };
-
- struct u3_usb_handle {
- @@ -69,7 +70,7 @@
- typedef struct u3_usb_handle u3_usb_handle_t;
-
- struct usb_msc_cbw {
- - uint32_t dCBWSignature;
- + uint8_t dCBWSignature[4];
- uint32_t dCBWTag;
- uint32_t dCBWDataTransferLength;
- uint8_t bmCBWFlags;
- @@ -79,7 +80,7 @@
- } __attribute__ ((packed));
-
- struct usb_msc_csw {
- - uint32_t dCSWSignature;
- + uint8_t dCSWSignature[4];
- uint32_t dCSWTag;
- uint32_t dCSWDataResidue;
- uint8_t bCSWStatus;
- @@ -88,7 +89,7 @@
- const char *u3_subsystem_name = "libusb";
- const char *u3_subsystem_help = "'scan' to automatically use the first detected U3 device, or 'vid:pid' if not detected";
-
- -struct usb_device *
- +static struct usb_device *
- locate_u3_device(uint16_t vid, uint16_t pid)
- {
- struct usb_bus *bus;
- @@ -115,6 +116,7 @@
- {
- uint16_t vid, pid;
- regex_t vid_pid_regex;
- + int has_vid_pid = 0;
-
- struct usb_device *u3_device;
- u3_usb_handle_t *handle_wrapper;
- @@ -125,7 +127,6 @@
-
- int err;
- char errbuf[U3_MAX_ERROR_LEN];
- - int i;
-
- // init
- u3_set_error(device, "");
- @@ -137,25 +138,45 @@
- "expression: %s", errbuf);
- return U3_FAILURE;
- }
- + if (regexec(&vid_pid_regex, which, 0, 0, 0) == 0) {
- + // Do de regexing here, this prevents leaking of the
- + // vid_pid_regex memory
- + char *seperator=0;
- + has_vid_pid = 1;
- + vid = strtoul(which, &seperator, 16);
- + pid = strtoul(seperator+1, &seperator, 16);
- + }
- + regfree(&vid_pid_regex);
-
- usb_init();
- if (debug)
- usb_set_debug(255);
-
- // Find device
- - if (regexec(&vid_pid_regex, which, 0, 0, 0) == 0) {
- - char *seperator=0;
- - vid = strtoul(which, &seperator, 16);
- - pid = strtoul(seperator+1, &seperator, 16);
- + if (has_vid_pid) {
- u3_device = locate_u3_device(vid, pid);
- +
- + if (u3_device == NULL) {
- + u3_set_error(device, "Could not locate the U3 device '%s', "
- + "try 'scan' for first available device", which);
- + return U3_FAILURE;
- + }
- } else if (strcmp(which, "scan") == 0) {
- - i = 0;
- + int i = 0;
- u3_device = NULL;
- - while (u3_device == NULL && i < U3_DEV_LIST_LENGTH) {
- + while (u3_device == NULL &&
- + !(u3_dev_list[i][0] == 0 && u3_dev_list[i][1] == 0))
- + {
- u3_device = locate_u3_device(u3_dev_list[i][0],
- u3_dev_list[i][1]);
- i++;
- }
- +
- + if (u3_device == NULL) {
- + u3_set_error(device, "Could not locate any known U3 device, "
- + "the VID:PID of your device might not be known to U3 tool");
- + return U3_FAILURE;
- + }
- // } else if (regexec(&serial_regex, which, 0, 0, 0) == 0) {
- //TODO: search for a specific serial number
- } else {
- @@ -164,14 +185,6 @@
- return U3_FAILURE;
- }
-
- - regfree(&vid_pid_regex);
- -
- - if (u3_device == NULL) {
- - u3_set_error(device, "Could not locate the U3 device '%s', "
- - "try 'scan' for first available device", which);
- - return U3_FAILURE;
- - }
- -
- // Open device
- handle_wrapper = (u3_usb_handle_t *) malloc(sizeof(u3_usb_handle_t));
- if (handle_wrapper == NULL) {
- @@ -203,8 +216,13 @@
- goto open_fail;
- }
- interface_desc = config_desc->interface->altsetting;
- -
- handle_wrapper->interface_num = interface_desc->bInterfaceNumber;
- + err = usb_detach_kernel_driver_np(handle_wrapper->handle, handle_wrapper->interface_num);
- + if (err != 0 && err != -61) {
- + u3_set_error(device, "failed to detach USB device with %s", strerror(errno));
- + goto open_fail;
- + }
- +
- if ((err=usb_claim_interface(handle_wrapper->handle,
- handle_wrapper->interface_num)) != 0)
- {
- @@ -274,6 +292,8 @@
- int dxfer_direction, int dxfer_length, uint8_t *dxfer_data,
- uint8_t *status)
- {
- + unsigned int tag = 1;
- + int res;
- u3_usb_handle_t *handle_wrapper = (u3_usb_handle_t *) device->dev;
- struct usb_msc_cbw cbw;
- struct usb_msc_csw csw;
- @@ -294,16 +314,21 @@
- }
-
- // Prepare command
- - memset(&cbw, 0, sizeof(cbw));
- - cbw.dCBWSignature = CBW_SIGNATURE;
- + memset(&cbw, 0, sizeof(cbw));
- + cbw.dCBWSignature[0] = 'U';
- + cbw.dCBWSignature[1] = 'S';
- + cbw.dCBWSignature[2] = 'B';
- + cbw.dCBWSignature[3] = 'C';
- cbw.dCBWDataTransferLength = dxfer_length;
- - cbw.bmCBWFlags |= (dxfer_direction & CBW_FLAG_DIRECTION);
- - cbw.bCBWCBLength = U3_CBWCB_LEN;
- - memcpy(&(cbw.CBWCB), cmd, U3_CBWCB_LEN);
- + cbw.bmCBWFlags = dxfer_direction & CBW_FLAG_DIRECTION;
- + cbw.dCBWTag = tag;
- + cbw.bCBWLUN = 1;
- + cbw.bCBWCBLength = U3_CBWCB_LEN;
- + memcpy(&(cbw.CBWCB), cmd, U3_CBWCB_LEN);
-
- // send command
- - if (usb_bulk_write(handle_wrapper->handle, handle_wrapper->ep_out,
- - (char *) &cbw, sizeof(cbw), U3_DEVICE_TIMEOUT)
- + if ((res = usb_bulk_write(handle_wrapper->handle, handle_wrapper->ep_out,
- + (char *) &cbw, sizeof(cbw), U3_DEVICE_TIMEOUT))
- != sizeof(cbw))
- {
- u3_set_error(device, "Failed executing scsi command: "
- @@ -321,10 +346,10 @@
- if (plen > USB_MAX_PACKET_LEN)
- plen = USB_MAX_PACKET_LEN;
-
- - if (usb_bulk_write(handle_wrapper->handle,
- + if ((res = usb_bulk_write(handle_wrapper->handle,
- handle_wrapper->ep_out,
- (char *) dxfer_data+bytes_send, plen,
- - U3_DEVICE_TIMEOUT) != plen)
- + U3_DEVICE_TIMEOUT)) < 0)
- {
- u3_set_error(device, "Failed executing scsi command: "
- "Could not write data to device");
- @@ -334,9 +359,9 @@
- bytes_send += plen;
- }
- } else if (dxfer_direction == CBW_DATA_IN) {
- - if (usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
- + if ((res = usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
- (char *) dxfer_data, dxfer_length,
- - U3_DEVICE_TIMEOUT) != dxfer_length)
- + U3_DEVICE_TIMEOUT)) < 0)
- {
- u3_set_error(device, "Failed executing scsi command: "
- "Could not read data from device");
- @@ -344,16 +369,20 @@
- }
- }
-
- + memset(&csw, 0, sizeof(csw));
- +
- // read command status
- - if (usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
- - (char *) &csw, sizeof(csw), U3_DEVICE_TIMEOUT)
- - != sizeof(csw))
- + if ((res = usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
- + (char *) &csw, sizeof(csw), U3_DEVICE_TIMEOUT))
- + < 0)
- {
- u3_set_error(device, "Failed executing scsi command: "
- "Could not read command status from device");
- return U3_FAILURE;
- }
-
- + assert(tag == csw.dCSWTag);
- + tag++;
- *status = csw.bCSWStatus;
-
- return U3_SUCCESS;
|