combined-r59.patch 40 KB

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