12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496 |
- Subject: All upstream commits until r59 combined
- Author: Daviedev <daviedev@users.sourceforge.net>
- Forwarded: not-needed
- --- 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;
|