Making JaCarta Editor

    “I can say only one thing about the Kingdom of Shadows: there is reality and there is its Shadow; this is the essence of everything. In the real World, there is only Amber, the real city on the real Earth, in which everything is collected. And the Kingdom of Shadows is only the infinity of unreality. Here you can also find everything - but it will be shadows, a distorted reflection of reality. The Kingdom of Shadows surrounds Amber from all sides. And beyond, chaos reigns. Everything is possible on the way from Amber to the Kingdom of Chaos. ”
    Roger Zhelyazny. The Nine Princes of Amber


    It all started with the need to work with the same key on etoken from different, significantly remote workstations (USB Over IP will be a little expensive for a couple of tokens) and my great desire to open this closed world. I came across the work habr.com/post/276057 for which its author has great respect, in my project a significant part of the functions he reversed was used (the code is open). True, as it turned out, everything that works with etsdk.dll only works with blue fish. Therefore, for JaCarta, new functions had to be rewritten, and some of them had to be edited.

    As a result of long research, the JaCarta Editor appeared - a program that shows and allows you to edit entities (that is how the token file system objects are called in the official documentation, apparently hinting at their ephemerality and irreality) on tokens from Aladdin, including the most modern ones.

    A similar application for Rutoken is publicly available as part of the Rutoken SDK (Rutoken Editor), but for Aladdin, at least it is not in the public domain, although about 15 years ago, judging by the documentation that was found on the Internet, it was (ETEditor).

    The program is written in Autoit, tested with EToken PRO Java 72 K, JaCarta LT, JaCarta Pro, JaCarta GOST-2.

    The program will not work if Rutoken drivers are installed on the computer (it is required that EToken or Ja Carta have a reader number 0).

    For the same reason, only one token must be connected for correct operation.

    The script uses Window $ system calls, and was tested only with this OS family.

    For work installation of the "Single client JaCarta" is required(free download from the manufacturer’s website), when installed, a much newer version of etsdk.dll and jcFS.dll containing the JaCarta File System functions (very similar to those in etsdk.dll, but installed in the windows system folder are also installed) jcFS there are much more functions without which working with some modern jakarts, for example GOST-2, will be impossible). When the Unified Client is installed, it is naturally not necessary to search and put this dll in the folder with the program, otherwise, with the driver installed the specific type of token, this dll should be in the program folder.

    All jcFS functions are described in detail on the manufacturer’s website, but nevertheless, some parameters of these functions had to be selected experimentally.

    In order to access the root directory of the token, you must call the ETRootDirOpen or JCRootDirOpen function (which is the same, since the first in the dll calls the second, this is true for almost all functions, but there are a few exceptions) with a vendor identifier of 0 (constants like 0xF007 will allow see only individual directories of mostly old eToken which store bank keys generated using utilities such as PKIAdmin and MessagePRO).

    The next important feature of modern jakarta is the need to know the id of the applet that is installed on the token, the JCSelectApplet function is responsible for this.

    Older tokens usually have a default applet and calling this function is not specifically required, but for new and relatively new jakarts without knowing the applet id, further work becomes impossible. Calling all functions receiving information from the token in this case returns False. In my project, in this case, a two-stage brute force is implemented (the token always responds to two id, but only one of them works) id and further work with the desired value.

    All information is displayed in the output window located under the directory tree.
    The PIN code has been entered, information about the remaining attempts to enter it is also displayed.
    The contents of the directories and brief information about the files are displayed: the name, whether the file is private information is a private PIN code - the letter p: (the file is public after it, the unit is private) and the file size in bytes after “s:”. The file is opened by double-clicking.

    You can view and, if necessary, copy the contents of the token files to the buffer in hexadecimal format or save in binary form to a computer.

    You can also change the contents of the file and select “Save Changes” in the menu (the PIN code must be entered first, if it has not been entered, an appropriate message will be displayed, in which case the edited data can be selected and copied to the clipboard).

    To delete a file, select it and click "Delete", after which a confirmation window will appear.

    JaCarta File System has an interesting feature, which is present on all tokens that I tested. If you create a directory or several directories without files on the token, during the next session of working with the token they will disappear, apparently this way the file system takes care of saving the token's memory and cleans up all garbage.

    Therefore, when you click the Create button in the program, a chain is created immediately from a directory or two directories and a file. The nesting depth of directories in the program is two, not counting the root. In the root directory, you can only create directories, but not files.
    Before creating, editing or deleting entities, you must enter a PIN code.

    A very important note about directory names!

    On tokens where the content is created by the manufacturer, you will never see directories with the same name, wherever they are. This is due to file system features.

    Suppose we have the following entity on the token: // 0001 / A001 / 0008 (that is, the folder 0001 is in the root directory, the folder A001 is in it, and the file 0008 is in it) and we create a new entity on the token: // CC00 / 0001/1010 . When accessing the file 1010, the search for the directory 0001 will begin, which is located in the root and will be found first, but there is no such file in it. As a result, the function returns False and the entity becomes lost; you cannot either access it and delete it either. Only token initialization will help.

    Of particular note is EToken PRO and JA Carta Pro, which differ only in appearance, they have system files in the root directory (they are shown on the screen), in one of which the hash of the pin code is stored, changing these files leads to the fact that authorization becomes impossible (pin code becomes incorrect) and after that only initialization will help.

    Regarding private keys, it was possible to establish the following: if a container created by a third-party cryptographic provider, such as CryptoPro, is stored on the token, then all its contents, including private keys, will be available, it's just a flash drive with a PIN code (as shown in the picture). If the key pair was generated on board the token using PKCS11, then only the certificate and public key will be available.

    Since this is an experimental program, I do not recommend using it with tokens containing valid EDS keys, all operations are carried out at the experimenter's fear and risk. This is especially true for the creation of new entities, in some cases the result is difficult to predict.

    All information for creating the program was obtained from open sources, the purpose of its creation is purely research.

    The script itself

    JACartaEditor.au3
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #NoTrayIcon
    ;функции из jcFS.dll
    Dim $ETSdkDll=DllOpen('jcFS.dll')
    Func ETTokenLock($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenLock', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenUnLock($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenUnLock', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETReadersEnumOpen()
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETReadersEnumOpen', _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETReadersEnumNext($EnumId)
    	Local $Reader=DllStructCreate('CHAR name[260]; BYTE etoken;')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETReadersEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Reader) _
    	)
    	Local $Result[2]=[	DllStructGetData($reader,'name'), _
    						DllStructGetData($reader,'etoken')]
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:$Result
    EndFunc
    Func ETReadersEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETReadersEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenBind($ReaderName)
    	Local $In=DllStructCreate('BYTE['&(StringLen($ReaderName)+1)&']')
    	Local $Out=DllStructCreate('DWORD')
    	DllStructSetData($In,1,$ReaderName)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenBind', _
    		'PTR',DllStructGetPtr($Out), _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETTokenRebind($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenRebind', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenUnbind($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenUnbind', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenLogin($BindId,$Pin='')
    	Local $In=DllStructCreate('BYTE['&(StringLen($Pin)+1)&']')
    	DllStructSetData($In,1,$Pin)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenLogin', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenPinChange($BindId,$Pin)
    	Local $In=DllStructCreate('CHAR['&(StringLen($Pin)+1)&']')
    	DllStructSetData($In,1,$Pin)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenPinChange', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenLogout($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenLogout', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETRootDirOpen($BindId,$Dir=0xF007)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETRootDirOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$BindId, _
    		'DWORD',$Dir _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETDirOpen($Dir,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$Dir, _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETDirCreate($Dir,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirCreate', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$Dir, _
    		'DWORD',$DirId, _
    		'DWORD',0 _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETDirGetInfo($DirId)
    	Local $Out=DllStructCreate('WORD wDirName; WORD wSize')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirGetInfo', _
    		'DWORD',$DirId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    Local $Result[2]=[	DllStructGetData($Out,'wDirName'), _
    						DllStructGetData($Out,'wSize')]
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:$Result
    EndFunc
    Func ETDirClose($DirId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirClose', _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETDirDelete($DirId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirDelete', _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETDirEnumOpen($DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirEnumOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETDirEnumNext($EnumId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETDirEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETDirEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETFileOpen($File,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId, _
    		'DWORD',$File _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETFileCreate($File,$DirId,$Size,$Private=0)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileCreate', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId, _
    		'DWORD',$File, _
    		'DWORD',$Size, _
    		'DWORD',$Private _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETFileGetInfo($FileId)
    	Local $Out=DllStructCreate('WORD name;WORD private;WORD;WORD size')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileGetInfo', _
    		'DWORD',$FileId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Local $Result[3]=[	DllStructGetData($Out,'name'), _
    						DllStructGetData($Out,'private'), _
    						DllStructGetData($Out,'size')]
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:$Result
    EndFunc
    Func ETFileRead($FileId)
    	Local $FileInfo=ETFileGetInfo($FileId)
    	If @error Then Return SetError(@error,0,False)
    	Local $Out=DllStructCreate('BYTE ['&$FileInfo[2]&']')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileRead', _
    		'DWORD',$FileId, _
    		'DWORD',0, _
    		'DWORD',0xFFFF, _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$FileInfo[2] _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETFileWrite($FileId,$Data,$Pos=0)
    	$Data=Binary($Data)
    	Local $DataSize=BinaryLen($Data)
    	Local $In=DllStructCreate('BYTE['&$DataSize&']')
    	DllStructSetData($In,1,$Data)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileWrite', _
    		'DWORD',$FileId, _
    		'DWORD',$Pos, _
    		'PTR',DllStructGetPtr($In), _
    		'DWORD',$DataSize _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETFileClose($FileId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileClose', _
    		'DWORD',$FileId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETFileDelete($FileId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFileDelete', _
    		'DWORD',$FileId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETFilesEnumOpen($DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFilesEnumOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETFilesEnumNext($EnumId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFilesEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETFilesEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETFilesEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func ETTokenLabelGet($BindId)
    	Local $Out1=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenLabelGet', _
    		'DWORD',$BindId, _
    		'PTR',0, _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	If $CallRes[0] Then Return SetError($CallRes[0],0,False)
    	Local $Out2=DllStructCreate('CHAR['&DllStructGetData($Out1,1)&']')
    	$CallRes=DllCall($ETSdkDll,'WORD','ETTokenLabelGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out2), _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out2,1)
    EndFunc
    Func ETTokenIDGet($BindId)
    	Local $Out1=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenIDGet', _
    		'DWORD',$BindId, _
    		'PTR',0, _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	If $CallRes[0] Then Return SetError($CallRes[0],0,False)
    	Local $Out2=DllStructCreate('CHAR['&DllStructGetData($Out1,1)&']')
    	$CallRes=DllCall($ETSdkDll,'WORD','ETTokenIDGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out2), _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out2,1)
    EndFunc
    Func ETTokenMaxPinGet($BindId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenMaxPinGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETTokenMinPinGet($BindId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETTokenMinPinGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func ETSelectApplet($BindId, $Applet)
    Local $In=DllStructCreate('DWORD')
    	DllStructSetData($In,1,$Applet)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','ETSelectApplet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Applet) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCSelectApplet($BindId, $Applet)
    Local $In=DllStructCreate('WORD')
    	DllStructSetData($In,1,$Applet)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCSelectApplet', _
    		'DWORD',$BindId, _
    		'WORD',$Applet _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCReadersEnumOpen()
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCReadersEnumOpen', _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCReadersEnumNext($EnumId)
    	Local $Reader=DllStructCreate('CHAR name[260]; BYTE etoken;')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCReadersEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Reader) _
    	)
    	Local $Result[2]=[	DllStructGetData($reader,'name'), _
    						DllStructGetData($reader,'etoken')]
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:$Result
    EndFunc
    Func JCReadersEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCReadersEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenBind($ReaderName)
    	Local $In=DllStructCreate('CHAR['&(StringLen($ReaderName)+1)&']')
    	Local $Out=DllStructCreate('DWORD')
    	DllStructSetData($In,1,$ReaderName)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenBind', _
    		'PTR',DllStructGetPtr($Out), _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCTokenRebind($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenRebind', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenUnbind($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenUnbind', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenLogin($BindId,$Pin)
    	Local $In=DllStructCreate('CHAR['&(StringLen($Pin)+1)&']')
    	DllStructSetData($In,1,$Pin)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenLogin', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenPinChange($BindId,$Pin)
    	Local $In=DllStructCreate('CHAR['&(StringLen($Pin)+1)&']')
    	DllStructSetData($In,1,$Pin)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenPinChange', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($In) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenLogout($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenLogout', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCRootDirOpen($BindId,$Dir=0)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCRootDirOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$BindId, _
    		'WORD',$Dir _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirOpen($Dir,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$Dir, _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirCreate($Dir,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirCreate', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$Dir, _
    		'DWORD',$DirId, _
    		'DWORD',0 _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirGetInfo($DirId)
    	Local $Out=DllStructCreate('BYTE[8]')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirGetInfo', _
    		'DWORD',$DirId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirClose($DirId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirClose', _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCDirDelete($DirId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirDelete', _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCDirEnumOpen($DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirEnumOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirEnumNext($EnumId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCDirEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCDirEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCFileOpen($File,$DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId, _
    		'DWORD',$File _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCFileCreate($File,$DirId,$Size,$Private=0)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileCreate', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId, _
    		'DWORD',$File, _
    		'DWORD',$Size, _
    		'DWORD',$Private _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCFileGetInfo($FileId)
    	Local $Out=DllStructCreate('WORD name;WORD private;WORD;WORD size')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileGetInfo', _
    		'DWORD',$FileId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Local $Result[3]=[	DllStructGetData($Out,'name'), _
    						DllStructGetData($Out,'private'), _
    						DllStructGetData($Out,'size')]
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:$Result
    EndFunc
    Func JCFileRead($FileId)
    	Local $FileInfo=JCFileGetInfo($FileId)
    	If @error Then Return SetError(@error,0,False)
    	Local $Out=DllStructCreate('BYTE ['&$FileInfo[2]&']')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileRead', _
    		'DWORD',$FileId, _
    		'DWORD',0, _
    		'DWORD',0xFFFF, _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$FileInfo[2] _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCFileWrite($FileId,$Data,$Pos=0)
    	$Data=Binary($Data)
    	Local $DataSize=BinaryLen($Data)
    	Local $In=DllStructCreate('BYTE['&$DataSize&']')
    	DllStructSetData($In,1,$Data)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileWrite', _
    		'DWORD',$FileId, _
    		'DWORD',$Pos, _
    		'PTR',DllStructGetPtr($In), _
    		'DWORD',$DataSize _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCFileClose($FileId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileClose', _
    		'DWORD',$FileId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCFileDelete($FileId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFileDelete', _
    		'DWORD',$FileId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCFilesEnumOpen($DirId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFilesEnumOpen', _
    		'PTR',DllStructGetPtr($Out), _
    		'DWORD',$DirId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCFilesEnumNext($EnumId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFilesEnumNext', _
    		'DWORD',$EnumId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCFilesEnumClose($EnumId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCFilesEnumClose', _
    		'DWORD',$EnumId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenLabelGet($BindId)
    	Local $Out1=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenLabelGet', _
    		'DWORD',$BindId, _
    		'PTR',0, _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	If $CallRes[0] Then Return SetError($CallRes[0],0,False)
    	Local $Out2=DllStructCreate('CHAR['&DllStructGetData($Out1,1)&']')
    	$CallRes=DllCall($ETSdkDll,'WORD','JCTokenLabelGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out2), _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out2,1)
    EndFunc
    Func JCTokenIDGet($BindId)
    	Local $Out1=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenIDGet', _
    		'DWORD',$BindId, _
    		'PTR',0, _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	If $CallRes[0] Then Return SetError($CallRes[0],0,False)
    	Local $Out2=DllStructCreate('CHAR['&DllStructGetData($Out1,1)&']')
    	$CallRes=DllCall($ETSdkDll,'WORD','JCTokenIDGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out2), _
    		'PTR',DllStructGetPtr($Out1) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out2,1)
    EndFunc
    Func JCTokenMaxPinGet($BindId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenMaxPinGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCTokenMinPinGet($BindId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenMinPinGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    Func JCTokenUnLock($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenUnLock', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenLock($BindId)
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenLock', _
    		'DWORD',$BindId _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:True
    EndFunc
    Func JCTokenPinAttemptsGet($BindId)
    	Local $Out=DllStructCreate('DWORD')
    	Local $CallRes=DllCall($ETSdkDll,'WORD','JCTokenPinAttemptsGet', _
    		'DWORD',$BindId, _
    		'PTR',DllStructGetPtr($Out) _
    	)
    	Return $CallRes[0] _
    		?SetError($CallRes[0],0,False) _
    		:DllStructGetData($Out,1)
    EndFunc
    ;Начало приложения
    Opt("GUIOnEventMode", 1)
    Dim $BindId, $filelog, $Result, $DirIdRoot=False, $Edit, $msg, $Fileinfo, $treeview, $generalitem, $displayitem, $diritem, $Edit, $SrcSubId, $Output, $pinbutton, $hPinWin, $PinEdit, $pinokbutton, $pincancelbutton, $Pin, $Edit1, $Reader, $Applet, $AppletID, $text, $CreateDirWin
    Global $Dir1, $Dir2
    Dim $hParentWin, $hChildWin, $sItemText, $folderbutton, $filebutton, $deletebutton, $CreateFileWin, $FileEdit, $fileokbutton, $filecancelbutton, $publicbutton, $privatebutton, $sizefile
    Dim $hFile, $hMain
    Global Enum $idSave= 1000, $Save
    Dim $Appname = 'JaCarta Editor'
    ;Функция получения applet ID брутфорсом
    Func Applet()
    	  GUICtrlSetData($Output, 'Попытка получить applet ID... '&@CRLF,1)
    	  Local $Result, $AppletTemp= 0
    	  For $Applet = 0 To 65535  Step 1
    		 $Result = 0
    		 $Result=JCSelectApplet($BindId,$Applet) ; 0x2001 PROJAVA для E-token, 0x1002 PRO, 0x1001 R2, 0x2202 GOST, 0x2205 DATASTORE, 0x2206 ГОСТ-2, 0x2201, 0x2204 (чёрные JaCarta)
    			If $Result = True   Then
    			   $AppletTemp=$Applet
    			   $AppletID=$Applet
    			   ExitLoop
    			EndIf
    	  Next
    	  Local $Id=ETTokenLabelGet($BindId)
    	  if $Id= False Then
    		 For $Applet=$AppletTemp+1 To 65535  Step 1
    			 $Result=0
    			 $Result=JCSelectApplet($BindId,$Applet)
    			   If $Result = True   Then
    				  ExitLoop
    			   EndIf
    		 Next
    	  EndIf
    	  JCSelectApplet($BindId,$Applet)
    	  GUICtrlSetData($Output, 'Select applet 0x'&hex($Applet,4)&@CRLF,1)
    	  $AppletID=$Applet
    EndFunc
    ;Просмотр директорий и файлов в цикле
    Func PrintDir($Id,$Prefix)
    	  Local $EnumId=ETDirEnumOpen($Id)
    	  While 1
    			Local $dir=ETDirEnumNext($EnumId)
    			If @error Then ExitLoop
    			Local $DirId=ETDirOpen($dir,$Id)
    			Local   $Dirinfo
    			$Dirinfo=ETDirGetInfo($DirId)
    			Local $Dirtext='(dir)'&hex($dir,4)
    			$diritem = _GUICtrlTreeView_AddChild($treeview,$Prefix, $Dirtext)
    			PrintDir($DirId,$diritem)
    			ETDirClose($DirId)
    	  WEnd
    	  ETDirEnumClose($EnumId)
    	  $EnumId=ETFilesEnumOpen($Id)
    	  While 1
    			Local $file=ETFilesEnumNext($EnumId)
    			If @error Then ExitLoop
    			Local $FileId=ETFileOpen($file,$Id)
    			$Fileinfo=ETFileGetInfo($FileId)
    			Local $filetext='(file)'&hex($file,5)&' '&'p: '&$Fileinfo[1]&' s: '&$Fileinfo[2]&@CRLF
    			_GUICtrlTreeView_AddChild($treeview,$Prefix,$filetext)
    	  WEnd
    	  ETFilesEnumClose($EnumId)
    EndFunc
    ;операции подключения к токену и получения от него информации
    Func List()
    		 GUICtrlSetData($Output, '')
    		 Local $text
    		 Local $EnumId=ETReadersEnumOpen()
    		 GUICtrlSetData($Output, 'В системе установлены ридеры:'&@CRLF,1)
    		 While 1
    			   $Reader=ETReadersEnumNext($EnumId)
    			   If @error Then ExitLoop
    			   GUICtrlSetData($Output, $Reader[0]&@CRLF,1)
    		 WEnd
    		 ETReadersEnumClose($EnumId)
    		 Local $EnumId=ETReadersEnumOpen()
    		 $Reader=ETReadersEnumNext($EnumId)
    		 $BindId=ETTokenBind($Reader[0])
    		 $Result=JCTokenLock($BindId)
    		 GUICtrlSetData($Output, 'Подключен ридер '&$Reader[0]&@CRLF,1)
    		 ;если не получается получить ID токена, значит надо подбирать AppletID
    		 $Result=ETTokenIDGet($BindId)
    		 if $Result= False Then
    			if $AppletID<>0 Then
    			   JCSelectApplet($BindId,$AppletID)
    			Else
    			   Applet()
    			EndIf
    		 EndIf
    		 $Result=ETTokenIDGet($BindId)
    		 $text=$Reader[0]&' ID '&$Result
    		 $generalitem = _GUICtrlTreeView_AddChild($treeview,0,$text)
    		 $Result=ETTokenLabelGet($BindId)
    		 GUICtrlSetData($Output, 'Label: '&$Result&@CRLF,1)
    		 $DirIdRoot=ETRootDirOpen($BindId,0) ;0xF007 для банков 0x0001 для крипто про
    		 $Result=JCTokenPinAttemptsGet($BindId)
    		 ;если был введён пин код начинаем авторизацию
    		 If $Pin <> 0   Then
    			$Result=JCTokenLogin($BindId,$Pin)
    			If $Result=False   Then
    			   $Result=JCTokenPinAttemptsGet($BindId)
    			   MsgBox(0x10,$Appname,'Неверный PIN код'&@CRLF&'Количество попыток ввода PIN кода: '&$Result )
    			Else
    			GUICtrlSetData($Output, 'Login OK'&@CRLF,1)
    			EndIf
    		 EndIf
    		 $Result=JCTokenPinAttemptsGet($BindId)
    		 GUICtrlSetData($Output, 'Количество попыток ввода PIN кода: '&$Result&@CRLF,1)
    		 PrintDir($DirIdRoot,0)
    		 ETTokenUnbind($BindId)
    		 ETReadersEnumClose($EnumId)
    EndFunc
    ;закрытие дочерних окон и программы
    Func onClose()
    	  GUISetState(@SW_HIDE, $hPinWin)
    	  GUISetState(@SW_HIDE, $hChildWin)
    	  GUISetState(@SW_HIDE, $CreateFileWin)
    	  if @GUI_WinHandle=$hParentWin Then
    		 Exit
    	  EndIf
    EndFunc
    ;вывод окна ввода пин кода
    Func onPin()
    	  GUISetState(@SW_SHOW, $hPinWin )
    EndFunc
    ;подготовка к авторизации после ввода пин кода
    Func onPinOK()
    	  $Pin=GUICtrlRead($PinEdit)
    	  GUISetState(@SW_HIDE, $hPinWin)
    	  _GUICtrlTreeView_DeleteAll ($treeview)
    	  List()
    EndFunc
    ;отмена ввода пин кода
    Func onPinCancel()
    	  GUISetState(@SW_HIDE, $hPinWin)
    EndFunc
    ;функция удаления
    Func Delete()
    	  If $Pin=0   Then
    		 MsgBox(0x10,$Appname,'Для удаления файла сначала введите пин код' )
    	  Else
    		 Local $hItem = _GUICtrlTreeView_GetSelection($treeview)
    		 Local $Del = _GUICtrlTreeView_GetText($treeview, $hItem)
    		 if _GUICtrlTreeView_GetChildren($treeview, $hItem)=False Then
    			$Del=StringTrimLeft (  $Del, 6 )
    			Local $p=0
    			$p=StringInStr ($Del,"p:")
    			$Del=StringMid ( $Del, 1, $p-2 )
    			if MsgBox(4 + 32, $Appname,  'Удалить '& $Del &' ?') = 6 Then
    			   Local $DirID=_GUICtrlTreeView_GetParentHandle($treeview, $hItem)
    			   Local $Dir= _GUICtrlTreeView_GetText($treeview, $DirID)
    			   $Dir=StringTrimLeft (  $Dir, 5 )
    			   $BindId=ETTokenBind($Reader[0])
    			   $Result=JCTokenLock($BindId)
    			   if $AppletID<>0 Then
    				  JCSelectApplet($BindId,$AppletID)
    			   EndIf
    			   If $Pin <> 0   Then
    				  $Result=JCTokenLogin($BindId,$Pin)
    				  If $Result=False   Then
    					 $Result=JCTokenPinAttemptsGet($BindId)
    					 MsgBox(0x10,$Appname,'Неверный PIN код'&@CRLF&'Количество попыток ввода PIN кода: '&$Result)
    				  EndIf
    			   EndIf
    			   Local $HDir=GetDir(ETRootDirOpen($BindId,0), $Dir)
    			   Local $DELFile =JCFileOpen(Dec ($Del), $HDir)
    			   JCFileDelete($DELFile )
    			   ETDirClose($HDir)
    			   ETTokenUnbind($BindId)
    			   _GUICtrlTreeView_DeleteAll ($treeview)
                   List()
    			EndIf
    		 Else
    			   MsgBox(0x10,$Appname,'Сначала удалите все файлы в папке после чего папка будет удалена автоматически' )
    		 EndIf
    	  EndIf
    EndFunc
    ;функция вывода окна создания файла
    Func onFileCreate()
    	  If $Pin=0   Then
    		 MsgBox(0x10,$Appname,'Для создания файла сначала введите пин код' )
    	  Else
    		 Local $hItem = _GUICtrlTreeView_GetSelection($treeview)
    		 Local $FileText = 0, $Dir1=0, $Dir2=0
    		 $FileText = _GUICtrlTreeView_GetText($treeview, $hItem)
    		 ;Проверка не выбрана ли корневая директория
    		 if  StringLen($FileText) >20 Then
    			   GUICtrlSetData($FileEdit, '')
    			   GUICtrlSetData($FileEdit, '//',0)
    		 Else
    			   $Dir1=StringTrimLeft (  $FileText, 5 )
    			   Local $ParentID=_GUICtrlTreeView_GetParentHandle($treeview, $hItem)
    			   Local $ParentDir= _GUICtrlTreeView_GetText($treeview, $ParentID)
    			   if StringInStr ($ParentDir,"Dir")=0 Then
    				  $ParentDir=''
    				  GUICtrlSetData($FileEdit, '')
    				  GUICtrlSetData($FileEdit, '//'&$Dir1&'/',0)
    			   Else
    				  $Dir2=StringTrimLeft (  $ParentDir, 5 )
    				  $Dir2='/'&$Dir2
    				  GUICtrlSetData($FileEdit, '')
    				  GUICtrlSetData($FileEdit, '/'&$Dir2&'/'&$Dir1&'/',0)
    			   EndIf
    		 EndIf
    		 GUISetState(@SW_SHOW, $CreateFileWin)
    	  EndIf
    EndFunc
    ;отмена создания файла
    Func onFileCancel()
    	  GUISetState(@SW_HIDE, $CreateFileWin)
    EndFunc
    ;функция создания файла
    Func onFileOK()
    	  Local $filename=GUICtrlRead($FileEdit)
    	  Local $isPrivate=_GUICtrlButton_GetCheck($privatebutton)
    	  Local $fileSize=GUICtrlRead($sizefile)
    	  $BindId=ETTokenBind($Reader[0])
    	  $Result=JCTokenLock($BindId)
    	  if $AppletID<>0 Then
    		 JCSelectApplet($BindId,$AppletID)
    	  EndIf
    	  If $Pin <> 0   Then
    		 $Result=JCTokenLogin($BindId,$Pin)
    		 If $Result=False   Then
    			$Result=JCTokenPinAttemptsGet($BindId)
    			MsgBox(0x10,$Appname,'Неверный PIN код'&@CRLF&'Количество попыток ввода PIN кода: '&$Result )
    		 EndIf
    	  EndIf
    	  Local $rootdir=ETRootDirOpen($BindId,0)
    	  Local $text=StringTrimLeft (  $filename, 2 )
    	  Local $text1=StringLeft($text, 4)
    	  $dir1=JCDirOpen(Dec ($text1), $rootdir)
    	  if $dir1=false Then
    		 $dir1= ETDirCreate(Dec ($text1), $rootdir)
    	  EndIf
    	  if StringLen($text) >12 Then
    		 $text=StringTrimLeft (  $text, 5 )
    		 $text1=StringLeft($text, 4)
    		 $dir2=JCDirOpen(Dec ($text1), $dir1)
    		 if $dir2=false Then
    			$dir2= ETDirCreate(Dec ($text1), $dir1)
    		 EndIf
    		 $text=StringTrimLeft (  $text, 5 )
    		 Local $DstFile=JCFileCreate(Dec ($text),$Dir2,$fileSize,$isPrivate)
    		 JCFileClose($DstFile)
    	  Else
    		 $text=StringTrimLeft (  $text, 5 )
    		 Local $DstFile=JCFileCreate(Dec ($text),$Dir1,$fileSize,$isPrivate)
    		 JCFileClose($DstFile)
    	  EndIf
    	  ETTokenUnbind($BindId)
    	  GUISetState(@SW_HIDE, $CreateFileWin)
    	  GUISetState(@SW_SHOW, $hParentWin)
    	  _GUICtrlTreeView_DeleteAll ($treeview)
    	  List()
    EndFunc
    ;сохранение изменённого файла на токене
    Func SaveFile()
    	  If $Pin=0   Then
    		 MsgBox(0x10,$Appname,'Для сохранения файла сначала введите пин код' )
    	  Else
    		 Local $filebody=GUICtrlRead($Edit1)
    		 Local $hItem = _GUICtrlTreeView_GetSelection($treeview)
    		 Local $FileEd = _GUICtrlTreeView_GetText($treeview, $hItem)
    		 $FileEd=StringTrimLeft (  $FileEd, 6 )
    		 Local $p=0
    		 $p=StringInStr ($FileEd,"p:")
    		 $FileEd=StringMid ( $FileEd, 1, $p-2 )
    		 Local $DirID=_GUICtrlTreeView_GetParentHandle($treeview, $hItem)
    		 Local $Dir= _GUICtrlTreeView_GetText($treeview, $DirID)
    		 $Dir=StringTrimLeft (  $Dir, 5 )
    		 $BindId=ETTokenBind($Reader[0])
    		 $Result=JCTokenLock($BindId)
    		 if $AppletID<>0 Then
    			JCSelectApplet($BindId,$AppletID)
    		 EndIf
    		 If $Pin <> 0   Then
    			$Result=JCTokenLogin($BindId,$Pin)
    			If $Result=False   Then
    			   $Result=JCTokenPinAttemptsGet($BindId)
    			   MsgBox(0x10,$Appname,'Неверный PIN код'&@CRLF&'Количество попыток ввода PIN кода: '&$Result)
    			EndIf
    		 EndIf
    		 Local $HDir=GetDir(ETRootDirOpen($BindId,0), $Dir)
    		 Local $File=JCFileOpen(Dec ($FileEd),$HDir)
    		 Local $Data =Binary('0x' & $filebody)
    		 JCFileWrite($File, $Data)
    		 JCFileClose($File)
    		 ETDirClose($HDir)
    		 ETTokenUnbind($BindId)
    		 GUISetState(@SW_HIDE, $hChildWin)
    		 _GUICtrlTreeView_DeleteAll ($treeview)
             List()
    	  EndIf
    EndFunc
    ;сохранение открытого на токене файла на компьютер
    Func SaveFileAs()
    	  Local  $varFile = 0
    	  $varFile = FileSaveDialog( "Сохранить файл", @MyDocumentsDir & "\", "Бинарные файлы (*.bin)", 16,'',$hParentWin)
    	  If StringLen($varFile) > 3 Then
    		 Local  $filedest
    		 $filedest = FileOpen($varFile, 17)
    		 ; Check if file open
    		 If $filedest = -1 Then
    			MsgBox(0, "Error", "Unable to open file.")
    			Exit
    		 EndIf
    		 FileWrite($filedest, $text)
    		 FileClose($filedest)
    	  EndIf
    EndFunc
    ;Обработка команд меню окна просмотра и редактирования файла
    Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg, $lParam
        Switch $wParam
    	  Case $Save
                SaveFile()
    	  Case $idSave
                SaveFileAs()
        EndSwitch
    EndFunc   ;==>WM_COMMAND
    ;инициализация графического интерфейса
    Func GUIInit()
    	  $hParentWin=	GUICreate($Appname, 560, 400)
    	  GUISetOnEvent($GUI_EVENT_CLOSE,'onClose')
    	  ;Создание главного окна
    	  $treeview = GUICtrlCreateTreeView(6, 6, 400, 300, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
    					 $Output = GUICtrlCreateEdit("" , 6, 320, 400, 70, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_NOHIDESEL + $ES_WANTRETURN)
    					 $pinbutton = GUICtrlCreateButton("&Ввести PIN код", 430, 20, 100, 50)
    					 $filebutton = GUICtrlCreateButton("&Создать", 430, 80, 100, 50)
    					 $deletebutton = GUICtrlCreateButton("&Удалить", 430, 140, 100, 50)
    	  ;Создание окна ввода пин кода
    	  $hPinWin = GUICreate('Введите PIN код', 200, 200, -1, -1, $WS_SYSMENU, -1, $hParentWin)
                        $PinEdit = GUICtrlCreateInput ("" , 50, 40, 100, 25, $ES_PASSWORD + $ES_NOHIDESEL + $ES_WANTRETURN)
                        $pinokbutton = GUICtrlCreateButton("&OK", 20, 100, 60, 40)
                        $pincancelbutton = GUICtrlCreateButton("&Отмена", 110, 100, 60, 40)
    	  ;Окно создания файла
    	  $CreateFileWin = GUICreate('Создание папок и файла', 340, 350, -1, -1, $WS_SYSMENU, -1, $hParentWin)
                        $FileEdit = GUICtrlCreateInput ("" , 50, 70, 230, 25)
                        $fileokbutton= GUICtrlCreateButton("&OK", 70, 240, 60, 40)
                        $filecancelbutton = GUICtrlCreateButton("&Отмена", 210, 240, 60, 40)
                        $publicbutton= _GUICtrlButton_Create($CreateFileWin, "Public", 100, 120, 50, 30,  $BS_AUTORADIOBUTTON, 0)
                        $privatebutton=_GUICtrlButton_Create($CreateFileWin, "Private", 160, 120, 50, 30,  $BS_AUTORADIOBUTTON, 0)
                        _GUICtrlButton_SetCheck($publicbutton,  $BST_CHECKED)
                        Local $label=GUICtrlCreateLabel('Введите имя папок и файла в hex формате 1001 ', 70, 20, 170, 40, $SS_CENTER)
                        $sizefile = GUICtrlCreateInput ("10" , 220, 175, 50, 20)
                        Local $label1=GUICtrlCreateLabel('Введите размер файла в байтах', 20, 180, 200, 60, $SS_CENTER)
    	  ;Окно редактирования файла
    	  $hChildWin = GUICreate($sItemText, 300, 230, -1, -1, $WS_SYSMENU, -1, $hParentWin)
    				    $Edit1 = GUICtrlCreateEdit("", 10, 10, 240, 160, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_NOHIDESEL + $ES_WANTRETURN)
    	  ; Создаёт меню "Файл" в окне редактирования файла
    	  $hFile = _GUICtrlMenu_CreateMenu ()
    	  _GUICtrlMenu_InsertMenuItem ($hFile, 0, 'Сохранить как...', $idSave)
    	  _GUICtrlMenu_InsertMenuItem ($hFile, 1, 'Сохранить изменения', $Save)
    	  $hMain = _GUICtrlMenu_CreateMenu ()
    	  _GUICtrlMenu_InsertMenuItem ($hMain, 0, 'Файл', 0, $hFile)
    	  _GUICtrlMenu_SetMenu ($hChildWin, $hMain)
    	  ;Определение событий
    	  GUICtrlSetOnEvent($filebutton,'onFileCreate')
    	  GUICtrlSetOnEvent($deletebutton,'Delete')
    	  GUICtrlSetOnEvent($pinbutton,'onPin')
    	  GUICtrlSetOnEvent($pinokbutton,'onPinOK')
    	  GUICtrlSetOnEvent($pincancelbutton,'onPinCancel')
    	  GUICtrlSetOnEvent($fileokbutton,'onFileOK')
    	  GUICtrlSetOnEvent($filecancelbutton,'onFileCancel')
    	  GUISetOnEvent($GUI_EVENT_CLOSE,'onClose')
    	  GUISetState(@SW_SHOW, $hParentWin)
    	  GUIRegisterMsg(0x0111, "WM_COMMAND")
    EndFunc
    ;запуск основных функций приложения
    GUIInit()
    List()
    ;функция обработки двойного щелчка мышью на дереве файлов и директорий
    GUIRegisterMsg($WM_NOTIFY, "MY_WM_NOTIFY")
    Global $iDoubleClick = 0
    Func MY_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
        Local $tagNMHDR, $vEvent
        Switch $wParam
            Case $treeview
                $tagNMHDR = DllStructCreate("int;int;int", $lParam)
                If @error Then Return
                $vEvent = DllStructGetData($tagNMHDR, 3)
                If $vEvent = $NM_DBLCLK Then
                    $iDoubleClick = 1
                EndIf
        EndSwitch
        $tagNMHDR = 0
    EndFunc  ;==>MY_WM_NOTIFY
    ;функция поиска директории, в которой кликнули по файлу
    Func GetDir( $Id,$Dir_Id)
    	  Local $DirId=0
    	  Local $DirResult=0
    	  Local $EnumId=ETDirEnumOpen($Id)
    	  While 1
    		Local $dir=ETDirEnumNext($EnumId)
    		If @error Then ExitLoop
    			$DirId=ETDirOpen($dir,$Id)
    			if hex($dir,4)=$Dir_Id Then
    			   $DirResult=$DirId
    			   ExitLoop
    			EndIf
    			$DirResult=GetDir( $DirId, $Dir_Id)
    			ETDirClose($DirId)
    	  WEnd
    	  ETDirEnumClose($EnumId)
    	  Return  $DirResult
    EndFunc
    ;функция открытия файла на токене и вывода его содержимого в дочернее окно
    Func ListFile($file, $Dir_Id)
    	  $BindId=ETTokenBind($Reader[0])
    	  $Result=JCTokenLock($BindId)
    	  if $AppletID<>0 Then
    		 JCSelectApplet($BindId,$AppletID)
    	  EndIf
    	  If $Pin <> 0   Then
    		 $Result=JCTokenLogin($BindId,$Pin)
    		 If $Result=False   Then
    			$Result=JCTokenPinAttemptsGet($BindId)
    			MsgBox(0x10,$Appname,'Неверный PIN код'&@CRLF&'Количество попыток ввода PIN кода: '&$Result )
    		 EndIf
    	  EndIf
    	  if StringLen($Dir_Id)>10 Then
    		 $HDir=ETRootDirOpen($BindId,0)
    	  Else
    		 Local $HDir=GetDir(ETRootDirOpen($BindId,0), $Dir_Id)
    	  EndIf
    	  $SrcSubId=JCFileOpen(Dec ($file), $HDir)
    	  $text=JCFileRead($SrcSubId)
    	  GUICtrlSetData($Edit1, hex($text))
    	  JCFileClose($SrcSubId)
    	  ETDirClose($HDir)
    	  ETTokenUnbind($BindId)
    EndFunc
    ;обработка двойного щелчка мышью и получения имени файла на токене
       While 1
          if $iDoubleClick Then
    		 Local $hItem = _GUICtrlTreeView_GetSelection($treeview)
    		 if _GUICtrlTreeView_GetChildren($treeview, $hItem)=False Then
    			Local $hItem = _GUICtrlTreeView_GetSelection($treeview)
    			$sItemText = _GUICtrlTreeView_GetText($treeview, $hItem)
    			if StringInStr ($sItemText,"Dir")=0 Then
    			   Local $text1=0
    			   $text1=StringTrimLeft (  $sItemText, 6 )
    			   Local $p=0
    			   $p=StringInStr ($text1,"p:")
    			   $sItemText=0
    			   $sItemText=StringMid ( $text1, 1, $p-2 )
    			   GUISetState(@SW_SHOW, $hChildWin)
    			   GUISetOnEvent($GUI_EVENT_CLOSE,'onClose')
    			   Local $DirID=_GUICtrlTreeView_GetParentHandle($treeview, $hItem)
    			   Local $Dir= _GUICtrlTreeView_GetText($treeview, $DirID)
    			   $text1=StringTrimLeft (  $Dir, 5 )
    			   $Dir=$text1
    			   ListFile($sItemText, $Dir)
    			EndIf
    		 EndIf
    		 $iDoubleClick = 0
         EndIf
       WEnd
    


    Sources of information

    eToken Developer's Guide Version 3.50 (December 2003)

    Also popular now: