RIPCD.PAS
上传用户:hstrip
上传日期:2007-01-06
资源大小:51k
文件大小:8k
源码类别:

SCSI/ASPI

开发平台:

Pascal

  1. {$A+,B-,D+,E+,F+,G+,I+,L+,N+,O+,P+,Q+,R+,S+,T-,V+,X+,Y+}
  2. {$M 16384,0,16384}
  3. Program RipCD;
  4. Uses
  5. Crt,Dos;
  6. Const
  7. DriveNo : Word = 4;
  8. Var
  9. _AX, _Flags : Word;
  10. Const
  11. DriverOk : Byte = 255;
  12. CDOk : Byte = 255;
  13. CDDrives : Byte = 0;
  14. Function cdExist : Boolean; Assembler;
  15. Asm
  16. CMP [CDOk],-1
  17. JE @@DOCHECK
  18. MOV AL,[CDOk]
  19. JMP @@EXIT
  20. @@DOCHECK:
  21. MOV AX,$1500
  22. XOR BX,BX
  23. XOR CX,CX
  24. INT $2F
  25. TEST BX,BX
  26. JNZ @@OK
  27. MOV AL,FALSE
  28. JMP @@EXIT
  29. @@OK:
  30. MOV AL,TRUE
  31. MOV [CDDrives],BL
  32. @@EXIT:
  33. MOV [CDOk],AL
  34. End;
  35. Function cdDriveCount : Byte; Assembler;
  36. Asm
  37. CALL cdExist
  38. OR AL,AL
  39. JZ @@NO_CD
  40. MOV AL,[CDDrives]
  41. JMP @@EXIT
  42. @@NO_CD:
  43. XOR AX,AX
  44. @@EXIT:
  45. End;
  46. Function driverExist : Boolean; Assembler;
  47. Asm
  48. CMP [DriverOk],-1
  49. JE @@DOCHECK
  50. MOV AL,[DriverOk]
  51. JMP @@EXIT
  52. @@DOCHECK:
  53. MOV AX,$1100
  54. PUSH $DADA
  55. INT $2F
  56. POP BX
  57. CMP AL,$FF
  58. JE @@OK
  59. @@NOT_OK:
  60. MOV AL,FALSE
  61. JMP @@EXIT
  62. @@OK:
  63. CMP BX,$ADAD
  64. JNE @@NOT_OK
  65. MOV AL,TRUE
  66. @@EXIT:
  67. MOV [DriverOK],AL
  68. End;
  69. Procedure Request(Prompt: String; rCommand,rParam: Byte; rDataLength: Byte; Var rData);
  70. Var
  71. DeviceRequest : Record
  72. Len : Byte;
  73. UnitNo : Byte;
  74. Command : Byte;
  75. Status : Word;
  76. Reserved : Array[1..8] Of Byte;
  77. TheData : Array[0..31] Of Byte;
  78. End;
  79. Data : Array[0..31] Of Byte;
  80. P : PChar;
  81. W : Word;
  82. Procedure SendRequest(Var R);
  83. Begin
  84. Asm
  85. MOV AX,$1510
  86. MOV CX,[DriveNo]
  87. LES BX,[DWORD PTR R]
  88. INT $2F
  89. End;
  90. End;
  91. Begin
  92. If Prompt<>'' Then
  93. Write('Reading: ',Prompt);
  94. With DeviceRequest Do Begin
  95. Len:=13;
  96. UnitNo:=0;
  97. Command:=3;
  98. TheData[0]:=0;
  99. P:=@Data;
  100. Move(P,TheData[1],4);
  101. W:=rDataLength+1;
  102. Move(W,TheData[5],2);
  103. TheData[7]:=0;
  104. TheData[8]:=0;
  105. TheData[9]:=0;
  106. TheData[10]:=0;
  107. TheData[11]:=0;
  108. TheData[12]:=0;
  109. End;
  110. Data[0]:=rCommand;
  111. Data[1]:=rParam;
  112. SendRequest(DeviceRequest);
  113. Move(Data[1],rData,rDataLength);
  114. If Prompt<>'' Then
  115. WriteLn;
  116. End;
  117. Function ReadVTOC(Var VTOC; Index : Word) : Word; Assembler;
  118. Asm
  119. MOV AX,$1505
  120. LES BX,[DWORD PTR VTOC]
  121. MOV CX,[DriveNo]
  122. MOV DX,[Index]
  123. INT $2F
  124. PUSHF
  125. POP [_Flags]
  126. MOV [_AX],AX
  127. JC @@ERR
  128. MOV [DosError],0
  129. JMP @@EXIT
  130. @@ERR:
  131. MOV [DosError],AX
  132. XOR AX,AX
  133. @@EXIT:
  134. End;
  135. Function cdDrive(Index : Byte) : Char; Assembler;
  136. Var
  137. Letters : Array[1..26] Of Char;
  138. Asm
  139. CMP [Index],0
  140. JE @@NO_DRIVE
  141. CALL cdDriveCount
  142. CMP AL,[Index]
  143. JB @@NO_DRIVE
  144. MOV AX,$150D
  145. MOV BX,SS
  146. MOV ES,BX
  147. LEA BX,[Letters]
  148. INT $2F
  149. MOV BL,[Index]
  150. XOR BH,BH
  151. MOV SI,BX
  152. MOV AL,[BYTE PTR Letters+SI-1]
  153. ADD AL,'A'
  154. JMP @@EXIT
  155. @@NO_DRIVE:
  156. MOV AL,0
  157. @@EXIT:
  158. End;
  159. Function cdDriveExist(Drive : Char) : Boolean; Assembler;
  160. Asm
  161. CALL driverExist
  162. OR AL,AL
  163. JZ @@NO_DRIVER
  164. MOV CL,[Drive]
  165. XOR CH,CH
  166. AND CL,$DF
  167. CMP CL,'A'
  168. JB @@NO_DRIVER
  169. CMP CL,'Z'
  170. JA @@NO_DRIVER
  171. SUB CL,'A'
  172. MOV AX,$150B
  173. XOR BX,BX
  174. INT $2F
  175. CMP BX,$ADAD
  176. JNE @@NO_DRIVER
  177. TEST AX,AX
  178. JZ @@NO_DRIVER
  179. MOV AL,TRUE
  180. JMP @@EXIT
  181. @@NO_DRIVER:
  182. MOV AL,FALSE
  183. @@EXIT:
  184. End;
  185. Function GetFileName(Func: Byte; Var Name) : Boolean; Assembler;
  186. Asm
  187. MOV AH,$15
  188. MOV AL,[Func]
  189. LES BX,[DWORD PTR Name]
  190. MOV CX,[DriveNo]
  191. INT $2F
  192. End;
  193. Procedure ReadSector(Index : LongInt; Var Sector); Assembler;
  194. Asm
  195. mov ax,$1508
  196. les bx,[dword ptr Sector]
  197. mov cx,[DriveNo]
  198. mov dx,$0001
  199. mov di,[word ptr Index]
  200. mov si,[word ptr Index+2]
  201. int $2f
  202. End;
  203. Procedure GetDiskFree(Var _ax,_bx,_cx,_dx : Word); Assembler;
  204. Asm
  205. mov ah,$36
  206. mov   dx,[DriveNo]
  207. inc dx
  208. int $21
  209. les di,[dword ptr _ax]
  210. mov [es:di],ax
  211. les di,[dword ptr _bx]
  212. mov [es:di],bx
  213. les di,[dword ptr _cx]
  214. mov [es:di],cx
  215. les di,[dword ptr _dx]
  216. mov [es:di],dx
  217. End;
  218. Procedure GetVolumeLabel(Var VL);
  219. Var
  220. SR : SearchRec;
  221. Begin
  222. Write('Reading: Volume label');
  223. FillChar(VL,13,#0);
  224. FindFirst(Chr(65+DriveNo)+':*.*',VolumeID,SR);
  225. While DosError=0 Do Begin
  226. If (SR.Attr And VolumeID)<>0 Then Begin
  227. If Pos('.',SR.Name)>0 Then
  228. Delete(SR.name,Pos('.',SR.Name),1);
  229. Move(SR.Name[1],VL,Length(SR.Name));
  230. Break;
  231. End;
  232. FindNext(SR);
  233. End;
  234. WriteLn;
  235. End;
  236. Var
  237. Data : Array[1..16] Of Byte;
  238. F,F2 : File;
  239. I : Word;
  240. TrackLo : Byte;
  241. TrackHi : Byte;
  242. VTOC : Array[0..16383] Of Byte;
  243. Index : Word;
  244. Dir : DirStr;
  245. Name : NameStr;
  246. Ext : ExtStr;
  247. Size : Word;
  248. InBuffer : Word;
  249. S : String;
  250. C : Char;
  251. _bx,_cx,_dx : Word;
  252. Begin
  253. If Not driverExist Then Begin
  254. WriteLn('MSCDEX not loaded');
  255. Halt(1);
  256. End;
  257. If ParamStr(1)='/?' Then Begin
  258. WriteLn('Usage: RIPCD filename d:');
  259. Halt(1);
  260. End;
  261. If cdDriveCount=1 Then Begin
  262. If (ParamCount<1) Or (ParamCount>2) Then Begin
  263. WriteLn('Invalid number of parameters; RIPCD /? for help');
  264. Halt(1);
  265. End;
  266. DriveNo:=Ord(cdDrive(1))-Ord('A');
  267. End Else Begin
  268. If ParamCount<>2 Then Begin
  269. WriteLn('Invalid number of parameters; RIPCD /? for help');
  270. Halt(1);
  271. End;
  272. S:=ParamStr(2);
  273. If (Length(S)=2) And (S[2]=':') And (UpCase(S[1]) In ['A'..'Z']) Then Begin
  274. C:=UpCase(S[1]);
  275. If Not cdDriveExist(C) Then Begin
  276. WriteLn('Drive ',C,': is not a cd-rom');
  277. Halt(1);
  278. End;
  279. DriveNo:=Ord(C)-Ord('A');
  280. End Else Begin
  281. WriteLn('Invalid parameters; RIPCD /? for help');
  282. Halt(1);
  283. End;
  284. End;
  285. FSplit(ParamStr(0),Dir,Name,Ext);
  286. Assign(F,ParamStr(1));
  287. ReWrite(F,1);
  288. I:=0;
  289. BlockWrite(F,I,2); { Offset of VTOC }
  290. BlockWrite(F,I,2); { Offset of Sectors }
  291. Request('Sector size',7,0,3,Data);
  292. BlockWrite(F,Data,3);
  293. Request('Volume size',8,0,4,Data);
  294. BlockWrite(F,Data,4);
  295. Request('Audio disk info',10,0,6,Data);
  296. BlockWrite(F,Data,6);
  297. TrackLo:=Data[1];
  298. TrackHi:=Data[2];
  299. Request('UPC code',14,0,10,Data);
  300. BlockWrite(F,Data,10);
  301. Write('Reading: Filenames');
  302. GetFileName(2,VTOC);
  303. BlockWrite(F,VTOC,38);
  304. GetFileName(3,VTOC);
  305. BlockWrite(F,VTOC,38);
  306. GetFileName(4,VTOC);
  307. BlockWrite(F,VTOC,38);
  308. WriteLn;
  309. GetVolumeLabel(VTOC);
  310. BlockWrite(F,VTOC,12);
  311. Write('Reading: Disk free data');
  312. GetDiskFree(_ax,_bx,_cx,_dx);
  313. BlockWrite(F,_ax,2);
  314. BlockWrite(F,_bx,2);
  315. BlockWrite(F,_cx,2);
  316. BlockWrite(F,_dx,2);
  317. WriteLn;
  318. BlockWrite(F,TrackLo,1);
  319. BlockWrite(F,TrackHi,1);
  320. Write('Reading: Audio track info, tracks ',TrackLo,'-',TrackHi);
  321. For I:=TrackLo To TrackHi Do Begin
  322. WriteLn(I);
  323. Request('',11,I,6,Data);
  324. BlockWrite(F,Data[2],5);
  325. End;
  326. WriteLn;
  327. I:=FileSize(F);
  328. Seek(F,0);
  329. BlockWrite(F,I,2);
  330. Seek(F,I);
  331. ReadVTOC(VTOC,0);
  332. Index:=0;
  333. Repeat
  334. Write('Reading: Sector ',Index);
  335. Write(', reading');
  336. ReadVTOC(VTOC,Index);
  337. If DosError<>0 Then Begin
  338. WriteLn(', end of table');
  339. Break;
  340. End;
  341. Write(', compressing');
  342. Assign(F2,'VTOC.TMP');
  343. ReWrite(F2,1);
  344. BlockWrite(F2,VTOC,2048);
  345. Close(F2);
  346. SwapVectors;
  347. If GetEnv('COMSPEC')='' Then
  348. Exec('C:COMMAND.COM','/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL')
  349. Else
  350. Exec(GetEnv('COMSPEC'),'/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL');
  351. SwapVectors;
  352. Assign(F2,'VTOC.TMP');
  353. Erase(F2);
  354. Assign(F2,'VTOC_C.TMP');
  355. ReSet(F2,1);
  356. BlockWrite(F,Index,2);
  357. Size:=FileSize(F2)+6;
  358. BlockWrite(F,Size,2);
  359. BlockWrite(F,_AX,2);
  360. BlockWrite(F,_Flags,2);
  361. BlockRead(F2,VTOC,16384,InBuffer);
  362. BlockWrite(F,VTOC,InBuffer);
  363. Close(F2);
  364. Erase(F2);
  365. WriteLn;
  366. Inc(Index);
  367. Until FALSE;
  368. ReadVTOC(VTOC,$FFFF);
  369. Index:=$FFFF;
  370. BlockWrite(F,Index,2);
  371. BlockWrite(F,Size,2);
  372. BlockWrite(F,_AX,2);
  373. _Flags:=_Flags Or 1;
  374. BlockWrite(F,_Flags,2);
  375. I:=FileSize(F);
  376. Seek(F,2);
  377. BlockWrite(F,I,2);
  378. Seek(F,I);
  379. Write('Reading: System sector 16');
  380. ReadSector(16,VTOC);
  381. Assign(F2,'VTOC.TMP');
  382. ReWrite(F2,1);
  383. BlockWrite(F2,VTOC,2048);
  384. Close(F2);
  385. SwapVectors;
  386. Exec(GetEnv('COMSPEC'),'/C '+Dir+'CRUNCH.COM VTOC.TMP VTOC_C.TMP >NUL');
  387. SwapVectors;
  388. Assign(F2,'VTOC.TMP');
  389. Erase(F2);
  390. Assign(F2,'VTOC_C.TMP');
  391. ReSet(F2,1);
  392. Size:=FileSize(F2)+6;
  393. BlockRead(F2,VTOC,16384,InBuffer);
  394. BlockWrite(F,VTOC,InBuffer);
  395. Close(F2);
  396. Erase(F2);
  397. WriteLn;
  398. Close(F);
  399. End.
  400. { return 33032 for invalid tracks }