; FFScan is a scan function for any of the following scanners: ; - all scanners from Avision (I am going to check it) ; - Fujitsu SP10, Fujitsu SP300C, Fujitsu SP600C, Fujitsu SP620C (checked) ; - Bell+Howell 2000F (checked) ; FYI: Fujitsu and B+H models above are produced by Avision, all of them are ; perfectly equivalent. I recently discovered that scanners from Avision are ; by far the cheapest on the market. I regret I recently bought two Kodak i260 ; (excellent scanners, but too expensive compared to Avision). ; Raw scanned data, at one byte per pixel in b&w, will be accomodated ; into a system memory area. The amount of memory to allocate must ; be (scan width) by (scan length) bytes. Scan density: 200 dpi. ; ; PARAMETERS: ; ; 1: HWND of the calling program ; 2: system memory area pointer ; 3: scan width in pixels ; 4: scan length in lines ; 5: sheet feeder: 0=no ADF, 1=ADF ; 6: threeshold: 0 to 255 ; 7: host adapter id: 0 to 7 ; 8: scanner device SCSI ID: 0 to 7 ; 9: scanner device SCSI LUN: 0 to 7 ; ; This function does not return any value, but in case of failure it ; sends a messagebox indicating the following 6 values: ; ; a: ASPI status (decimal) \ ; b: host adapter status (decimal) |---> status code ; c: target status (decimal) / ; d: sense key (hex) \ ; e: additional sense code (hex) |---> sense code ; f: additional sense code qualifier (hex) / ; ; a) ASPI status meaning: ; 0001 = SCSI request completed without error ; 0002 = SCSI request aborted by host ; 0004 = SCSI request completed with error ; 0128 = invalid SCSI request ; 0129 = invalid HA number (host adapter not installed) ; 0130 = SCSI device not installed (scanner device not found ; at SCSI ID & LUN, or not "on" at PC's POST time) ; ; b) Host adapter status meaning: ; 0000 = host adapter did not detect any error ; 0017 = selection timeout ; 0018 = data overrun/underrun ; 0019 = unexpected bus free ; 0020 = target bus phase sequence failure ; ; c) Target status meaning: ; 0000 = non target status ; 0002 = check condition (sense data valid) ; 0008 = target/LUN busy ; 0024 = reservation conflict ; ; d) Sense key meaning: ; 00h = no sense ; 02h = not ready ; 03h = medium error ; 04h = hardware error ; 05h = illegal request ; 06h = unit attention ; 0Bh = aborted command ; Examples: Sense Key = 3 (medium error) might mean jam, ADF cover open, ; or empty ADF; Sense Key = 5 (illegal request) might mean: invalid ; command, invalid field in CDB, unsupported logical unit, invalid field ; in parameter list. The exact reason is given by the additional sense ; code and the additional sense code qualifier. ; ; e) additional sense code (ASC), see below ; ; f) additional sense code qualifier (ASCQ), see below ; ; Remember that d, e, and f (Sense data) are valid only if the target ; status is equal to 0002 (Check Condition). ; ; ASC and ASCQ depend on the scanner model and manufacturer. Check the ; specific SCSI2 command set manual of your scanner. ; ;*******************************************; FFScan PROC PARM_1:DWORD, PARM_2:DWORD, PARM_3:DWORD, PARM_4:DWORD, PARM_5:DWORD, PARM_6:DWORD, PARM_7:DWORD, PARM_8:DWORD, PARM_9:DWORD ;===========================================; PUSH ESI ; PUSH EDI ; PUSH EBP ; PUSH EBX ; ;===========================================; PUSH PARM_1 ; POP schWnd ; PUSH PARM_2 ; POP scMemoryArea ; PUSH PARM_3 ; POP scImageWidth ; PUSH PARM_4 ; POP scImageHeight ; PUSH PARM_5 ; POP scADF ; PUSH PARM_6 ; POP scLampLevel ; PUSH PARM_7 ; POP scAdapId ; PUSH PARM_8 ; POP scSCSIid ; PUSH PARM_9 ; POP scSCSIlun ; ;===========================================;TEST UNIT READY COMMAND INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,scAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,scSCSIid 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 FFSF1_1 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFSF1_1: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFS_CHECK_SENSE ;===========================================;OBJECT POSITION COMMAND INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,scAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,scSCSIid 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 MOV AL,SCSI_OBJECTPOS MOV [EDI],AL CMP scADF,0 JZ FFSF2_1 MOV AL,1 MOV [EDI + 1],AL FFSF2_1: MOV EAX,fnSendASPI32Command PUSH OFFSET SRB_EXEC CALL EAX ADD ESP,4 ;absolutely required CMP SRB_EXEC.SRB_Status,SS_PENDING JNZ FFSF2_2 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFSF2_2: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFS_CHECK_SENSE ;===========================================;SET WINDOW COMMAND INVOKE ResetEvent, hEventSRB ;-------------------------------------------;reset del buffer LEA EDI,SetWindowBuffer MOV ECX,72 MOV AL,0 FFSF3_1: MOV [EDI],AL INC EDI LOOP FFSF3_1 ;-------------------------------------------;preparing the buffer LEA EDI,SetWindowBuffer ;...........................................; MOV AL,64 MOV [EDI+7],AL ;64=window descr. block length ;...........................................; MOV AL,200 MOV [EDI+11],AL ;X-res MOV [EDI+13],AL ;Y-res ;...........................................; MOV EAX,scImageWidth MOV EBX,6 ;/200*1200 (v. reference) MUL EBX MOV [EDI+24],AH ;width-LOHI MOV [EDI+25],AL ;width-LOLO SHR EAX,16 MOV [EDI+22],AH ;width-HIHI MOV [EDI+23],AL ;width-HILO ;...........................................; MOV EAX,scImageHeight MOV EBX,6 ;/200*1200 (v. manuale) MUL EBX MOV [EDI+28],AH ;length-LOHI MOV [EDI+29],AL ;length-LOLO SHR EAX,16 MOV [EDI+26],AH ;lenght-HIHI MOV [EDI+27],AL ;lenght-HILO ;...........................................; MOV EAX,scLampLevel MOV [EDI+31],AL ;threshold ;...........................................; MOV AL,1 MOV [EDI+34],AL ;bit per pixel ;-------------------------------------------; CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,scAdapId MOV SRB_EXEC.SRB_HaId,AL MOV SRB_EXEC.SRB_Flags,SRB_EVENT_NOTIFY MOV EAX,scSCSIid MOV SRB_EXEC.SRB_Target,AL MOV SRB_EXEC.SRB_BufLen,72 LEA EAX,SetWindowBuffer 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,SCSI_SETWINDOW MOV [EDI],AL MOV AL,72 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 FFSF3_2 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFSF3_2: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFS_CHECK_SENSE ;===========================================;READ COMMANDS (one or more) MOV EAX,scImageWidth MUL scImageHeight SHR EAX,3 MOV TotBytes2Read,EAX ;-------------------------------------------; FFSF4_1: CMP TotBytes2Read,32768 JB FFSF4_2 SUB TotBytes2Read,32768 MOV Bytes2Read,32768 ;reads 32768 bytes each time JMP FFSF4_3 FFSF4_2: PUSH TotBytes2Read POP Bytes2Read ;last time reads the reminder MOV TotBytes2Read,0 ;-------------------------------------------; FFSF4_3: INVOKE ResetEvent, hEventSRB CALL RESET_SRB_EXEC MOV SRB_EXEC.SRB_Cmd,SC_EXEC_SCSI_CMD MOV EAX,scAdapId MOV SRB_EXEC.SRB_HaId,AL MOV AL,SRB_DIR_IN ADD AL,SRB_EVENT_NOTIFY MOV SRB_EXEC.SRB_Flags,AL MOV EAX,scSCSIid MOV SRB_EXEC.SRB_Target,AL MOV EAX,Bytes2Read MOV SRB_EXEC.SRB_BufLen,EAX MOV EAX,scMemoryArea ADD scMemoryArea,32768 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,SCSI_READ10 MOV [EDI],AL MOV EAX,Bytes2Read MOV [EDI + 7],AH 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 FFSF4_4 INVOKE WaitForSingleObject, hEventSRB, INFINITE FFSF4_4: CMP SRB_EXEC.SRB_Status,SS_COMP JNZ FFS_CHECK_SENSE ;-------------------------------------------; CMP Bytes2Read,0 JNZ FFSF4_1 JMP FFS_OK ;===========================================;read CHECK SENSE data FFS_CHECK_SENSE: LEA EDI,szMsgSense ;prepare the message MOV AL,SRB_EXEC.SRB_Status CALL BYTE2DEC MOV [EDI + 13],AH MOV [EDI + 14],BH MOV [EDI + 15],BL MOV AL,SRB_EXEC.SRB_HaStat CALL BYTE2DEC MOV [EDI + 30],AH MOV [EDI + 31],BH MOV [EDI + 32],BL MOV AL,SRB_EXEC.SRB_TargStat CALL BYTE2DEC MOV [EDI + 51],AH MOV [EDI + 52],BH MOV [EDI + 53],BL LEA ESI,SRB_EXEC.SenseArea MOV AL,[ESI + 2] AND AL,0FH ;sense key CALL BYTE2HEX MOV [EDI + 68],BH MOV [EDI + 69],BL MOV AL,[ESI + 12] ;ASC CALL BYTE2HEX MOV [EDI + 79],BH MOV [EDI + 80],BL MOV AL,[ESI + 13] ;ASCQ CALL BYTE2HEX MOV [EDI + 91],BH MOV [EDI + 92],BL INVOKE MessageBoxA, schWnd, OFFSET szMsgSense, OFFSET szCaptionSense, MB_OK ;===========================================; FFS_OK: POP EBX ; POP EBP ; POP EDI ; POP ESI ; RET ; FFScan ENDP ; ;*******************************************; BYTE2DEC PROC ;===========================================; ; Prepare a byte in AL. The binary number is converted into three ; ASCII characters (in AH, BH e BL) that represent the decimal number. ;===========================================; 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 ;*******************************************; BYTE2HEX PROC ;===========================================; ; Prepare a byte in AL. The binary number is converted into two ; ASCII characters (in BH e BL) that represent the hex number. ;===========================================; 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 ;*******************************************;