combined-r59.patch 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496
  1. Subject: All upstream commits until r59 combined
  2. Author: Daviedev <daviedev@users.sourceforge.net>
  3. Forwarded: not-needed
  4. --- a/ChangeLog
  5. +++ b/ChangeLog
  6. @@ -1,4 +1,13 @@
  7. -0.3:
  8. +1.0 Daniel J Blueman <daniel@quora.org>
  9. + - Fix behaviour with newer U3 devices
  10. + - Printing fixes
  11. + - Detach mass-storage prior to USB access
  12. + - Gracefully quit with Ctrl-C
  13. + - Print data partition size when too small
  14. + - Limit update printing rate
  15. + - Fix linking to libusb; recommended over SG
  16. +
  17. +0.3
  18. - Detect correct subsystem from configure.
  19. - Use MinGW/MSYS to build on MS Windows
  20. - Hide password input under MS Windows
  21. --- a/TODO
  22. +++ b/TODO
  23. @@ -1,6 +1,5 @@
  24. Major:
  25. - If possible open sg subsystem Read-only to work around NOMEDIUM error with encrypted partition
  26. - - Handle ctrl-c
  27. - Documentation
  28. - Further documentation of U3 features
  29. - Document which options are destructive
  30. --- a/configure.ac
  31. +++ b/configure.ac
  32. @@ -37,11 +37,11 @@
  33. # Checks for libraries.
  34. #FIXME: PKG_CHECK_MODULES not provided on MinGW
  35. -#AS_IF([ test x$subsystem = xlibusb ],
  36. -# [ PKG_CHECK_MODULES([LIBUSB], [libusb],
  37. -# [ ],
  38. -# [ AC_MSG_FAILURE([libusb is required but not found.]) ])
  39. -# ])
  40. +AS_IF([ test x$subsystem = xlibusb ],
  41. + [ PKG_CHECK_MODULES([LIBUSB], [libusb],
  42. + [ ],
  43. + [ AC_MSG_FAILURE([libusb is required but not found.]) ])
  44. + ])
  45. # Checks for header files.
  46. AC_HEADER_STDC
  47. --- /dev/null
  48. +++ b/doc/commands.txt
  49. @@ -0,0 +1,579 @@
  50. +
  51. +---
  52. +
  53. +>> 0x00
  54. +description:
  55. + Read a page with some sort of device info
  56. +
  57. +type: request
  58. +
  59. +command:
  60. +
  61. + CBWCB = 0xFF 0x00 0x00 0x03 0x00 0x27 0x00 0x00 0x00 0x00 0x00 0x00
  62. +
  63. + byte data description
  64. + ------------------------------------------------------------------------------
  65. + 0 0xFF SCSI opcode
  66. + 1-2 0x0000 command
  67. + 3-4 0x0003 Page number
  68. + 5-6 0x27 Request data length
  69. + 9 0x0 ??? sofware update tool also uses 0x01 here
  70. +
  71. + valid page numbers according to bCSWStatus:
  72. + verbatime: 0x3, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x13, 0x14
  73. +
  74. +data:
  75. + 6+ bytes
  76. +
  77. + 0000 03 00 01 00 27 00 |....'. |
  78. +
  79. + byte data description
  80. + ------------------------------------------------------------------------------
  81. + 0-1 0x0003 page number
  82. + 2-3 0x0001 ??? mostly 0x01, once 0x03
  83. + 4-5 0x0027 total usefull data length (including 6 byte header)
  84. +
  85. +
  86. +page 0x03:
  87. +
  88. + 0000 03 00 01 00 27 00 77 00 00 00 03 81 07 06 54 30 |....'.w.......T0|
  89. + 0016 30 30 30 31 31 41 31 41 41 31 31 41 41 41 31 81 |00011A1AA11AAA1.|
  90. + 0032 07 06 54 91 4e 0f 00 |..T.N..|
  91. +
  92. + byte data description
  93. + ------------------------------------------------------------------------------
  94. + 0-5 header(see above)
  95. + 6 Real size of full record...????
  96. + 7-11 ??? same for both verbatime and sandisk
  97. + 11-14 0x54060781 ??? same as @ byte 31 (actual value different on verbatim)
  98. + 15-30 "000011A1AA11AAA1" Serial number
  99. + 31-34 0x54060781 ??? same as @ byte 11
  100. + 35-38 0x000f4e91 Device size in 512-byte blocks
  101. +
  102. +page 0x0c:
  103. +
  104. + 0000 0c 00 01 00 0a 00 10 27 00 00 |.......'.. |
  105. +
  106. + byte data description
  107. + ------------------------------------------------------------------------------
  108. + 0-5 header(see above)
  109. + 6-9 0x00002710 Maximum wrong password try for secure zone.
  110. +
  111. +---
  112. +
  113. +>> 0x20
  114. +description:
  115. + Round CD size to a value the device likes
  116. +
  117. +type: action
  118. +
  119. +command:
  120. + CBWCB = 0xFF 0x20 0x00 0x02 0xFF 0x03 0x00 0x00 0x00 0x00 0x00 0x00
  121. +
  122. + byte data description
  123. + ------------------------------------------------------------------------------
  124. + 0 0xFF scsi opcode
  125. + 1-2 0x0020 command
  126. + 3 0x02 ??? can atleast be 0x02 and 0x03 but not 0, 1, 4, is
  127. + this some sort of domain id to select the partition,
  128. + like in 0x21, byte 3??? the verbatim is less picky and
  129. + accepts all values...
  130. + 4-7 0x3FF Value to round (in 512-byte sectors)
  131. + 8 0x0 Direction to round(0x00 = down, 0x01 = up)
  132. +
  133. +data:
  134. + 4 bytes
  135. +
  136. + 0000 00 02 00 00 |....|
  137. +
  138. + byte data description
  139. + ------------------------------------------------------------------------------
  140. + 0-3 0x200 Rounded value
  141. +
  142. +---
  143. +
  144. +>> 0x21
  145. +description:
  146. + get information about the partition configuration
  147. +
  148. +type: request
  149. +
  150. +command:
  151. + CBWCB = 0xFF 0x21 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  152. +
  153. + byte data description
  154. + ------------------------------------------------------------------------------
  155. +
  156. +data:
  157. +
  158. + 0000 02 02 00 00 00 91 1e 0f 00 03 01 00 00 00 30 00 |..............0.|
  159. + can be read in any multiple of 8 all dat beyond the above data is zero(0)
  160. +
  161. + u3-remover uses the following data(IIRC), (0x0f4e91 == full drive size):
  162. + 0000 01 02 00 00 00 91 4e 0f 00 |......... |
  163. +
  164. +
  165. + byte data description
  166. + ------------------------------------------------------------------------------
  167. + 0 02 amount of available records, where 1 record = 8 byte???
  168. + 1 02 ??? some sort of domain id???
  169. + 3-4 00 00 00 ??
  170. + 5-8 0x000F1E91 size of data partition in 512-byte sectors
  171. + 9 0x03 ?? some sort of domain id????
  172. + 10 0x01 ?? WARNING: If set to 0 on Sandisk cruzer, cd drive
  173. + will show up as direct-access, but can't be used, also
  174. + drive doesn't react to command 0x00, page 3 and you
  175. + won't be able to re-partition device!!!!
  176. + 11-12 00 00 ??
  177. + 13-15 0x003000 size of cdrom partitoin in 512-byte sectors
  178. +
  179. +---
  180. +
  181. +>> 0x22
  182. +description:
  183. + Repartition device
  184. +
  185. +type: action
  186. +
  187. +command:
  188. + CBWCB = 0xFF 0x22 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  189. +
  190. + byte data description
  191. + ------------------------------------------------------------------------------
  192. +
  193. +data:
  194. + 0000 02 02 00 00 00 91 1e 0f 00 03 01 00 00 00 30 00 |..............0.|
  195. + 0016 00 |. |
  196. +
  197. +
  198. + byte data description
  199. + ------------------------------------------------------------------------------
  200. + 0 0x02 amount of dword of data(+1byte+1dword=packet_size)
  201. + 1-4 0x00000002 ???
  202. + 5-8 0x000f1e91 Size of data partition in 512-byte sectors
  203. + 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...)
  204. + 13-16 0x00003000 Size of CD partition in 512-byte sectors
  205. +
  206. +---
  207. +
  208. +>> 0x42
  209. +description:
  210. + Write block of data to CD-rom partition
  211. +
  212. +type: action
  213. +
  214. +command:
  215. + CBWCB = 0xFF 0x42 0x00 0x01 0x00 0x00 0x01 0x1D 0x00 0x00 0x00 0x01
  216. +
  217. + byte data description
  218. + ------------------------------------------------------------------------------
  219. + 0 0xFF scsi opcode
  220. + 1-2 0x42 command
  221. + 3 0x01 ???
  222. + 4-7 0x0000011D Block Address (Big Endian!!!!!!!)
  223. + 8-11 0x01 ??? (Big Endian?)
  224. +
  225. +data:
  226. + A 2048 byte block
  227. +
  228. +---
  229. +
  230. +>> 0x61
  231. +description:
  232. + read out hidden data/config storage. Looks the same as with mDrive.
  233. +
  234. +type: request
  235. +
  236. +command:
  237. + CBWCB = 0xFF 0x61 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  238. +
  239. + byte data description
  240. + ------------------------------------------------------------------------------
  241. +
  242. +data:
  243. +
  244. +
  245. + byte data description
  246. + ------------------------------------------------------------------------------
  247. +
  248. +---
  249. +
  250. +>> 0x63
  251. +description:
  252. + read out hidden data/config storage. Looks the similar as with mDrive.
  253. +
  254. +type: request
  255. +
  256. +command:
  257. + CBWCB = 0xFF 0x63 0x00 0x00 0x00 0x55 0x33 0x49 0x4E 0x50 0x52 0x50
  258. +
  259. + byte data description
  260. + ------------------------------------------------------------------------------
  261. +
  262. +data:
  263. +
  264. +
  265. + byte data description
  266. + ------------------------------------------------------------------------------
  267. +
  268. +---
  269. +
  270. +>> 0xA0
  271. +description:
  272. + get some sort of data partition information
  273. +
  274. +type: request
  275. +
  276. +command:
  277. +
  278. + CBWCB = 0xFF 0xA0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  279. +
  280. + byte data description
  281. + ------------------------------------------------------------------------------
  282. +
  283. +data:
  284. + 16 byte
  285. +
  286. + 0000 40 ab 1d 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............|
  287. +
  288. + 0000 40 ab 1d 00 40 ab 1d 00 01 00 00 00 00 00 00 00 |@...@...........| (secured)
  289. +
  290. +
  291. + byte data description
  292. + ------------------------------------------------------------------------------
  293. + 0-3 0x001dab40 Total data partition size
  294. + 4-7 0x001dab40 Amount of data partition encrypted????
  295. + 8-11 0x00000001 Lock(=0) or Unlocked(=1)
  296. + 12-15 0x00000000 Wrong password try counter
  297. +
  298. +---
  299. +
  300. +>> 0xA1
  301. +description:
  302. + FUZED
  303. +
  304. +type: Request?
  305. +
  306. +command:
  307. +
  308. + CBWCB = 0xFF 0xA1 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  309. +
  310. + byte data description
  311. + ------------------------------------------------------------------------------
  312. + 0 scsi opcode
  313. + 1-2 command
  314. + 3 0 Failes on Sandisk if != 0
  315. + 4- changing these doesn't seem to have any effect
  316. +
  317. +data:
  318. +
  319. + data is random, and changes due to executing commands
  320. +
  321. + byte data description
  322. + ------------------------------------------------------------------------------
  323. +
  324. +
  325. +---
  326. +
  327. +>> 0xA2
  328. +description:
  329. + Secure data partition
  330. +
  331. + Password hash is a md5 sum of the unicode password including the terminating
  332. + null. So for a password of 'a' the following byte stream is fead to the md5
  333. + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
  334. +
  335. + It seems that if the whole of the data partition is made secure zone, then
  336. + the data currently on the data partition is accessible in the secure zone.
  337. + If only a part of the data partition is made secure zone than the first part
  338. + of the data on the partition is retained and the rest isn't accessible. In
  339. + this case the secure zone will contain garbage(the data on that was on that
  340. + part of the data partition but decrypted with an other key).
  341. +
  342. + If the device is already secured and this command is issued again, the current
  343. + data on the device is lost(if secure zone == 100%).
  344. +
  345. +type: action
  346. +
  347. +command:
  348. +
  349. + CBWCB = 0xFF 0xA2 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  350. +
  351. + byte data description
  352. + ------------------------------------------------------------------------------
  353. +
  354. +data:
  355. + 20 byte
  356. +
  357. + 0000 40 ab 1d 00 33 2c e7 85 e9 73 57 4a 1c 5f da f3 |@...3,...sWJ._..|
  358. + 0016 ee e3 f0 83 |....|
  359. +
  360. +
  361. + byte data description
  362. + ------------------------------------------------------------------------------
  363. + 0-3 0x001dab40 Size of private zone????
  364. + 4-19 ... Password hash ( pass='a')
  365. +
  366. +
  367. +---
  368. +
  369. +>> 0xA3
  370. +description:
  371. + value rounding for data partition securing
  372. +
  373. +type: request
  374. +
  375. +command:
  376. + CBWCB = 0xFF 0xA3 0x00 0x00 0x40 0xAB 0x1D 0x00 0x01 0x00 0x00 0x00
  377. +
  378. + byte data description
  379. + ------------------------------------------------------------------------------
  380. + 0 0xFF scsi opcode
  381. + 1-2 0x00A3 Command
  382. + 3 0x00 ???
  383. + 4-7 0x001DAB40 Value to round (in 512-byte sectors)
  384. + 8 0x01 Direction to round(0x00 = down, 0x01 = up)
  385. +
  386. +
  387. +data:
  388. + 4 byte
  389. +
  390. + 0000 40 ab 1d 00 |@...|
  391. +
  392. + byte data description
  393. + ------------------------------------------------------------------------------
  394. + 0-3 0x001DAB40 Rounded value
  395. +
  396. +---
  397. +
  398. +>> 0xA4
  399. +description:
  400. + unlock device
  401. +
  402. + Password hash is a md5 sum of the unicode password including the terminating
  403. + null. So for a password of 'a' the following byte stream is fead to the md5
  404. + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
  405. +
  406. +type: action
  407. +
  408. +command:
  409. +
  410. + CBWCB = 0xFF 0xA4 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  411. +
  412. + byte data description
  413. + ------------------------------------------------------------------------------
  414. +
  415. +data:
  416. + 16 byte
  417. +
  418. + 0000 33 2c e7 85 e9 73 57 4a 1c 5f da f3 ee e3 f0 83 |3,...sWJ._......|
  419. +
  420. + byte data description
  421. + ------------------------------------------------------------------------------
  422. + 0-15 ... password hash (pass='a')
  423. +
  424. +---
  425. +
  426. +>> 0xA6
  427. +description:
  428. + change password
  429. +
  430. + Password hash is a md5 sum of the unicode password including the terminating
  431. + null. So for a password of 'a' the following byte stream is fead to the md5
  432. + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
  433. +
  434. +type: action
  435. +
  436. +command:
  437. +
  438. + CBWCB = 0xFF 0xA6 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  439. +
  440. + byte data description
  441. + ------------------------------------------------------------------------------
  442. +
  443. +data:
  444. +
  445. + 0000 33 2c e7 85 e9 73 57 4a 1c 5f da f3 ee e3 f0 83 |3,...sWJ._......|
  446. + 0016 c0 51 c1 bb 98 b7 1c cb 15 b0 cf 9c 67 d1 43 ee |.Q..........g.C.|
  447. +
  448. + byte data description
  449. + ------------------------------------------------------------------------------
  450. + 0-15 ... Old password hash ( pass='a')
  451. + 16-31 ... New password hash ( pass='b')
  452. +
  453. +---
  454. +
  455. +>> 0xA7
  456. +description:
  457. + Remove security
  458. +
  459. + Password hash is a md5 sum of the unicode password including the terminating
  460. + null. So for a password of 'a' the following byte stream is fead to the md5
  461. + function: 0x61 0x00 0x00 0x00 == UNICODE "a\0"
  462. +
  463. + hmm... if security zone size != size of data partition, then this fails!!!
  464. + it returns a failed status but doesn't increase the password try counter,
  465. + even if password was incorrect.... to remove the secure zone if it doesn't
  466. + fully occupy the data partition, recreate the secure zone with maximum size.
  467. + > Possible cause: If this command is issued the secure zone becomes the public
  468. + zone, and thus all data on the disk will be retained. It is suspected that all
  469. + partitions/zones are stored encrypted on the flash device(Yes, even the public
  470. + zone). So, if this command is issued the secure zone key is decrypted(if
  471. + encrypted at all) and the zone is marked as public. Logically this would not
  472. + work if there is a public and secure zone. Then you would end up with two
  473. + public zone's with different encryptions keys.
  474. +
  475. + Byte 3 of command does something... but still doesn't allow for removing half
  476. + secure zones.
  477. +
  478. +type: action
  479. +
  480. +command:
  481. +
  482. + CBWCB = 0xFF 0xA7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  483. +
  484. + byte data description
  485. + ------------------------------------------------------------------------------
  486. +
  487. +data:
  488. +
  489. + 0000 c0 51 c1 bb 98 b7 1c cb 15 b0 cf 9c 67 d1 43 ee |.Q..........g.C.|
  490. +
  491. + byte data description
  492. + ------------------------------------------------------------------------------
  493. + 0-15 ... Password hash (in this case 'b')
  494. +
  495. +---
  496. +
  497. +>> 0x100
  498. +description:
  499. + seen used after a 0xA4(with some normal scsi stuff in between...).
  500. + generate reset some sort of reset or insert condition on data disk. Linux old 2.4
  501. + usb-storage sees it as a disconnect of the drive.
  502. +
  503. +type:
  504. +
  505. +command:
  506. +
  507. + CBWCB = 0xFF 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  508. +
  509. + byte data description
  510. + ------------------------------------------------------------------------------
  511. +
  512. +data:
  513. + No data....
  514. +
  515. +
  516. +---
  517. +
  518. +>> 0x101
  519. +description:
  520. + disconnect's and possibly reconnects device
  521. +
  522. +type: action
  523. +
  524. +command:
  525. +
  526. + CBWCB = 0xFF 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  527. +
  528. + byte data description
  529. + ------------------------------------------------------------------------------
  530. +
  531. +data:
  532. + 12 bytes
  533. +
  534. + 0000 50 00 00 00 40 9c 00 00 01 00 00 00 |P...@.......|
  535. +
  536. + byte data description
  537. + ------------------------------------------------------------------------------
  538. + 8 0x01 If 1 reconnect after disconnect, else not
  539. + all other byte's dont seem to have any effect...
  540. +
  541. +---
  542. +
  543. +>> 0x103
  544. +description:
  545. +Get chip maker and version
  546. +
  547. +type: request
  548. +
  549. +command:
  550. +
  551. + CBWCB = 0xFF 0x03 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  552. +
  553. + byte data description
  554. + ------------------------------------------------------------------------------
  555. +
  556. +data:
  557. + 24 bytes
  558. +
  559. + 0000 33 2e 32 31 00 00 00 00 53 61 6e 44 69 73 6b 20 |3.21....SanDisk |
  560. + 0016 00 00 00 00 00 00 00 00 |........|
  561. +
  562. + byte data description
  563. + ------------------------------------------------------------------------------
  564. + 0-7 "3.21" Chip version
  565. + 8-23 "SanDisk" Chip maker
  566. +
  567. +
  568. +
  569. +
  570. +
  571. +
  572. +
  573. +possible read commands:
  574. +0x20
  575. +0x21
  576. +0x61
  577. +0x63
  578. +0x68
  579. +0x6b 512?
  580. +0x81 128-byte
  581. +0x84 64-byte
  582. +0x85 64-byte
  583. +0x88 64-byte
  584. +0xa1 4-byte
  585. +0xc1
  586. +0xe2 = read random?, 64-byte
  587. +
  588. +0x102 512-byte
  589. +
  590. +Write:
  591. +0x01 -> 0x1f
  592. +0x22 -> 0x40
  593. +0x42
  594. +0x60
  595. +0x62
  596. +0x6a
  597. +0x6c
  598. +0x6d
  599. +0x6e
  600. +0x82 128 byte
  601. +0x83 64 byte?
  602. +0x86
  603. +0x87
  604. +0xc0
  605. +0xc2
  606. +
  607. +
  608. +
  609. +
  610. +---
  611. +
  612. +>>
  613. +description:
  614. +
  615. +type:
  616. +
  617. +command:
  618. +
  619. + byte data description
  620. + ------------------------------------------------------------------------------
  621. +
  622. +data:
  623. +
  624. +
  625. + byte data description
  626. + ------------------------------------------------------------------------------
  627. +
  628. +
  629. --- a/src/display_progress.c
  630. +++ b/src/display_progress.c
  631. @@ -20,17 +20,18 @@
  632. #include <stdio.h>
  633. void display_progress(unsigned int cur, unsigned int total) {
  634. - unsigned int procent;
  635. - unsigned int bar_len;
  636. - int i;
  637. + static unsigned int last = 0;
  638. + unsigned int percent;
  639. + unsigned int bar_len, i;
  640. if (total == 0) return;
  641. - procent = (cur * 100) / total;
  642. + percent = (cur * 100) / total;
  643. + if (percent == last) return;
  644. putchar('|');
  645. bar_len = (cur * PROGRESS_BAR_WIDTH) / total;
  646. - for (i =0; i < bar_len; i++) {
  647. + for (i = 0; i < bar_len; i++) {
  648. putchar('*');
  649. }
  650. for (i = bar_len; i < PROGRESS_BAR_WIDTH; i++) {
  651. @@ -38,6 +39,8 @@
  652. }
  653. putchar('|');
  654. - printf(" %d%%\r", procent);
  655. + printf(" %d%%\r", percent);
  656. fflush(stdout);
  657. +
  658. + last = percent;
  659. }
  660. --- a/src/main.c
  661. +++ b/src/main.c
  662. @@ -24,6 +24,8 @@
  663. #include <stdlib.h>
  664. #include <string.h>
  665. #include <unistd.h>
  666. +#include <signal.h>
  667. +#include <assert.h>
  668. #include <sys/types.h>
  669. #include <sys/stat.h>
  670. @@ -42,10 +44,11 @@
  671. #define MAX_FILENAME_STRING_LENGTH 1024
  672. #define MAX_PASSWORD_LENGTH 1024
  673. -char *version = VERSION;
  674. +static char *version = VERSION;
  675. int debug = 0;
  676. -int batch_mode = 0;
  677. +static int batch_mode = 0;
  678. +static int quit = 0;
  679. enum action_t { unknown, load, partition, dump, info, unlock, change_password,
  680. enable_security, disable_security, reset_security };
  681. @@ -57,7 +60,7 @@
  682. *
  683. * @returns TRUE if user wants to continue else FALSE to abort.
  684. */
  685. -int confirm() {
  686. +static int confirm(void) {
  687. char c;
  688. int retval;
  689. int done;
  690. @@ -93,24 +96,24 @@
  691. /**
  692. * Symbols of size multiplication factors.
  693. */
  694. -char factor_symbols[] = "kMGTPE";
  695. +static char factor_symbols[] = " kMGTPE";
  696. /**
  697. * Print bytes is human readable fashion.
  698. *
  699. * @param size Data size to print
  700. */
  701. -void print_human_size(uint64_t size) {
  702. - float fsize = 0;
  703. +static void print_human_size(uint64_t size) {
  704. + double fsize = 0;
  705. unsigned int factor = 0;
  706. fsize = size;
  707. - while (fsize > 1024) {
  708. + while (fsize >= 1024) {
  709. fsize /= 1024;
  710. factor++;
  711. }
  712. - printf("%.2f %cB", fsize, factor_symbols[factor-1]);
  713. + printf("%.2f %cB", fsize, factor_symbols[factor]);
  714. }
  715. /**
  716. @@ -122,7 +125,7 @@
  717. * @returns U3_SUCCESS if successful, else U3_FAILURE and
  718. * an error string can be obtained using u3_error()
  719. */
  720. -int get_tries_left(u3_handle_t *device, int *tries) {
  721. +static int get_tries_left(u3_handle_t *device, int *tries) {
  722. struct dpart_info dpinfo;
  723. struct property_0C security_properties;
  724. @@ -151,10 +154,10 @@
  725. /********************************** Actions ***********************************/
  726. -int do_load(u3_handle_t *device, char *iso_filename) {
  727. +static int do_load(u3_handle_t *device, char *iso_filename) {
  728. struct stat file_stat;
  729. struct part_info pinfo;
  730. - uint32_t cd_size;
  731. + off_t cd_size;
  732. FILE *fp;
  733. uint8_t buffer[U3_BLOCK_SIZE];
  734. unsigned int bytes_read=0;
  735. @@ -171,10 +174,10 @@
  736. return EXIT_FAILURE;
  737. }
  738. - cd_size = file_stat.st_size / U3_SECTOR_SIZE;
  739. + cd_size = ((uintmax_t) file_stat.st_size) / U3_SECTOR_SIZE;
  740. if (file_stat.st_size % U3_SECTOR_SIZE)
  741. cd_size++;
  742. - block_cnt = file_stat.st_size / U3_BLOCK_SIZE;
  743. + block_cnt = ((uintmax_t) file_stat.st_size) / U3_BLOCK_SIZE;
  744. if (file_stat.st_size % U3_BLOCK_SIZE)
  745. block_cnt++;
  746. @@ -186,10 +189,10 @@
  747. }
  748. if (cd_size > pinfo.cd_size) {
  749. - fprintf(stderr, "CD image(%lu byte) is to big for current cd "
  750. - "partition(%u byte), please repartition device.\n",
  751. - file_stat.st_size,
  752. - U3_SECTOR_SIZE * pinfo.cd_size);
  753. + fprintf(stderr, "CD image (%ju bytes) is to big for current CD "
  754. + "partition (%llu bytes)\n",
  755. + (uintmax_t) file_stat.st_size,
  756. + 1ll * U3_SECTOR_SIZE * pinfo.cd_size);
  757. return EXIT_FAILURE;
  758. }
  759. @@ -228,7 +231,7 @@
  760. }
  761. block_num++;
  762. - } while (!feof(fp));
  763. + } while (!feof(fp) && !quit);
  764. display_progress(block_num, block_cnt);
  765. putchar('\n');
  766. @@ -238,7 +241,7 @@
  767. return EXIT_SUCCESS;
  768. }
  769. -int do_partition(u3_handle_t *device, char *size_string) {
  770. +static int do_partition(u3_handle_t *device, char *size_string) {
  771. uint64_t size;
  772. uint32_t cd_sectors;
  773. @@ -263,7 +266,7 @@
  774. return EXIT_SUCCESS;
  775. }
  776. -int do_unlock(u3_handle_t *device, char *password) {
  777. +static int do_unlock(u3_handle_t *device, char *password) {
  778. int result=0;
  779. int tries_left=0;
  780. @@ -297,7 +300,7 @@
  781. }
  782. }
  783. -int do_change_password(u3_handle_t *device, char *password,
  784. +static int do_change_password(u3_handle_t *device, char *password,
  785. char *new_password)
  786. {
  787. int result=0;
  788. @@ -335,7 +338,7 @@
  789. }
  790. }
  791. -int do_enable_security(u3_handle_t *device, char *password) {
  792. +static int do_enable_security(u3_handle_t *device, char *password) {
  793. if (u3_enable_security(device, password) != U3_SUCCESS) {
  794. fprintf(stderr, "u3_enable_security() failed: %s\n",
  795. u3_error_msg(device));
  796. @@ -345,7 +348,7 @@
  797. return EXIT_SUCCESS;
  798. }
  799. -int do_disable_security(u3_handle_t *device, char *password) {
  800. +static int do_disable_security(u3_handle_t *device, char *password) {
  801. int result=0;
  802. int tries_left=0;
  803. @@ -380,7 +383,7 @@
  804. }
  805. }
  806. -int do_reset_security(u3_handle_t *device) {
  807. +static int do_reset_security(u3_handle_t *device) {
  808. int result=0;
  809. // the enable security command is always possible without the correct
  810. @@ -408,7 +411,7 @@
  811. }
  812. }
  813. -int do_info(u3_handle_t *device) {
  814. +static int do_info(u3_handle_t *device) {
  815. struct part_info pinfo;
  816. struct dpart_info dpinfo;
  817. struct chip_info cinfo;
  818. @@ -484,8 +487,8 @@
  819. return EXIT_SUCCESS;
  820. }
  821. -int do_dump(u3_handle_t *device) {
  822. - int retval = EXIT_SUCCESS;
  823. +static int do_dump(u3_handle_t *device) {
  824. + int retval;
  825. struct part_info pinfo;
  826. struct dpart_info dpinfo;
  827. @@ -595,12 +598,12 @@
  828. }
  829. }
  830. - return EXIT_SUCCESS;
  831. + return retval;
  832. }
  833. /************************************ Main ************************************/
  834. -void usage(const char *name) {
  835. +static void usage(const char *name) {
  836. printf("u3-tool %s - U3 USB stick manager\n", version);
  837. printf("\n");
  838. printf("Usage: %s [options] <device name>\n", name);
  839. @@ -622,7 +625,7 @@
  840. printf("For the device name use:\n %s\n", u3_subsystem_help);
  841. }
  842. -void print_version() {
  843. +static void print_version(void) {
  844. printf("u3-tool %s\n", version);
  845. printf("subsystem: %s\n", u3_subsystem_name);
  846. printf("\n");
  847. @@ -632,6 +635,10 @@
  848. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
  849. }
  850. +static void set_quit(int sig) {
  851. + quit = 1;
  852. +}
  853. +
  854. int main(int argc, char *argv[]) {
  855. u3_handle_t device;
  856. @@ -711,6 +718,9 @@
  857. }
  858. device_name = argv[optind];
  859. + assert(signal(SIGINT, set_quit) != SIG_ERR);
  860. + assert(signal(SIGTERM, set_quit) != SIG_ERR);
  861. +
  862. //
  863. // open the device
  864. //
  865. @@ -772,9 +782,9 @@
  866. case partition:
  867. printf("\n");
  868. printf("WARNING: Loading a new cd image causes the ");
  869. - printf("whole device to be whiped. This INCLUDES\n ");
  870. + printf("whole device to be wiped. This INCLUDES\n ");
  871. printf("the data partition.\n");
  872. - printf("I repeat: ANY EXCISTING DATA WILL BE LOST!\n");
  873. + printf("I repeat: ANY EXISTING DATA WILL BE LOST!\n");
  874. if (confirm())
  875. retval = do_partition(&device, size_string);
  876. break;
  877. --- a/src/secure_input.c
  878. +++ b/src/secure_input.c
  879. @@ -33,9 +33,9 @@
  880. DWORD mode;
  881. HANDLE ih;
  882. #else
  883. - struct termio ttymode;
  884. + struct termios ttymode;
  885. #endif
  886. - int pos;
  887. + size_t pos;
  888. int ch;
  889. // input checking
  890. @@ -51,9 +51,9 @@
  891. }
  892. SetConsoleMode(ih, mode & ~(ENABLE_ECHO_INPUT ));
  893. #else
  894. - ioctl(STDIN_FILENO, TCGETA, &ttymode);
  895. + tcgetattr(STDIN_FILENO, &ttymode);
  896. ttymode.c_lflag &= ~( ECHO | ECHOE | ECHONL );
  897. - ioctl(STDIN_FILENO, TCSETAF, &ttymode);
  898. + tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttymode);
  899. #endif
  900. pos=0;
  901. @@ -75,7 +75,7 @@
  902. fputc('\n', stdout);
  903. #else
  904. ttymode.c_lflag |= ECHO | ECHOE | ECHONL;
  905. - ioctl(STDIN_FILENO, TCSETAF, &ttymode);
  906. + tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttymode);
  907. fputc('\n', stdout);
  908. #endif
  909. }
  910. --- a/src/u3_commands.c
  911. +++ b/src/u3_commands.c
  912. @@ -52,10 +52,9 @@
  913. * U3_PASSWORD_HASH_LEN long.
  914. */
  915. void u3_pass_to_hash(const char *password, uint8_t *hash) {
  916. - unsigned int passlen;
  917. + unsigned int passlen, i;
  918. unsigned int unicode_passlen;
  919. uint8_t *unicode_pass;
  920. - int i;
  921. passlen = strlen(password);
  922. unicode_passlen = (passlen+1)*2;
  923. @@ -178,7 +177,7 @@
  924. return U3_FAILURE;
  925. }
  926. if (cd_size > device_properties.device_size) {
  927. - u3_set_error(device, "Requested CD size is to big for device");
  928. + u3_set_error(device, "Requested CD size is larger than device (%ull bytes)", device_properties.device_size << 9ULL);
  929. return U3_FAILURE;
  930. }
  931. --- /dev/null
  932. +++ b/src/u3_scsi_debug.c
  933. @@ -0,0 +1,111 @@
  934. +/**
  935. + * u3-tool - U3 USB stick manager
  936. + * Copyright (C) 2007 Daviedev, daviedev@users.sourceforge.net
  937. + *
  938. + * This program is free software; you can redistribute it and/or modify
  939. + * it under the terms of the GNU General Public License as published by
  940. + * the Free Software Foundation; either version 2 of the License, or
  941. + * (at your option) any later version.
  942. + *
  943. + * This program is distributed in the hope that it will be useful,
  944. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  945. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  946. + * GNU General Public License for more details.
  947. + *
  948. + * You should have received a copy of the GNU General Public License along
  949. + * with this program; if not, write to the Free Software Foundation, Inc.,
  950. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  951. + */
  952. +#include "u3_scsi.h"
  953. +#include "u3_error.h"
  954. +
  955. +#include <sys/types.h>
  956. +#include <sys/stat.h>
  957. +#include <sys/ioctl.h>
  958. +#include <stdlib.h>
  959. +#include <fcntl.h>
  960. +#include <string.h>
  961. +#include <unistd.h>
  962. +#include <errno.h>
  963. +
  964. +#include <stdio.h>
  965. +
  966. +#include "sg_err.h"
  967. +
  968. +#define U3_TIMEOUT 2000 //2000 millisecs == 2 seconds
  969. +
  970. +int u3_open(u3_handle_t *device, const char *which)
  971. +{
  972. + FILE *fp;
  973. +
  974. + u3_set_error(device, "");
  975. + device->dev = NULL;
  976. +
  977. + if (strcmp(which, "stdout") == 0) {
  978. + fp = stdout;
  979. + } else if (strcmp(which, "stderr") == 0) {
  980. + fp = stderr;
  981. + } else {
  982. + u3_set_error(device, "unknown output '%s', 'stdout' and "
  983. + "'stderr' only supported", which);
  984. + return U3_FAILURE;
  985. + }
  986. +
  987. + device->dev = fp;
  988. + return U3_SUCCESS;
  989. +}
  990. +
  991. +void u3_close(u3_handle_t *device)
  992. +{
  993. + FILE *fp = (FILE *)(device->dev);
  994. +// if (fp != stdout && fp != stderr) {
  995. +// fclose(fp);
  996. +// }
  997. +}
  998. +
  999. +int u3_send_cmd(u3_handle_t *device, uint8_t cmd[U3_CMD_LEN],
  1000. + int dxfer_direction, int dxfer_length, uint8_t *dxfer_data,
  1001. + uint8_t *status)
  1002. +{
  1003. + FILE *fp = (FILE *)device->dev;
  1004. + int i;
  1005. +
  1006. + fprintf(fp, "---------------------------------------------------------"
  1007. + "-----------------------\n");
  1008. +
  1009. + fprintf(fp, "Command block:\n");
  1010. + for (i=0; i < U3_CMD_LEN; i++) {
  1011. + fprintf(fp, "%.2X ", cmd[i]);
  1012. + }
  1013. + fprintf(fp, "\n");
  1014. +
  1015. + fprintf(fp, "\n");
  1016. + switch (dxfer_direction) {
  1017. + case U3_DATA_NONE:
  1018. + fprintf(fp, "No data\n");
  1019. + break;
  1020. + case U3_DATA_TO_DEV:
  1021. + fprintf(fp, "Sending %d bytes of data to device\n", dxfer_length);
  1022. +
  1023. + fprintf(fp, "Data:");
  1024. + for (i=0; i < dxfer_length; i++) {
  1025. + if (i % 8 == 0) fprintf(fp, "\n%.4x\t", i);
  1026. + fprintf(fp, "%.2x ", dxfer_data[i]);
  1027. + }
  1028. + fprintf(fp, "\n");
  1029. + break;
  1030. + case U3_DATA_FROM_DEV:
  1031. + fprintf(fp, "Reading %d bytes of data from device\n", dxfer_length);
  1032. + memset(dxfer_data, 0, dxfer_length);
  1033. + break;
  1034. + }
  1035. +
  1036. + fprintf(fp, "---------------------------------------------------------"
  1037. + "-----------------------\n");
  1038. +
  1039. + *status = 0;
  1040. +
  1041. + return U3_SUCCESS;
  1042. +}
  1043. +
  1044. +
  1045. --- a/src/u3_scsi_sg.c
  1046. +++ b/src/u3_scsi_sg.c
  1047. @@ -32,13 +32,14 @@
  1048. #include <string.h>
  1049. #include <unistd.h>
  1050. #include <errno.h>
  1051. +#include <string.h>
  1052. #include <linux/cdrom.h>
  1053. #include <scsi/sg.h>
  1054. #include "sg_err.h"
  1055. -#define U3_TIMEOUT 2000 //2000 millisecs == 2 seconds
  1056. +#define SG_TIMEOUT 2000 //2000 millisecs == 2 seconds
  1057. const char *u3_subsystem_name = "sg";
  1058. const char *u3_subsystem_help = "'/dev/sda0', '/dev/sg3'";
  1059. @@ -97,6 +98,7 @@
  1060. {
  1061. int *sg_fd = (int *)device->dev;
  1062. close(*sg_fd);
  1063. + free(sg_fd);
  1064. }
  1065. int u3_send_cmd(u3_handle_t *device, uint8_t cmd[U3_CMD_LEN],
  1066. @@ -123,23 +125,23 @@
  1067. // Prepare command
  1068. memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
  1069. io_hdr.interface_id = 'S'; // fixed
  1070. + io_hdr.dxfer_direction = dxfer_direction; // Select data direction
  1071. io_hdr.cmd_len = U3_CMD_LEN; // length of command in bytes
  1072. - // io_hdr.iovec_count = 0; // don't use iovector stuff
  1073. - io_hdr.mx_sb_len = sizeof(sense_buf); // sense buffer size. do we use this???
  1074. - io_hdr.dxfer_direction = dxfer_direction; // send data to device
  1075. + io_hdr.mx_sb_len = 0; // sense buffer size. do we use this???
  1076. + io_hdr.iovec_count = 0; // don't use iovector stuff
  1077. io_hdr.dxfer_len = dxfer_length; // Size of data transfered
  1078. io_hdr.dxferp = dxfer_data; // Data buffer to transfer
  1079. io_hdr.cmdp = cmd; // Command buffer to execute
  1080. io_hdr.sbp = sense_buf; // Sense buffer
  1081. - io_hdr.timeout = U3_TIMEOUT; // timeout
  1082. - // io_hdr.flags = 0; // take defaults: indirect IO, etc
  1083. + io_hdr.timeout = SG_TIMEOUT; // timeout
  1084. + io_hdr.flags = 0; // take defaults: indirect IO, etc
  1085. // io_hdr.pack_id = 0; // internal packet. used by te program to recognize packets
  1086. // io_hdr.usr_ptr = NULL; // user data
  1087. // preform ioctl on device
  1088. if (ioctl(*sg_fd, SG_IO, &io_hdr) < 0) {
  1089. u3_set_error(device, "Failed executing scsi command: "
  1090. - "SG_IO ioctl Failed");
  1091. + "SG_IO ioctl failed with %s", strerror(errno));
  1092. return U3_FAILURE;
  1093. }
  1094. --- a/src/u3_scsi_spt.c
  1095. +++ b/src/u3_scsi_spt.c
  1096. @@ -36,7 +36,7 @@
  1097. #include <windows.h>
  1098. #include <ddk/ntddscsi.h>
  1099. -#define U3_TIMEOUT 2 // 2 seconds
  1100. +#define SPT_TIMEOUT 2 // 2 seconds
  1101. const char *u3_subsystem_name = "spt";
  1102. const char *u3_subsystem_help = "The drive letter of the device";
  1103. @@ -58,11 +58,11 @@
  1104. return U3_FAILURE;
  1105. }
  1106. - //take the drive letter and put it in the format used in CreateFile
  1107. + // Take the drive letter and put it in the format used in CreateFile
  1108. memcpy(lpszDeviceName, (char *) "\\\\.\\*:", 7);
  1109. lpszDeviceName[4] = which[0];
  1110. - //get a handle to the device, the parameters used here must be used in order for this to work
  1111. + // Get a handle to the device, the parameters used here must be used in order for this to work
  1112. hDevice=CreateFile(lpszDeviceName,
  1113. GENERIC_READ|GENERIC_WRITE,
  1114. FILE_SHARE_READ|FILE_SHARE_WRITE,
  1115. @@ -71,7 +71,8 @@
  1116. FILE_ATTRIBUTE_NORMAL,
  1117. NULL);
  1118. - //if for some reason we couldn't get a handle to the device we will try again using slightly different parameters for CreateFile
  1119. + // If for some reason we couldn't get a handle to the device we will try again using slightly
  1120. + // different parameters for CreateFile
  1121. if (hDevice==INVALID_HANDLE_VALUE)
  1122. {
  1123. u3_set_error(device, "Failed openning handle for %s: Error %d\n", which, GetLastError());
  1124. @@ -118,19 +119,40 @@
  1125. sptd.SenseInfoLength = 0; // don't use this currently...
  1126. sptd.DataIn = dxfer_direction; // data direction
  1127. sptd.DataTransferLength = dxfer_length; // Size of data transfered
  1128. - sptd.TimeOutValue = U3_TIMEOUT; // timeout in seconds
  1129. + sptd.TimeOutValue = SPT_TIMEOUT; // timeout in seconds
  1130. sptd.DataBuffer = dxfer_data; // data buffer
  1131. //sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, sbuf);
  1132. memcpy(sptd.Cdb, cmd, U3_CMD_LEN);
  1133. // preform ioctl on device
  1134. - err = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
  1135. - sizeof(sptd), &sptd, sizeof(sptd), &returned, NULL);
  1136. + err = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
  1137. + sizeof(sptd), &sptd, sizeof(sptd), &returned, NULL);
  1138. // evaluate result
  1139. if (!err) {
  1140. - u3_set_error(device, "Failed executing scsi command: "
  1141. - "Error %d", GetLastError());
  1142. + DWORD errcode;
  1143. + LPVOID lpMsgBuf;
  1144. +
  1145. + errcode = GetLastError();
  1146. +
  1147. + err = FormatMessage(
  1148. + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  1149. + NULL,
  1150. + errcode,
  1151. + 0,
  1152. + (LPTSTR) &lpMsgBuf,
  1153. + 0,
  1154. + NULL);
  1155. +
  1156. + if (err != 0) {
  1157. + u3_set_error(device, "Failed executing scsi command: "
  1158. + "%s (Error %d)", lpMsgBuf, errcode);
  1159. + LocalFree(lpMsgBuf);
  1160. + } else {
  1161. + u3_set_error(device, "Failed executing scsi command: "
  1162. + "Unknown Error %d", errcode);
  1163. + }
  1164. +
  1165. return U3_FAILURE;
  1166. }
  1167. --- a/src/u3_scsi_usb.c
  1168. +++ b/src/u3_scsi_usb.c
  1169. @@ -1,6 +1,6 @@
  1170. /**
  1171. * u3-tool - U3 USB stick manager
  1172. - * Copyright (C) 2007 Daviedev, daviedev@users.sourceforge.net
  1173. + * Copyright (C) 2011 Daviedev, daviedev@users.sourceforge.net
  1174. *
  1175. * This program is free software; you can redistribute it and/or modify
  1176. * it under the terms of the GNU General Public License as published by
  1177. @@ -30,34 +30,35 @@
  1178. #include <fcntl.h>
  1179. #include <string.h>
  1180. #include <unistd.h>
  1181. +#include <assert.h>
  1182. #include <usb.h>
  1183. #include <errno.h>
  1184. #include <regex.h>
  1185. // USB maximum packet length
  1186. -#define USB_MAX_PACKET_LEN 256
  1187. +#define USB_MAX_PACKET_LEN 2048
  1188. // USB command block wrapper length
  1189. #define U3_CBWCB_LEN 12
  1190. -// USB MSC command/status wrapper signatures
  1191. -#define CBW_SIGNATURE 0x43425355
  1192. -#define CSW_SIGNATURE 0x53425355
  1193. -
  1194. // USB MSC command block wrapper data direction bits
  1195. #define CBW_DATA_IN 0x80
  1196. #define CBW_DATA_OUT 0x00
  1197. #define CBW_DATA_NONE 0x00
  1198. #define CBW_FLAG_DIRECTION 0x80
  1199. -#define U3_DEVICE_TIMEOUT 20000 //2000 millisecs == 2 seconds
  1200. +#define U3_DEVICE_TIMEOUT 2000 //2000 millisecs == 2 seconds
  1201. -#define U3_DEV_LIST_LENGTH 4
  1202. -uint16_t u3_dev_list[U3_DEV_LIST_LENGTH][2] = {
  1203. +uint16_t u3_dev_list[][2] = {
  1204. { 0x08ec, 0x0020 }, // Verbatim Store 'N Go
  1205. { 0x0781, 0x5406 }, // Sandisk Cruzer Micro
  1206. { 0x0781, 0x5408 }, // Sandisk Cruzer Titanium
  1207. { 0x0781, 0x550a }, // Sandisk Cruzer Pattern
  1208. + { 0x0781, 0x5151 }, // Sandisk Cruzer Micro Skin 8GB (Thanks to dnelson @sf)
  1209. + { 0x0781, 0x540e }, // Sandisk Cruzer Contour
  1210. + { 0x0781, 0x5530 }, // Sandisk Cruzer
  1211. + { 0x0781, 0x5535 }, // Sandisk Ultra Backup
  1212. + { 0, 0 },
  1213. };
  1214. struct u3_usb_handle {
  1215. @@ -69,7 +70,7 @@
  1216. typedef struct u3_usb_handle u3_usb_handle_t;
  1217. struct usb_msc_cbw {
  1218. - uint32_t dCBWSignature;
  1219. + uint8_t dCBWSignature[4];
  1220. uint32_t dCBWTag;
  1221. uint32_t dCBWDataTransferLength;
  1222. uint8_t bmCBWFlags;
  1223. @@ -79,7 +80,7 @@
  1224. } __attribute__ ((packed));
  1225. struct usb_msc_csw {
  1226. - uint32_t dCSWSignature;
  1227. + uint8_t dCSWSignature[4];
  1228. uint32_t dCSWTag;
  1229. uint32_t dCSWDataResidue;
  1230. uint8_t bCSWStatus;
  1231. @@ -88,7 +89,7 @@
  1232. const char *u3_subsystem_name = "libusb";
  1233. const char *u3_subsystem_help = "'scan' to automatically use the first detected U3 device, or 'vid:pid' if not detected";
  1234. -struct usb_device *
  1235. +static struct usb_device *
  1236. locate_u3_device(uint16_t vid, uint16_t pid)
  1237. {
  1238. struct usb_bus *bus;
  1239. @@ -115,6 +116,7 @@
  1240. {
  1241. uint16_t vid, pid;
  1242. regex_t vid_pid_regex;
  1243. + int has_vid_pid = 0;
  1244. struct usb_device *u3_device;
  1245. u3_usb_handle_t *handle_wrapper;
  1246. @@ -125,7 +127,6 @@
  1247. int err;
  1248. char errbuf[U3_MAX_ERROR_LEN];
  1249. - int i;
  1250. // init
  1251. u3_set_error(device, "");
  1252. @@ -137,25 +138,45 @@
  1253. "expression: %s", errbuf);
  1254. return U3_FAILURE;
  1255. }
  1256. + if (regexec(&vid_pid_regex, which, 0, 0, 0) == 0) {
  1257. + // Do de regexing here, this prevents leaking of the
  1258. + // vid_pid_regex memory
  1259. + char *seperator=0;
  1260. + has_vid_pid = 1;
  1261. + vid = strtoul(which, &seperator, 16);
  1262. + pid = strtoul(seperator+1, &seperator, 16);
  1263. + }
  1264. + regfree(&vid_pid_regex);
  1265. usb_init();
  1266. if (debug)
  1267. usb_set_debug(255);
  1268. // Find device
  1269. - if (regexec(&vid_pid_regex, which, 0, 0, 0) == 0) {
  1270. - char *seperator=0;
  1271. - vid = strtoul(which, &seperator, 16);
  1272. - pid = strtoul(seperator+1, &seperator, 16);
  1273. + if (has_vid_pid) {
  1274. u3_device = locate_u3_device(vid, pid);
  1275. +
  1276. + if (u3_device == NULL) {
  1277. + u3_set_error(device, "Could not locate the U3 device '%s', "
  1278. + "try 'scan' for first available device", which);
  1279. + return U3_FAILURE;
  1280. + }
  1281. } else if (strcmp(which, "scan") == 0) {
  1282. - i = 0;
  1283. + int i = 0;
  1284. u3_device = NULL;
  1285. - while (u3_device == NULL && i < U3_DEV_LIST_LENGTH) {
  1286. + while (u3_device == NULL &&
  1287. + !(u3_dev_list[i][0] == 0 && u3_dev_list[i][1] == 0))
  1288. + {
  1289. u3_device = locate_u3_device(u3_dev_list[i][0],
  1290. u3_dev_list[i][1]);
  1291. i++;
  1292. }
  1293. +
  1294. + if (u3_device == NULL) {
  1295. + u3_set_error(device, "Could not locate any known U3 device, "
  1296. + "the VID:PID of your device might not be known to U3 tool");
  1297. + return U3_FAILURE;
  1298. + }
  1299. // } else if (regexec(&serial_regex, which, 0, 0, 0) == 0) {
  1300. //TODO: search for a specific serial number
  1301. } else {
  1302. @@ -164,14 +185,6 @@
  1303. return U3_FAILURE;
  1304. }
  1305. - regfree(&vid_pid_regex);
  1306. -
  1307. - if (u3_device == NULL) {
  1308. - u3_set_error(device, "Could not locate the U3 device '%s', "
  1309. - "try 'scan' for first available device", which);
  1310. - return U3_FAILURE;
  1311. - }
  1312. -
  1313. // Open device
  1314. handle_wrapper = (u3_usb_handle_t *) malloc(sizeof(u3_usb_handle_t));
  1315. if (handle_wrapper == NULL) {
  1316. @@ -203,8 +216,13 @@
  1317. goto open_fail;
  1318. }
  1319. interface_desc = config_desc->interface->altsetting;
  1320. -
  1321. handle_wrapper->interface_num = interface_desc->bInterfaceNumber;
  1322. + err = usb_detach_kernel_driver_np(handle_wrapper->handle, handle_wrapper->interface_num);
  1323. + if (err != 0 && err != -61) {
  1324. + u3_set_error(device, "failed to detach USB device with %s", strerror(errno));
  1325. + goto open_fail;
  1326. + }
  1327. +
  1328. if ((err=usb_claim_interface(handle_wrapper->handle,
  1329. handle_wrapper->interface_num)) != 0)
  1330. {
  1331. @@ -274,6 +292,8 @@
  1332. int dxfer_direction, int dxfer_length, uint8_t *dxfer_data,
  1333. uint8_t *status)
  1334. {
  1335. + unsigned int tag = 1;
  1336. + int res;
  1337. u3_usb_handle_t *handle_wrapper = (u3_usb_handle_t *) device->dev;
  1338. struct usb_msc_cbw cbw;
  1339. struct usb_msc_csw csw;
  1340. @@ -294,16 +314,21 @@
  1341. }
  1342. // Prepare command
  1343. - memset(&cbw, 0, sizeof(cbw));
  1344. - cbw.dCBWSignature = CBW_SIGNATURE;
  1345. + memset(&cbw, 0, sizeof(cbw));
  1346. + cbw.dCBWSignature[0] = 'U';
  1347. + cbw.dCBWSignature[1] = 'S';
  1348. + cbw.dCBWSignature[2] = 'B';
  1349. + cbw.dCBWSignature[3] = 'C';
  1350. cbw.dCBWDataTransferLength = dxfer_length;
  1351. - cbw.bmCBWFlags |= (dxfer_direction & CBW_FLAG_DIRECTION);
  1352. - cbw.bCBWCBLength = U3_CBWCB_LEN;
  1353. - memcpy(&(cbw.CBWCB), cmd, U3_CBWCB_LEN);
  1354. + cbw.bmCBWFlags = dxfer_direction & CBW_FLAG_DIRECTION;
  1355. + cbw.dCBWTag = tag;
  1356. + cbw.bCBWLUN = 1;
  1357. + cbw.bCBWCBLength = U3_CBWCB_LEN;
  1358. + memcpy(&(cbw.CBWCB), cmd, U3_CBWCB_LEN);
  1359. // send command
  1360. - if (usb_bulk_write(handle_wrapper->handle, handle_wrapper->ep_out,
  1361. - (char *) &cbw, sizeof(cbw), U3_DEVICE_TIMEOUT)
  1362. + if ((res = usb_bulk_write(handle_wrapper->handle, handle_wrapper->ep_out,
  1363. + (char *) &cbw, sizeof(cbw), U3_DEVICE_TIMEOUT))
  1364. != sizeof(cbw))
  1365. {
  1366. u3_set_error(device, "Failed executing scsi command: "
  1367. @@ -321,10 +346,10 @@
  1368. if (plen > USB_MAX_PACKET_LEN)
  1369. plen = USB_MAX_PACKET_LEN;
  1370. - if (usb_bulk_write(handle_wrapper->handle,
  1371. + if ((res = usb_bulk_write(handle_wrapper->handle,
  1372. handle_wrapper->ep_out,
  1373. (char *) dxfer_data+bytes_send, plen,
  1374. - U3_DEVICE_TIMEOUT) != plen)
  1375. + U3_DEVICE_TIMEOUT)) < 0)
  1376. {
  1377. u3_set_error(device, "Failed executing scsi command: "
  1378. "Could not write data to device");
  1379. @@ -334,9 +359,9 @@
  1380. bytes_send += plen;
  1381. }
  1382. } else if (dxfer_direction == CBW_DATA_IN) {
  1383. - if (usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
  1384. + if ((res = usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
  1385. (char *) dxfer_data, dxfer_length,
  1386. - U3_DEVICE_TIMEOUT) != dxfer_length)
  1387. + U3_DEVICE_TIMEOUT)) < 0)
  1388. {
  1389. u3_set_error(device, "Failed executing scsi command: "
  1390. "Could not read data from device");
  1391. @@ -344,16 +369,20 @@
  1392. }
  1393. }
  1394. + memset(&csw, 0, sizeof(csw));
  1395. +
  1396. // read command status
  1397. - if (usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
  1398. - (char *) &csw, sizeof(csw), U3_DEVICE_TIMEOUT)
  1399. - != sizeof(csw))
  1400. + if ((res = usb_bulk_read(handle_wrapper->handle, handle_wrapper->ep_in,
  1401. + (char *) &csw, sizeof(csw), U3_DEVICE_TIMEOUT))
  1402. + < 0)
  1403. {
  1404. u3_set_error(device, "Failed executing scsi command: "
  1405. "Could not read command status from device");
  1406. return U3_FAILURE;
  1407. }
  1408. + assert(tag == csw.dCSWTag);
  1409. + tag++;
  1410. *status = csw.bCSWStatus;
  1411. return U3_SUCCESS;