Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

4 Neutral
  1. Okay, fine, as already said, I will do that. I hereby declare this thread to be closed 🙂
  2. Yes, absolutely, I wanted to close this issue here, anyway. Is there an option where I can close it or does it have to be closed by a moderator or administrator?
  3. Okay, so here for the next steps: Solving potential issues also for the 32- and 64-bit versions of the FilesCollector and compiling it (PoC) Check whether I really need the DLL and can pull all into one single EXE file without complications Get an overview of Strings, AnsiStrings, WideStrings, and Unicode Modify the "compressed layout" of the window to a better readable UI(X) and recompile the entire HL7-Server Suite in both (x86 and x64) flavours Get a certificate for my software projects Test: Compression and obfuscation (just "at home" for learning purposes) Test: Product registration (just "at home" for learning purposes) I will keep you in the loop. And, once again, I want to thank you all, but especially @Kas Ob. and @aehimself, for the wonderful and utterly friendly help you have provided me to handle all this within just a few days. Thus, I have had the chance to learn incredibly much incredibly fast which I now have as a basis for further code development in Delphi and, similarly, other coding languages. This has been a wonderful start into the New Year which, of course, I would like to wish you all belatedly. And if you permit me to come up with a few other questions when they arise, I would be very happy, indeed.
  4. Now I have both 32- and 64-bit applications running on selectively different ports (which makes no sense, port 3000 is the real one in use by my software from 2010, ports 3001 (HL7SocketCollector x86) and 3002 (HL7SocketCollector x64) have been activated for testing purposes only. For this I had to create a different (for purposes of differentiation) ODBCname in both the ODBCad32.exe in the System32 and the SysWOW64 directory of Windows. See the promised screenshot:
  5. Due to you help, dear friends, I have been successfully able to create both x86- and x64-applications under the original scheme (EXE and DLL) - I have taken the latest source code I could find, associated the files to each other which, version-wise, belonged to one another, and compiled them. There have been some string warnings so far, but none of them hindered compiling. The port is detected correctly, and data can be transferred using the "HL7Sender" test program (I will show you a screenshot in a minute). But as I now want to professionalize the software development process and cycle, I want to do 4 things: Check the "pristineness" of my software on systems such as Virus Total - done. Enter my "Details" and Copyright data in the "Version Info" - done. Generating a md5 hash to identify the authenticity of my software - how can I do this? By using an external tool? Get a certificate to identify myself as the software originator - is there one which you can recommend? Furthermore, there are another 2 thoughts I wanted to ask you about: Does it make any sense to compress the EXE using EXE obfuscator or security tools such as UPX or ASPack? Size-wise it is no longer needed, and it surely will not optimize the execution speed of the program itself or the inner processing of data. So what could be a reason to still do it? Does it make sense to have the software provided with a registration or licence key? My setting is that a clinic receives a full virtual software appliance with everything preinstalled or I copy the programs' installer onto the virtual appliance and run it there - per se there is no need for a license file as it is absolutely clear and well-documented where I put my HL7 software (and also the PHP App Suite) on. It is, to be honest, more an emotional question for me as I always wanted to try this out (no need for me, historically, to do that for LISP or PROLOG programs in an academic setting, of course ...). So, just in case I still want to try this out, is there a good solution you might recommend to me?
  6. Yes, thank you, a certificate is exactly what I want to turn to once the software is in action. Meanwhile, I have scrutinized the other *.exe files from 2010 and 2011 none of which has BobSoft in it any longer. We then either did not crypt the code or the *.exe files any longer or used tools such as the mentioned ASPack 2.12. I am fully aware of your concern regarding the safety and security but also the "open information strategy" regarding good proprietary software. Nonetheless, even a certificate nowadays, and also 10 years back at Stuxnet times is no longer any guarantee that nothing happens, but people at least can observe your willingness to be on the white and neither the grey nor black side of coding. I will crack on now compiling ... 🙂
  7. Look what I just detected: Although we had decided in 2010 to buy and use ASPack 2.12 to pack our even then rather larger EXE files, one of my 2 Delphi coders used Bobsoft Mini Delphi ... something I had no idea of until this very day (as you may know, this obfuscator / cryptor has become rather "famous" during 2018 and 2019 as it had been used to stealth some RATs active especially in Europe). Maybe that is the reason why the old but running Socket Collectors from 2010 show a 1/70 on VirusTotal ... And even if it is only 1/70, this means that the 3 different Socket Collector versions - I have checked only one so far with Exeinfo PE and PEiD -, up to now, have been FUD ... 😐
  8. To give you a picture of the whole meaning why this tiny little wee Delphi application is so outstandingly important:
  9. I fully agree to omitting the above-mentioned aspects which have nothing to do with the Delphi application regarding its "sniffing" activity and getting data in the right format. However, I usually try to be as thorough as possible when it comes to describing the entire context. I did not have time enough to describe the "DLL incident" 😉 any longer as I had to give my lecture at 11 AM. The DLL, back in 2010, was implemented because the original programmer, son of the then director of the "Institution of Informatics" at the University of Moscow, came to Germany with the Russian teaching then that considerable aspects of a software should be exported into a DLL. He also told me that some of the there-in contained code will get executed only later when needed. Since in those times we did not know which volume of data we had to deal with in the first place, we thought "DLL-outsourcing" the parsing process might be a good idea ... Personally, I am completely "emotionless" regarding the use of a DLL. Actually, that was to be one of my next steps, anyway, to get rid of the DLL as I do not like them very much. However, please bear in mind that I have been able to initially handle all this by means of your helping me only since yesterday and that my prior goal and "what we have agreed on here" was to do things step-wise. And this is exactly what I have followed. In other words: I have not been able time-wise to touch the DLL issue and ask you another question whether it would actually be needed in the first place and, therefore, all the code should not better be incorporated in one single EXE file. 🙂
  10. I am starting a lecture right now, so I do not have the time to depict it differently, so here just some plain words: An "integration server" receives specific data records about one single patient from its "clinical information system", it transforms, for instance, a data record from an ORACLE database into a single ADT message (thus generates ASCII text) and sends this ADT message to port 3000. My Delphi application "sits" on port 3000 and listens to what comes in. If what comes in is a parsed-as-valid ADT message, it sends back an ACK signal, extracts the individual elements from the ADT message into single items which then are saved into a MySQL (or MSAccess or MSSQLServer or PostGreSQL etc.) database table, in our context in a MySQL database; if the ADT message is malformed or not an ADT message at all (theoretically possible), the message or whatever it might be is rejected, a NOACK signal is sent, and the content is being saved in a different MySQL database table. Basis for the interaction between my Delphi application and the MySQL database is the ODBCname definition (cf. screenshot) Users, on the other hand, have exclusive access to the database via my Mazimoi ODS suite handled by PHP code, they see nothing of that "port 3000 sniffing and data handling" process. They either see the patients in the MySQL database table or they do not see them because, for example, the "integration server" was offline or the patient's data record in the "clinical information system" has been deleted or disactivated. The "Python script" and "Other sources" are not in that concept. The Python script was a quick hack 4 days ago to see whether my Windows 10 Pro system was able to handle sockets because I had hardened my Windows about a month before and feared that this might have had an influence on ports. I never used this Python script before, it was just a PoC. If you read my 5 bullet points "from left to right" then you see the direction. If you see your "Delphi application" sitting in the middle, then the picture is not right: The Delphi app (DA) communicates with the MySQL database via 32-bit-ODBC, correct. "Other sources" could be the "integration server" (IS), yes, but then the communication between IS and DA is mediated over the port 3000. The "PHP application" (PA) using a "WebUI" only communicates with the Database (using mysqli or PDO), there is no connection to the DA whatsoever. The DA is merely used to evaluate and store the IS-sent ADT messages in the MySQL database. PA and DA never see each other, PA merely sees DA's results as data record entries in the MySQL database.
  11. No, meanwhile the port problem is fixed. I had to do with the Palette icons not dropped onto the FormMain.dfm. Now that works well. Nah. I had used that Python server- and client-connection test script to see whether I had a WinSocket problem due to previous Windows hardening in the first place. This was not the case, and I could prove that by opening a Python server port (3000) and listening for a Python client connection to this port which worked flawlessly. So the Python "thingy" was just to test whether I can open and serve a port. Thank you, @aehimself, for mentioning the need to depict a workflow. The program's workflow is as such: My very large PHP-MySQL-JavaScript-XML-based suite called "Mazimoi ODS" can either create a new patient data record manually (there is a PHP-HTML form for that) or ... automatically scan for so-called ADT messages from the HL7 standards versions 2.2 to 2.5 (https://www.hl7.org/ and https://en.wikipedia.org/wiki/Health_Level_7) ... on port 3000 to which a so-called Data Exchange Integration Server (DEIS) sends these ADT messages as the result of the conversion of proprietary data from a clinical information system (CIS) which are often ORACLE-based. My software which I call "Mazimoi HL7 SocketCollector" basically "sniffs" for such ADT messages on port 3000 (agreed upon between DEIS and my software, it could be any other unoccupied port). Before that, it checks whether there is a valid ODBC name installed which you need a MySQL ODBC Connector version 3.x to ideally 5.x set up and running (32-bit also on 64-bit Windows [Windows -> SysWOW64 -> odbcad32.exe -> SystemDSN), if that is not the case, you will receive a Windows error message. The DLL file contains the parsing rules for detecting whether the ADT message is "in good shape" or has formal issues. Thus, when an ADT message (typically A01, A04, A08, P01, R01 ...) arrives at port 3000, this message is parsed. If the parsing does not reflect any formal issues, my software sends an "ACK" to the DEIS telling it that this ADT message has been acknowledged positively. In this case, the data contained in the ADT message (ASCII) is being extracted from the message (cf. an example message format below) and saved in the table "hl7_messages" in the database "adipositas" to be requested by an import step from within Mazimoi ODS (the user searches for a patient's known ID or her / his last or first name, gets the result list of potential patients and then may choose one to take over into the main system). If the parsing finds formal issues, a "NOACK" or "NO_ACK" is sent to the DEIS telling it that the message was rejected, and consecutively such rejected data is being saved in the table "hl7_messages_noack" in the database "adipositas" (within 9 years of running Mazimoi ODS using my "Mazimoi HL7 SocketCollector" not a single data record has been saved there as "NOACK" or "NO_ACK" in the context of roughly 22.5 million single ADT messages). The ADT messages are plain ASCII files delimited by a "|" separator - the only art here is to count the right position of the "field" transferred which is basically clumsy and error-prone, but the advantage is you can deal with a text file and do not need to decode something format-proprietary again. Here is an example if such ADT messages (all in German, but these messages can be internationalized according to the HL7 standards): MSH|^~\&|DPS||MANATHEA|3|201206250200||ADT^A01|1522464|P|2.2|||AL|NE EVN|A01|20120625020049 PID||CMM04069327|10024397|31210357|AAAAAA^BBBBBB||19930604000000|M|||fffffffff 36^^dddddd^^34127^D|06611000|0561/5299887||D||||||||dddddd|N||D PV1||O|3INAMB^^^3INN||31210357|||||||||||||ANOT|31210357||K||||||||||||||||||3922200|||||20120625020000|20120630235900|||||31210357 MSH|^~\&|MCCGateway|200^0001|KIM|Test1|20040603065933||ADT^A01|999999|P|2.2 EVN|A01|20040603065933|||NP4000 PID|2||0000176633||Pirner^Hans^Herr^^^|Pirner|19370506|M|||Albert Reichstr. 1^^Neumarkt^^92318^DE||||D|||||||||||| PV1|2|O|AM-NOTAU^^^FA-NOTAU^|AM|||^^^^^^^^^^^^^|^^^^^^^^^^^^^|^^^^^^^^^^^^^~~~|AMB|||||||||01168880||K||||||||||||||||||FA-NOTAU|||| |20040603065600||||||00001^^^^4 NK1|2|Pirner^^^^^||Albert Reichstr. 1^^Neumarkt^^92318^DE|||0 IN1|2|0004003230|0105830016^^^|TAUNUS BKK|Heidelbergerstr.14^^Darmstadt^^64283^DE||0180320220400|||||19370506|99991231||R|^^^^^|||^^^^^|||01||||||||||||||0595394007||||||| IN1|3||^^^||^^^^^|||||||19370506|99991231|||^^^^^|||^^^^^|||99||||||||||||||||||||| MSH|^~\&|GAPIT|GAPIT|CLOVER|CLOVER|20090610124829^YYYYMMDDHHM||BAR^P01||P|2.2|||NE|NE EVN|P01 PID|1|0001280539|0001280539||Mustermann^Max^^^Herr||19550122|M|||Musterstraße 6^^Musterstadt^^93053^DE||462410|||vh|RK|||||||||DE|J PV1|1|O|Amb_ADI^^^A_Chirurgie^^N|VorstatBeh||^^^^^N|^^^^^|993110801^Pache^Ulrich^^^Dr. med.^^LANR^^^^^^658039900|993110801^Pache^Ulrich^^^Dr. med.^^KVNR^^^^^^|Vorstat||J|||||^^^^^||2118733^^^Ein1^VN|Standard||||||||||||||||0401|||||AB|||20111212125900|20111212163113||||||| PV2|1|S|||||||||||||||||0029096978OBX|1||Vorerkrankung||? OBX|3||Diagnoseanlass||Eigenuntersuchung OBX|4||Erstdiagnosedatum||31.12.2007 OBX|5||AufklĂ€rung||N DG1|1|IC|C48.2 ^^ICD10SGBV_20||20090513082000||||||||||2|Bösartige Neubildung: Peritoneum, nicht nĂ€her bezeichnet PR1|1|OP|3-222||2009051409500000|I|1|||||||2 ORC||C 2009006167-01|C 2009006167-01||CM|||||Pathologie|Pathologie|0000933018|||20090810000000|||PAT_BEFUND^001| OBR|1||C 2009006167-01|||||||||||20090806153300||||||||20090807133600||||||||||hm| OBX|1|FT|PATHOLOGY^Pathologiebefund||C_2009006167-01.pdf|PDF|Tester, Karl, 30.01.1999\.br\Material: Urin\.br\\.br\9 ml gelbe klare FlĂŒssigkeit.\.br\\.br\Zytologisch im Zytozentrifugat einzelne urotheliale Schirmzellen sowie\.br\vereinzelt Urothelien aus tieferen Zelllagen, teils mit geringer\.br\KerngrĂ¶ĂŸenvariation. Einzelne Plattenepithelien aus oberen Zelllagen.\.br\PrĂ€zipitate eines fĂ€digen und fein granulĂ€ren Materials.\.br\\.br\Kritischer Bericht:\.br\\.br\Es handelt sich um einen sehr zellarmen, zytologisch negativen Urin\.br\(kein Tumorzellnachweis).\.br\\.br\\.br\\.br\\.br\\.br\Prof. Dr. med. T. RĂŒdiger\.br\\.br\Dieser Befund wurde qualifiziert elektronisch signiert und ist somit\.br\ohne Unterschrift gĂŒltig.\.br\| OBX|2|FT|PATHOLOGY^KRBW||C_2009006167-01.XML|XML|| Short legend: Each element between 2 "|" has a potential meaning. If there is no such "content", i. e. "||" or even "|||||||||||||", that means that there is no such content or that an existing content has not been transformed. Every new message starts with a "MSH". The first line starting with "MSH" ("medical subject header") tells me what this is all about - for instance, take a look at the second example, the name of the sender software ("MCCGateway"), the ADT message type ("ADT^A01") and he used HL7 version ("2.2"). The first elements on a new line determine the "originating section" meaning the context where this specific information arose in the CIS and needs to be imported logically into the subsequent systems (e. g. mine). Another art here is to see that some systems say they are using version 2.2 of the HL7 specification when in reality they use e. g. version 2.3, but this can easily be detected within the parsing process described and is of no higher importance. Additionally, there are specialized segments in such ADT messages which can be separately defined, for instance in "OBX segments" where some not routinely available information is saved to. This is as well not an issue since the preceding identifier is always "OBX". Again, this is just for explaining. And finally, there are "verncaculars" or "dialects" of HL7 interpreted by each generating system or DEIS as part of a tiny wee proprietary strategy, but this is seldom the cause of any ACK errors. In conclusion, "Mazimoi HL7 SocketCollector" is a regular and legal "port sniffer" for HL7 ADT messages, parses and accepts or rejects them according to "well-formedness", and saves the acknowledged message in a MySQL table "hl7_messages" (in case of failure "hl7_messages_noack") in the database "adipositas". Of course, port, table and database names are arbitrary and just need to be defined. Last, not least: There is also a "Mazimoi HL7 Files Collector" for those systems which prefer to send ADT messages as single files, but it has become clear during the last 10 years that almost no one uses this way to hand over information (this software checks for the new = most recent arrival of files in a certain directory and then starts the basically same parsing process). And, additionally, there is also the same software not for HL7 but for CSV data (socket collector) or files (files collector), but, again, this has not been in use much and is similarly structured to the HL7 source code. So, if I ever wanted to bring this to new life, I must have fixed the HL7 software issue. Now you should have a complete overview with necessary and unnecessary but context-relevant bits of information.
  12. The 2 following screenshots are made from a recompilation of the original code without any string conversion (, i. e. the original unmodified code).
  13. The 2 following screenshots are made from a recompilation of the original code after automatic string to AnsiString conversion. My next message will contain the difference from the original code without that conversion.
  14. Another question: Would it be helpful for all of you who have intended to help and support me to take a quick look into ... the working *.exe and *.dll from the live system, compared to the freshly RAD Studio 10.3.3 CE-compiled *.exe and *.dll from the D7 / D2007 sources, compared to the freshly RAD Studio 10.3.3 CE-compiled *.exe and *.dll from the modified D7 / D2007 sources? I will put them all into separate ZIP files (containing the *.ini file and the latest MySQL 5 ODBC driver 5.3.14) on a Google Drive folder and give you the link here ... https://drive.google.com/drive/folders/1xR5u0KIJe_w9R9SSMffyIHUnN-jae7rI?usp=sharing ... for your convenience.
  15. I think you by now can see the difference or if you already have a code working on D2010 then compare string handling parts, which is a process might be five minutes or 5 days. [...] Thank you so much for taking that much time for an explanation of my "uneducated" questions. My primary programming experiences in "languages for medicine" such as LISP and PROLOG had given me a different style of thinking and handling code, and script languages did not enhance this process. I find it relatively easy to "read" someone else's PHP or Python code and follow what the code is about to do, whereas in Delphi, C++ and C# this process is much harder for me ... I am sorry for that, but as I stated yesterday already I have learnt a great lot from your pointing me to do the right thing. Maybe I can give that back one day ...