
* Parameters for S4OpenEx
#define S4_EXCLUSIZE_MODE			0
#define S4_SHARE_MODE				1

* ctlCode definitions for S4Control
#define S4_LED_UP					0x00000004  && LED up
#define S4_LED_DOWN					0x00000008  && LED down
#define S4_LED_WINK					0x00000028  && LED wink
#define S4_GET_DEVICE_TYPE			0x00000025	&& get device type
#define S4_GET_SERIAL_NUMBER		0X00000026	&& get serial number
#define S4_GET_VM_TYPE				0X00000027  && get VM type
#define S4_GET_DEVICE_USABLE_SPACE	0x00000029  && get total space
#define S4_SET_DEVICE_ID			0x0000002a  && set ID
#define S4_RESET_DEVICE             0x00000002  && reset device
#define S4_DF_AVAILABLE_SPACE       0x00000031  && get the left space size of the current directory
#define S4_EF_INFO                  0x00000032  && get the EF information
#define S4_SET_USB_MODE				0x00000041  && set the device to USB mode
#define S4_SET_HID_MODE				0x00000042  && set the device to HID mode

&& device type
#define S4_LOCAL_DEVICE				0x00		&& local device
#define S4_MASTER_DEVICE			0x80		&& net master device
#define S4_SLAVE_DEVICE				0xc0		&& net slave device

* VM type
#define S4_VM_51					0x00		&& VM51
#define S4_VM_251_BINARY			0x01		&& VM251 binary mode
#define S4_VM_251_SOURCE	    	0X02		&& VM251 source mode


* PIN type
#define	S4_USER_PIN					0x000000a1		&& user PIN
#define S4_DEV_PIN					0x000000a2		&& developer PIN
#define S4_AUTHEN_PIN				0x000000a3		&& authentication key


* file type
#define S4_RSA_PUBLIC_FILE			0x00000006		&& RSA public file
#define S4_RSA_PRIVATE_FILE			0x00000007		&& RSA private file
#define S4_EXE_FILE					0x00000008		&& VM executable file
#define S4_DATA_FILE				0x00000009		&& data file
#define S4_XA_EXE_FILE				0x0000000b		&& XA executable file


#define S4_CREATE_NEW				0x000000a5		&& create new file
#define S4_UPDATE_FILE				0x000000a6		&& update file
#define S4_KEY_GEN_RSA_FILE			0x000000a7		&& produce RSA key pair
#define S4_SET_LICENCES				0x000000a8		&& set license for module of net device
#define S4_CREATE_ROOT_DIR			0x000000ab		&& create root directory
#define S4_CREATE_SUB_DIR			0x000000ac		&& create child directory, only for local device
#define S4_CREATE_MODULE			0x000000ad		&& create module, only for net device

#define S4_FILE_READ_WRITE          0x00000000      && can be read and written, default, only for executable file
#define S4_FILE_EXECUTE_ONLY        0x00000100      && can NOT be read or written, only for executable file
#define S4_CREATE_PEDDING_FILE		0X00002000		&& create padding file,only for executable file


#define S4_VM_EXE					0x00000000		&& run as VM executable file
#define S4_XA_EXE					0x00000001		&& run as XA executable file



#define	S4_SUCCESS					0x00000000		&& succeed
#define S4_UNPOWERED				0x00000001
#define	S4_INVALID_PARAMETER		0x00000002
#define S4_COMM_ERROR				0x00000003
#define S4_PROTOCOL_ERROR			0x00000004
#define S4_DEVICE_BUSY				0x00000005
#define S4_KEY_REMOVED				0x00000006
#define S4_INSUFFICIENT_BUFFER		0x00000011
#define S4_NO_LIST					0x00000012
#define S4_GENERAL_ERROR			0x00000013
#define S4_UNSUPPORTED				0x00000014
#define S4_DEVICE_TYPE_MISMATCH		0x00000020
#define S4_FILE_SIZE_CROSS_7FFF		0x00000021
#define S4_DEVICE_UNSUPPORTED		0x00006a81
#define S4_FILE_NOT_FOUND			0x00006a82
#define S4_INSUFFICIENT_SECU_STATE  0x00006982
#define S4_DIRECTORY_EXIST			0x00006901
#define S4_FILE_EXIST				0x00006a80
#define S4_INSUFFICIENT_SPACE		0x00006a84
#define S4_OFFSET_BEYOND			0x00006B00
#define S4_PIN_BLOCK				0x00006983
#define	S4_FILE_TYPE_MISMATCH		0x00006981
#define S4_CRYPTO_KEY_NOT_FOUND		0x00009403
#define S4_APPLICATION_TEMP_BLOCK	0x00006985
#define S4_APPLICATION_PERM_BLOCK	0x00009303
#define S4_DATA_BUFFER_LENGTH_ERROR	0x00006700		
#define S4_CODE_RANGE				0x00010000
#define S4_CODE_RESERVED_INST		0x00020000
#define S4_CODE_RAM_RANGE			0x00040000
#define S4_CODE_BIT_RANGE			0x00080000
#define S4_CODE_SFR_RANGE			0x00100000
#define S4_CODE_XRAM_RANGE			0x00200000
#define S4_ERROR_UNKNOWN			0xffffffff
#define S4_CURRENT_DF_ISNOT_MF		0x00000201
#define S4_INVAILABLE_MODULE_DF			0x00000202
#define S4_FILE_SIZE_TOO_LARGE		0x00000203	
#define S4_DF_SIZE					0x00000204	

#define MAX_ATR_LEN					56
#define MAX_ID_LEN					8



DECLARE Integer S4Enum IN sense4.dll String @s4CtxList, integer @lpCtxListSize
DECLARE Integer S4Open IN sense4.dll String @s4Ctx
DECLARE Integer S4Close IN sense4.dll String @s4Ctx
DECLARE Integer S4ChangeDir IN sense4.dll String @s4Ctx, String lpszPath
DECLARE Integer S4VerifyPin IN sense4.dll String @s4Ctx, String lpPin, Integer dwPinLen, Integer dwPinType
DECLARE Integer S4Execute IN sense4.dll String @s4Ctx, String lpszFileID, String lpInBuffer, Integer dwInbufferSize, String @lpOutBuffer, Integer dwOutBufferSize, Integer @lpReturnLen
DECLARE Integer S4EraseDir IN sense4.dll string @s4Ctx, String lpszDirID
DECLARE Integer S4CreateDir IN sense4.dll String @s4Ctx, String lpszDirID, integer dwDirsize, integer dwFlags
DECLARE Integer S4ChangePin IN sense4.dll String @s4Ctx, String lpOldPin, integer dwOldPinLen, String LpNewPin, integer dwNewPinLen, integer dwPinType
DECLARE Integer S4WriteFile IN sense4.dll String @s4Ctx, String lpszFileID, integer dwOffset, String lpBuffer,integer dwBufferSize, integer dwFileSize, integer @bytesWritten, integer dwFlags, integer bFileType
DECLARE Integer S4Control IN sense4.dll String @s4Ctx, integer ctlCode, String inbuff, integer inbufflen,;
String @outBuff, integer outBuffLen, integer @BytesReturned
Declare Integer S4Startup In sense4.dll 
Declare Integer S4Cleanup In sense4.dll
DECLARE Integer S4ExecuteEx IN sense4.dll String @s4Ctx, String lpszFileID, integer dwFlag, String lpInBuffer, Integer dwInbufferSize, String @lpOutBuffer, Integer dwOutBufferSize, Integer @lpReturnLen
DECLARE Integer S4OpenEx IN sense4.dll String @s4Ctx, String  @pS4OpenInfo
DECLARE Integer S4CreateDirEx IN sense4.dll String @s4Ctx, String lpszDirID, integer dwDirSize, integer dwFlags, String @pCreateDirInfo


&&You need add the lines above to your own program


s4Ctx=SPACE(92)
dime openInfo(8)  
dime s4CrtInfo(12) 

*input parameters
InBuff = CHR(31) + CHR(32)+CHR(33)+CHR(34)
*output parameters
OutBuff = SPACE(4)

s4ctxSize = 0

do while .T.
   wait "click 'c' or 'q':"to key   
   
   do case
   case key='C' .OR.key='c'
      clear

      ret = 1      
      retLen = 0
      dwIndex = 0
      
      S4Startup()
      
	  *enumerate SenseLock EL device
      ret = S4Enum(@s4Ctx, @s4CtxSize)
      ret = S4Enum(@s4Ctx, @s4CtxSize)
      if ret != S4_SUCCESS then
              ?"Failed to find SenseLock EL device!"
      else
              ?"Enumerate devices successfully!"
      endif
      
      *open SenseLock EL device
	  ret = s4Open(@s4Ctx)
      if ret != S4_SUCCESS then
              ?"Failed to open SenseLock EL device!"
              ?ret 
      else
              ?"Open SenseLock EL device successfully!"
      endif
      
      StrOutBuff = ""
      byteReturned = 0
      ret = S4Control(@s4Ctx, S4_LED_UP, "", 0, @StrOutBuff, 0, @ByteReturned)
      
      if ret = S4_SUCCESS then
      	?"Invoke S4Control successfully!"
      else
      	?"Failed to invoke S4Control!"
      endif
      
      
      
      *change current directory to root directory
      ret = S4ChangeDir(@s4Ctx,"\")
      if ret != S4_SUCCESS then
              ?"Failed to find MF!"
      else
              ?"Change current directory to MF."
      endif
      
      ret = s4VerifyPin(@s4Ctx, "123456781234567812345678", 24, S4_DEV_PIN)
      if ret = S4_SUCCESS then
      	?"Verify developer PIN successfully!"
      	ret = S4EraseDir(@s4Ctx, 0)
      	if ret = S4_SUCCESS then
      		?"Erase root directory successfully!"
      	endif
      else
      	?"Failed to verify developer PIN!"
      endif
      
 
      ret = S4CreateDir(@s4Ctx, "\", 0, S4_CREATE_ROOT_DIR)
      if ret = S4_SUCCESS then
      	?"Create root directory successfully!"
      else
      	?"Failed to create root directory!"
      endif 
      
      ret = S4ChangePIN(@s4Ctx, "12345678", 8, "11111111", 8, S4_USER_PIN)
      if ret = S4_SUCCESS then
      	?"Modify user PIN successfully!"
      else
      	?"Failed to modify user PIN!"
      endif

 	  ret = S4VerifyPin(@s4Ctx, "123456781234567812345678", 24, S4_DEV_PIN)
      if ret = S4_SUCCESS then
      	?"Verify developer PIN successfully!"
      else
      	?"Failed to verify developer PIN!"
      endif

      
      *get the content of demo_v20.bin
      Local cString, gnBinFile
      gnBinFile = FOPEN("demo_v20.bin", 0)  
      nSize =  FSEEK(gnBinFile, 0, 2)     
      FSEEK(gnBinFile, 0, 0)      && Move pointer to BOF
 	  cString = FREAD(gnBinFile, nSize) 	  
 	  FClose(gnBinFile)
 	  
 	  dwReturnLen = 0
 	  ret = S4VerifyPin(@s4Ctx, "123456781234567812345678", 24, S4_DEV_PIN)
 	  
 	  Ret = S4WriteFile(@s4Ctx, "1001", 0, cString, nSize, nSize, @dwReturnLen, S4_CREATE_NEW, S4_EXE_FILE)
 	  if ret = S4_SUCCESS
 	  	?"Write file 1001 successfully!"
 	  else
 	  	?"Failed to write file 1001!"
 	  	?ret
 	  endif
 	  
      *get the content of demo_v30.bin
       gnBinFile = FOPEN("demo_v30.bin", 0)  
      nSize =  FSEEK(gnBinFile, 0, 2)     
      FSEEK(gnBinFile, 0, 0)      && Move pointer to BOF
 	  cString = FREAD(gnBinFile, nSize) 	  
 	  FClose(gnBinFile)
 	  
 	  dwReturnLen = 0
	  
 	  Ret = S4WriteFile(@s4Ctx, "1002", 0, cString, nSize, 1000, @dwReturnLen, S4_CREATE_NEW, S4_XA_EXE_FILE)
 	  if ret = S4_SUCCESS
 	  	?"Write file 1002 successfully!"
 	  else
 	  	?"Failed to write file 1002!"
 	  	?ret
 	  endif
         
      *verify user PIN
      ret = s4VerifyPin(@s4Ctx, "11111111", 8, S4_USER_PIN)
      if ret != S4_SUCCESS then
              ?"Failed to verify user PIN!"
      else
              ?"Verify user PIN successfully!"
      endif
      
      *Execute file 1001,assume that the demo_v20.bin has been written in MF as 1001
      *Input argument is {31,32,33,34}
      ret = s4ExecuteEx(@s4Ctx,"1001", S4_VM_EXE, InBuff,4,@OutBuff,4,@retLen)
      if ret != S4_SUCCESS then
              ?"Failed to execute file 1001!"
      else
              ?"Execute file 1001 successfully!"
              OutBuff0=SUBSTR(OutBuff,1,1)
      		  y0=ASC(OutBuff0)
      		  OutBuff1=SUBSTR(OutBuff,2,1)
		      y1=ASC(OutBuff1)
			  x0=y1+y0 *256
		      OutBuff2=SUBSTR(OutBuff,3,1)
		      y2=ASC(OutBuff2)
		      OutBuff3=SUBSTR(OutBuff,4,1)
		      y3=ASC(OutBuff3)
		      x1=y3+y2*256      
		      ?"The return value is " + Str(x0) + Str(x1)      
      endif

	 * run 1002 as XA executable file
      ret = s4ExecuteEx(@s4Ctx,"1002",S4_XA_EXE, InBuff,4,@OutBuff,4,@retLen)
      if ret != S4_SUCCESS then
              ?"Failed to execute file 1002 as XA executable file!"
      else
              ?"Execute file 1002 as XA executable file successfully!"
              OutBuff0=SUBSTR(OutBuff,1,1)
      		  y0=ASC(OutBuff0)
      		  OutBuff1=SUBSTR(OutBuff,2,1)
		      y1=ASC(OutBuff1)
			  x0=y0+y1 *256
		      OutBuff2=SUBSTR(OutBuff,3,1)
		      y2=ASC(OutBuff2)
		      OutBuff3=SUBSTR(OutBuff,4,1)
		      y3=ASC(OutBuff3)
		      x1=y2+y3*256      
		      ?"The return value is " + Str(x1) + Str(x0)     
      endif
                
      ret = S4Control(@s4Ctx, S4_LED_DOWN, "", 0, @StrOutBuff, 0, @ByteReturned)
            
      if ret = S4_SUCCESS then
      	?"Invoke S4Control successfully!"
      else
      	?"Failed to invoke S4Control!"
      endif
            
      ret = s4Close(@s4Ctx)
      if ret != S4_SUCCESS then
      	?"Failed to close device!"
      else
      	?"Close device successfully!"
      endif 
      s4Cleanup()
   case key='Q' .OR.key='q'
   ?"Quit"
   exit
   endcase 
enddo

   	  DEFINE CLASS S4OPENINFO AS CUSTOM
		dwS4OpenInfoSize = SPACE(4)
		dwShareMode = SPACE(4)
	  ENDDEFINE

	  DEFINE CLASS S4CREATEDIRINFO AS CUSTOM
		dwS4CreateDirInfoSize = SPACE(4)
		szAtr = SPACE(8)
	  ENDDEFINE