;*******************************************; ; ; FFDiscInfo - useful to get info about a disc inserted into ; a CD-R or CD-RW writer device. ; It sends the target a READ DISC INFORMATION SCSI3 ; command, retrieves the Disc Information Block, and ; makes it readable to humans. ; ; This function takes the following parameters: ; ; - (HWND) the handle to the main window of the calling program ; - (int) the Host Adapter card number: usually 0 unless you have ; more than one host adapter card inserted into the bus of the PC ; - (int) the SCSI Id of the target ; - (int) the SCSI LUN of the target ; ;*******************************************; FFDiscInfo PROC PARM_1:DWORD, PARM_2:DWORD, PARM_3:DWORD, PARM_4:DWORD ;===========================================; PUSH ESI ; PUSH EDI ; PUSH EBP ; PUSH EBX ; ;===========================================; PUSH PARM_1 ; POP cdhWnd ; PUSH PARM_2 ; POP cdAdapId ; PUSH PARM_3 ; POP cdSCSIid ; PUSH PARM_4 ; POP cdSCSIlun ; ;===========================================;TEST UNIT READY COMMAND INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,6 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte MOV AL,SCSI_TST_U_RDY MOV [EDI],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFCF1_1 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFCF1_1: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFC_CHECK_SENSE ;===========================================;READ DISC INFORMATION INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_IN ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,34 LEA EAX,DiscInfoBlock MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte MOV AL,51H ;READ DISC INFORMATION MOV [EDI],AL MOV AL,34 MOV [EDI + 8],AL FFCF2_1: MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFCF2_2 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFCF2_2: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFC_CHECK_SENSE ;===========================================;34 bytes interpreter ; erasable LEA ESI,DiscInfoBlock MOV AL,[ESI+2] AND AL,00010000b CMP AL,0 JNZ FFC_LAB_0_A LEA ESI,_no LEA EDI,_erasable MOV ECX,3 CALL ESI2EDI JMP FFC_LAB_1 FFC_LAB_0_A: LEA ESI,_yes LEA EDI,_erasable MOV ECX,3 CALL ESI2EDI ; state of last session FFC_LAB_1: LEA ESI,DiscInfoBlock MOV EAX,0 MOV AL,[ESI+2] AND AL,00001100b SHR EAX,2 CMP AL,0 JNZ FFC_LAB_1_A LEA ESI,_empty_session LEA EDI,_session_state MOV ECX,18 CALL ESI2EDI JMP FFC_LAB_2 FFC_LAB_1_A: CMP AL,1 JNZ FFC_LAB_1_B LEA ESI,_incomplete_sess LEA EDI,_session_state MOV ECX,18 CALL ESI2EDI JMP FFC_LAB_2 FFC_LAB_1_B: CMP AL,2 JNZ FFC_LAB_1_C LEA ESI,_reserved LEA EDI,_session_state MOV ECX,18 CALL ESI2EDI JMP FFC_LAB_2 FFC_LAB_1_C: CMP AL,3 JNZ FFC_LAB_2 LEA ESI,_complete_session LEA EDI,_session_state MOV ECX,18 CALL ESI2EDI ; disc status FFC_LAB_2: LEA ESI,DiscInfoBlock MOV AL,[ESI+2] AND AL,00000011b CMP AL,0 JNZ FFC_LAB_2_A LEA ESI,_empty LEA EDI,_disc_status MOV ECX,30 CALL ESI2EDI JZ FFC_LAB_3 FFC_LAB_2_A: CMP AL,1 JNZ FFC_LAB_2_B LEA ESI,_incomplete LEA EDI,_disc_status MOV ECX,30 CALL ESI2EDI JZ FFC_LAB_3 FFC_LAB_2_B: CMP AL,2 JNZ FFC_LAB_2_C LEA ESI,_complete LEA EDI,_disc_status MOV ECX,30 CALL ESI2EDI JZ FFC_LAB_3 FFC_LAB_2_C: CMP AL,3 JNZ FFC_LAB_3 LEA ESI,_reserved LEA EDI,_disc_status MOV ECX,30 CALL ESI2EDI ; num of 1 track FFC_LAB_3: LEA ESI,DiscInfoBlock MOV AL,[ESI+3] CALL BYTE2HEX LEA EDI,_num_of_1_track MOV [EDI],BH MOV [EDI+1],BL ; num of sessions FFC_LAB_4: LEA ESI,DiscInfoBlock MOV AL,[ESI+4] CALL BYTE2HEX LEA EDI,_num_of_sessions MOV [EDI],BH MOV [EDI+1],BL ; first track FFC_LAB_5: LEA ESI,DiscInfoBlock MOV AL,[ESI+5] CALL BYTE2HEX LEA EDI,_first_track MOV [EDI],BH MOV [EDI+1],BL ; last track FFC_LAB_6: LEA ESI,DiscInfoBlock MOV AL,[ESI+6] CALL BYTE2HEX LEA EDI,_last_track MOV [EDI],BH MOV [EDI+1],BL ; did valid FFC_LAB_7: LEA ESI,DiscInfoBlock MOV AL,[ESI+7] AND AL,10000000b CMP AL,0 JNZ FFC_LAB_7_A LEA ESI,_no LEA EDI,_did_v MOV ECX,3 CALL ESI2EDI JMP FFC_LAB_8 FFC_LAB_7_A: LEA ESI,_yes LEA EDI,_did_v MOV ECX,3 CALL ESI2EDI ; dbc valid FFC_LAB_8: LEA ESI,DiscInfoBlock MOV AL,[ESI+7] AND AL,01000000b CMP AL,0 JNZ FFC_LAB_8_A LEA ESI,_no LEA EDI,_dbc_v MOV ECX,3 CALL ESI2EDI JMP FFC_LAB_9 FFC_LAB_8_A: LEA ESI,_yes LEA EDI,_dbc_v MOV ECX,3 CALL ESI2EDI ; uru FFC_LAB_9: LEA ESI,DiscInfoBlock MOV AL,[ESI+7] AND AL,00100000b CMP AL,0 JNZ FFC_LAB_9_A LEA ESI,_no LEA EDI,_uru MOV ECX,3 CALL ESI2EDI JMP FFC_LAB_10 FFC_LAB_9_A: LEA ESI,_yes LEA EDI,_uru MOV ECX,3 CALL ESI2EDI ; disk type FFC_LAB_10: LEA ESI,DiscInfoBlock MOV AL,[ESI+8] CMP AL,0 JNZ FFC_LAB_10_A LEA ESI,_cd_da LEA EDI,_disc_type MOV ECX,20 CALL ESI2EDI JMP FFC_LAB_11 FFC_LAB_10_A: CMP AL,10h JNZ FFC_LAB_10_B LEA ESI,_cd_i LEA EDI,_disc_type MOV ECX,20 CALL ESI2EDI JMP FFC_LAB_11 FFC_LAB_10_B: CMP AL,20h JNZ FFC_LAB_10_C LEA ESI,_cd_xa LEA EDI,_disc_type MOV ECX,20 CALL ESI2EDI JMP FFC_LAB_11 FFC_LAB_10_C: CMP AL,0FFh JNZ FFC_LAB_11 LEA ESI,_undefined LEA EDI,_disc_type MOV ECX,20 CALL ESI2EDI ; disk identification FFC_LAB_11: LEA ESI,DiscInfoBlock MOV AL,[ESI+12] CALL BYTE2HEX LEA EDI,_did MOV [EDI],BH MOV [EDI+1],BL MOV AL,[ESI+13] CALL BYTE2HEX MOV [EDI+2],BH MOV [EDI+3],BL MOV AL,[ESI+14] CALL BYTE2HEX MOV [EDI+4],BH MOV [EDI+5],BL MOV AL,[ESI+15] CALL BYTE2HEX MOV [EDI+6],BH MOV [EDI+7],BL ; last 1 FFC_LAB_12: LEA ESI,DiscInfoBlock MOV AL,[ESI+16] CALL BYTE2HEX LEA EDI,_last_1 MOV [EDI],BH MOV [EDI+1],BL MOV AL,[ESI+17] CALL BYTE2HEX MOV [EDI+2],BH MOV [EDI+3],BL MOV AL,[ESI+18] CALL BYTE2HEX MOV [EDI+4],BH MOV [EDI+5],BL MOV AL,[ESI+19] CALL BYTE2HEX MOV [EDI+6],BH MOV [EDI+7],BL ; last 2 FFC_LAB_13: LEA ESI,DiscInfoBlock MOV AL,[ESI+20] CALL BYTE2HEX LEA EDI,_last_2 MOV [EDI],BH MOV [EDI+1],BL MOV AL,[ESI+21] CALL BYTE2HEX MOV [EDI+2],BH MOV [EDI+3],BL MOV AL,[ESI+22] CALL BYTE2HEX MOV [EDI+4],BH MOV [EDI+5],BL MOV AL,[ESI+23] CALL BYTE2HEX MOV [EDI+6],BH MOV [EDI+7],BL ; bar code FFC_LAB_14: LEA ESI,DiscInfoBlock MOV AL,[ESI+24] CALL BYTE2HEX LEA EDI,_dbc MOV [EDI],BH MOV [EDI+1],BL MOV AL,[ESI+25] CALL BYTE2HEX MOV [EDI+2],BH MOV [EDI+3],BL MOV AL,[ESI+26] CALL BYTE2HEX MOV [EDI+4],BH MOV [EDI+5],BL MOV AL,[ESI+27] CALL BYTE2HEX MOV [EDI+6],BH MOV [EDI+7],BL MOV AL,[ESI+28] CALL BYTE2HEX MOV [EDI+8],BH MOV [EDI+9],BL MOV AL,[ESI+29] CALL BYTE2HEX MOV [EDI+10],BH MOV [EDI+11],BL MOV AL,[ESI+30] CALL BYTE2HEX MOV [EDI+12],BH MOV [EDI+13],BL MOV AL,[ESI+31] CALL BYTE2HEX MOV [EDI+14],BH MOV [EDI+15],BL JMP FFC_OK ;===========================================;read CHECK SENSE data FFC_CHECK_SENSE: LEA EDI,szMsgSense ;prepare the message LEA ESI,SRB_EXEC.CDBByte MOV AL,[ESI] CALL BYTE2HEX MOV [EDI + 14],BH MOV [EDI + 15],BL MOV AL,SRB_EXEC.SRB_Status CALL BYTE2DEC MOV [EDI + 32],AH MOV [EDI + 33],BH MOV [EDI + 34],BL MOV AL,SRB_EXEC.SRB_HaStat CALL BYTE2DEC MOV [EDI + 49],AH MOV [EDI + 50],BH MOV [EDI + 51],BL MOV AL,SRB_EXEC.SRB_TargStat CALL BYTE2DEC MOV [EDI + 70],AH MOV [EDI + 71],BH MOV [EDI + 72],BL LEA ESI,SRB_EXEC.SenseArea MOV AL,[ESI + 2] AND AL,0FH ;sense key CALL BYTE2HEX MOV [EDI + 87],BH MOV [EDI + 88],BL MOV AL,[ESI + 12] ;ASC CALL BYTE2HEX MOV [EDI + 98],BH MOV [EDI + 99],BL MOV AL,[ESI + 13] ;ASCQ CALL BYTE2HEX MOV [EDI + 110],BH MOV [EDI + 111],BL INVOKE MessageBoxA, cdhWnd, OFFSET szMsgSense, OFFSET szCaptionSense, MB_OK ;===========================================; FFC_OK: LEA EAX,DiscInfoMsg POP EBX ; POP EBP ; POP EDI ; POP ESI ; RET ; FFDiscInfo ENDP ; ;*******************************************; ;*******************************************; ; ESI2EDI - utility called by FFDiscInfo ;-------------------------------------------; ESI2EDI PROC E2E: MOV AL,[ESI] INC ESI MOV [EDI],AL INC EDI LOOP E2E RET ESI2EDI ENDP ;*******************************************; ;*******************************************; ;*******************************************; ; ; FFCDWrite - function to burn a file into a MODE-1 track in a blank ; CD-R disc and to close the disc. ; The track is burned in track at once style of writing; if ; the file were a ISO 9660 image you get a perfect CD-ROM of ; user data. ; ; Essentially this function does the following: ; ; - check the target device for readyness ; - read the Disc Information Block for the media inserted into the ; target device ; - exit if the CD-R disc is not empty ; - read the Track Information Block for track #1 in the disc ; - send the Write Parameters Mode Page by means of a MODE SELECT command ; - read 8 kB from the input file and burn 4 blocks into the CD-R disc ; - the previous step is repeated until the end of the input file is reached (see the note (*) below) ; - synchronize the cache to flush residual data from the buffer to the ; disc ; - close the track ; ; The function should be passed the following parameters: ; ; - (HWND) the handle to the main window of the calling program ; - (int) the Host Adapter card number (usually 0 unless you have more ; than one host adapter card inserted into the bus of the PC ; - (int) the SCSI Id of the target ; - (int) the SCSI LUN of the target ; - (HANDLE) the handle of the file to be burned (the calling program is ; responsible for opening and closing the file ; ;*******************************************; FFCDWrite PROC PARM_1:DWORD, PARM_2:DWORD, PARM_3:DWORD, PARM_4:DWORD, PARM_5:DWORD ;===========================================; PUSH ESI ; PUSH EDI ; PUSH EBP ; PUSH EBX ; ;===========================================; PUSH PARM_1 ; POP cdhWnd ; PUSH PARM_2 ; POP cdAdapId ; PUSH PARM_3 ; POP cdSCSIid ; PUSH PARM_4 ; POP cdSCSIlun ; PUSH PARM_5 ; POP cdFileHandle ; ;===========================================;TEST UNIT READY INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,6 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,SCSI_TST_U_RDY MOV [EDI],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF1_1 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF1_1: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;READ DISC INFORMATION INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_IN ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,34 LEA EAX,DiscInfoBlock MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,51H ;READ DISC INFORMATION MOV [EDI],AL MOV AL,34 ;length of the allocated buffer MOV [EDI + 8],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF2_2 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF2_2: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;IS DISC EMPTY ? ; disc status LEA ESI,DiscInfoBlock MOV AL,[ESI+2] AND AL,00000011b CMP AL,0 JZ FFD_K1 MOV EAX,2 ;2 = disc not empty JMP FFD_END ;===========================================;READ TRACK INFORMATION FFD_K1: INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_IN ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,28 LEA EAX,TrackInfoBlock MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,52H ;READ TRACK INFORMATION MOV [EDI],AL MOV AL,1 ;track bit = 1 MOV [EDI + 1],AL MOV AL,1 ;track number = 1 MOV [EDI + 5],AL MOV AL,28 ;length of the allocated buffer MOV [EDI + 8],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF2_3 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF2_3: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;SEND WRITE PARAMETERS PAGE INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_OUT ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,64 LEA EAX,ModeSelect1 MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,6 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,15H ;MODE SELECT MOV [EDI],AL MOV AL,64 ;length of the allocated buffer MOV [EDI + 4],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF2_Z INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF2_Z: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;CHECK FILE LENGTH INVOKE SetFilePointer, cdFileHandle, 0, 0, FILE_END MOV TotalBytes,EAX INVOKE SetFilePointer, cdFileHandle, 0, 0, FILE_BEGIN ;===========================================;WRITING MOV LBA,0 ;bug fix !!! (nov. 4th, 2002) NEXT_READ: INVOKE ReadFile, cdFileHandle, OFFSET LINE_0, 8192, OFFSET cdBytesRead, 0 ;...........................................; INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_OUT ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,8192 LEA EAX,LINE_0 MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,2AH ;WRITE 10 MOV [EDI],AL MOV EAX,LBA MOV [EDI + 5],AL SHR EAX,8 MOV [EDI + 4],AL SHR EAX,8 MOV [EDI + 3],AL SHR EAX,8 MOV [EDI + 2],AL MOV AL,4 ;num of blocks to write MOV [EDI + 8],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF2_6 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF2_6: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;...........................................; ADD LBA,4 MOV EAX,cdBytesRead SUB TotalBytes,EAX CMP TotalBytes,0 JA NEXT_READ ;===========================================;SYNCHRONIZE CACHE INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,35H ;SYNCHRONIZE CACHE MOV [EDI],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF1_7 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF1_7: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;CLOSE TRACK/SESSION INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,5BH ;CLOSE TRACK/SESSION MOV [EDI],AL MOV AL,2 ;see table 68-plextor MOV [EDI+2],AL MOV AL,0 ;track number MOV [EDI+5],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFDF1_8 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFDF1_8: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFD_CHECK_SENSE ;===========================================;NO ERROR JMP FFD_OK ;===========================================;read CHECK SENSE data FFD_CHECK_SENSE: LEA EDI,szMsgSense ;prepare the message LEA ESI,SRB_EXEC.CDBByte MOV AL,[ESI] CALL BYTE2HEX MOV [EDI + 14],BH MOV [EDI + 15],BL MOV AL,SRB_EXEC.SRB_Status CALL BYTE2DEC MOV [EDI + 32],AH MOV [EDI + 33],BH MOV [EDI + 34],BL MOV AL,SRB_EXEC.SRB_HaStat CALL BYTE2DEC MOV [EDI + 49],AH MOV [EDI + 50],BH MOV [EDI + 51],BL MOV AL,SRB_EXEC.SRB_TargStat CALL BYTE2DEC MOV [EDI + 70],AH MOV [EDI + 71],BH MOV [EDI + 72],BL LEA ESI,SRB_EXEC.SenseArea MOV AL,[ESI + 2] AND AL,0FH ;sense key CALL BYTE2HEX MOV [EDI + 87],BH MOV [EDI + 88],BL MOV AL,[ESI + 12] ;ASC CALL BYTE2HEX MOV [EDI + 98],BH MOV [EDI + 99],BL MOV AL,[ESI + 13] ;ASCQ CALL BYTE2HEX MOV [EDI + 110],BH MOV [EDI + 111],BL INVOKE MessageBoxA, cdhWnd, OFFSET szMsgSense, OFFSET szCaptionSense, MB_OK MOV EAX,99 ;99 = check sense JMP FFD_END ;===========================================; FFD_OK: MOV EAX,0 FFD_END: POP EBX ; POP EBP ; POP EDI ; POP ESI ; RET ; FFCDWrite ENDP ; ;*******************************************; ;*******************************************; ;*******************************************; ; ; FFCDReadSect - this function reads a block (a sector) in a disc ; inserted into a CD-R or CD-RW writer device; it ; sends the target a READ 10 SCSI3 command, gets the ; block, and returns 2048 bytes of data ; ; The function takes the following parameters: ; ; - (HWND) the handle to the main window of the calling program ; - (int) the Host Adapter card number (usually 0 unless you have more ; than one host adapter card inserted into the bus of the PC) ; - (int) the SCSI Id of the target ; - (int) the SCSI LUN of the target ; - (int) number of the sector to read: LBA address of the block ; - (char*) pointer to the buffer that will receive the data ; ;*******************************************; FFCDReadSect PROC PARM_1:DWORD, PARM_2:DWORD, PARM_3:DWORD, PARM_4:DWORD, PARM_5:DWORD, PARM_6:DWORD ;===========================================; PUSH ESI ; PUSH EDI ; PUSH EBP ; PUSH EBX ; ;===========================================; PUSH PARM_1 ; POP cdhWnd ; PUSH PARM_2 ; POP cdAdapId ; PUSH PARM_3 ; POP cdSCSIid ; PUSH PARM_4 ; POP cdSCSIlun ; PUSH PARM_5 ; POP cdSectNum ; PUSH PARM_6 ; POP cdPtrBuf ; ;===========================================;TEST UNIT READY INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,6 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,SCSI_TST_U_RDY MOV [EDI],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFUF1_1 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFUF1_1: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFU_CHECK_SENSE ;===========================================;READ SECT INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,cdAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_IN ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,cdSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,2048 MOV EAX,cdPtrBuf MOV SRB_EXEC.SRB_BufPointer,EAX MOV SRB_EXEC.SRB_SenseLen,SENSE_LEN MOV SRB_EXEC.SRB_CDBLen,10 MOV EAX,hEventSRB MOV SRB_EXEC.SRB_PostProc,EAX LEA EDI,SRB_EXEC.CDBByte NOP MOV AL,28H ;READ 10 MOV [EDI],AL MOV EAX,cdSectNum MOV [EDI + 5],AL SHR EAX,8 MOV [EDI + 4],AL SHR EAX,8 MOV [EDI + 3],AL SHR EAX,8 MOV [EDI + 2],AL MOV AL,1 ;num of blocks to read MOV [EDI + 8],AL MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFUF2_6 INVOKE WaitForSingleObject, hEventSRB, 10000 FFUF2_6: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFU_CHECK_SENSE ;===========================================;NO ERROR JMP FFU_OK ;===========================================;read CHECK SENSE data FFU_CHECK_SENSE: LEA EDI,szMsgSense ;prepare the message LEA ESI,SRB_EXEC.CDBByte MOV AL,[ESI] CALL BYTE2HEX MOV [EDI + 14],BH MOV [EDI + 15],BL MOV AL,SRB_EXEC.SRB_Status CALL BYTE2DEC MOV [EDI + 32],AH MOV [EDI + 33],BH MOV [EDI + 34],BL MOV AL,SRB_EXEC.SRB_HaStat CALL BYTE2DEC MOV [EDI + 49],AH MOV [EDI + 50],BH MOV [EDI + 51],BL MOV AL,SRB_EXEC.SRB_TargStat CALL BYTE2DEC MOV [EDI + 70],AH MOV [EDI + 71],BH MOV [EDI + 72],BL LEA ESI,SRB_EXEC.SenseArea MOV AL,[ESI + 2] AND AL,0FH ;sense key CALL BYTE2HEX MOV [EDI + 87],BH MOV [EDI + 88],BL MOV AL,[ESI + 12] ;ASC CALL BYTE2HEX MOV [EDI + 98],BH MOV [EDI + 99],BL MOV AL,[ESI + 13] ;ASCQ CALL BYTE2HEX MOV [EDI + 110],BH MOV [EDI + 111],BL INVOKE MessageBoxA, cdhWnd, OFFSET szMsgSense, OFFSET szCaptionSense, MB_OK MOV EAX,99 ;99 = check sense JMP FFU_END ;===========================================; FFU_OK: MOV EAX,0 FFU_END: POP EBX ; POP EBP ; POP EDI ; POP ESI ; RET ; FFCDReadSect ENDP ; ;*******************************************; ;*******************************************; ;*******************************************; ; THE FOLLOWING ARE UTILITIES ;*******************************************; ;*******************************************; BYTE2HEX PROC ;===========================================; ; Preparare un byte in AL. Il numero binario viene convertito in due ; caratteri ASCII (in BH e BL) che rappresentano il numero esadecimale. ;===========================================; PUSH EAX AND AL,0F0H SHR AL,4 CMP AL,0AH JB BY2H_6 CMP AL,0AH JNZ BY2H_1 MOV BH,"A" JMP BY2H_7 BY2H_1: CMP AL,0BH JNZ BY2H_2 MOV BH,"B" JMP BY2H_7 BY2H_2: CMP AL,0CH JNZ BY2H_3 MOV BH,"C" JMP BY2H_7 BY2H_3: CMP AL,0DH JNZ BY2H_4 MOV BH,"D" JMP BY2H_7 BY2H_4: CMP AL,0EH JNZ BY2H_5 MOV BH,"E" JMP BY2H_7 BY2H_5: MOV BH,"F" JMP BY2H_7 BY2H_6: MOV BH,AL ADD BH,30H BY2H_7: POP EAX AND AL,0FH CMP AL,0AH JB BY2H_13 CMP AL,0AH JNZ BY2H_8 MOV BL,"A" JMP BY2H_0 BY2H_8: CMP AL,0BH JNZ BY2H_9 MOV BL,"B" JMP BY2H_0 BY2H_9: CMP AL,0CH JNZ BY2H_10 MOV BL,"C" JMP BY2H_0 BY2H_10: CMP AL,0DH JNZ BY2H_11 MOV BL,"D" JMP BY2H_0 BY2H_11: CMP AL,0EH JNZ BY2H_12 MOV BL,"E" JMP BY2H_0 BY2H_12: MOV BL,"F" JMP BY2H_0 BY2H_13: MOV BL,AL ADD BL,30H ;===========================================; BY2H_0: RET BYTE2HEX ENDP ;*******************************************; BYTE2DEC PROC ;===========================================; ; Preparare un byte in AL. Il numero binario viene convertito in tre ; caratteri ASCII (in AH, BH e BL) che rappresentano il numero decimale. ;===========================================; MOV AH,0 MOV CL,10 DIV CL ADD AH,30H MOV BL,AH MOV AH,0 MOV CL,10 DIV CL ADD AH,30H MOV BH,AH ;===========================================; BY2D_0: RET BYTE2DEC ENDP ;*******************************************;