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
Sources of information
eToken Developer's Guide Version 3.50 (December 2003)
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)