Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation


About Mefistotelis

  • Rank
    More Active

LabVIEW Information

  • Version
    LabVIEW 7.0
  • Since

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. pylabview could do it, but it looks like there are differences in "Virtual Instrument Tag Strings" section, and the parser can't read that section ATM: So - only NI can help you, unless you are willing to help in development of pylabview.
  2. Front Panel is now proper XML (though I only support "FPHb" now, older Labview has FPHP instead, and latest ones use FPHc - those are not parsed, as I don't really need them for my use). Block Diagram is stored in exactly the same way, so I got "BDHb" support for free. I used the same general format LabVIEWs NED uses for XML panels. I can now either work to read "DFDS" section as well - it's quite complex as it isn't stand-alone section, meaning it needs data from other sections to parse. Or I can ignore default data, and start working on Front Panel re-creation without that.
  3. Working on Front Panel now. This is what pylabview generates: <?xml version='1.0' encoding='utf-8'?> <SL__rootObject ScopeInfo="0" class="oHExt" uid="1"> <root ScopeInfo="0" class="supC" uid="10"> <objFlags ScopeInfo="1">010000</objFlags> <bounds ScopeInfo="1">0000000000000000</bounds> <MouseWheelSupport ScopeInfo="1">00</MouseWheelSupport> <ddoList ScopeInfo="0" elements="61"> <SL__arrayElement ScopeInfo="1" uid="64" /> <SL__arrayElement ScopeInfo="1" uid="96" /> And this is the same part generated by NED within LabView: <SL__rootObject class="oHExt" uid="1"> <root class="supC" uid="10"> <objFlags>65536</objFlags> <bounds>(0, 0, 0, 0)</bounds> <MouseWheelSupport>0</MouseWheelSupport> <ddoList elements="61"> <SL__arrayElement uid="64"/> <SL__arrayElement uid="96"/>
  4. While I'm still working on parsers for all types of VI connectors, I also noticed the VICD block. Some old articles on its content: https://web.archive.org/web/20110101230244/http://zone.ni.com/devzone/cda/tut/p/id/5315 https://web.archive.org/web/20120115152126/http://www.ni.com/devzone/lvzone/dr_vi_archived6.htm Not sure if I'll be decoding that section further though - I believe the connectors block and default data block will be the only ones required to re-create front panel. The binary format of Front Panel should be easy to figure out by comparing binary data to the XML representation which can be generated in newer LV versions; anybody tried that?
  5. I need some example files to test my tool. I am running it on all the LV14 standard VIs, but it looks like these are not using all possible features of the VI format. In particular, I am not seeing use of some Refnum connectors. For example the type which 'Vi Explorer' calls "queue". Anyone knows what to click in LabVIEW to get such connector within the VI file? EDIT: Forced myself to read LabView help, now I know how the Queue works. Still didn't found some refnums in documentation, ie. Device Refnum.
  6. On linux, you may just use ldd: $ ldd my_binary Or if the loader refuses to run it on current platform, but you still need to know: $ readelf -d my_binary For Windows - there are tons of "PE Viewers" and "PE Explorers" which lets you look at import table.
  7. I don't think I can be completely convinced to your point: I agree refactoring LV doesn't make sense now, but I think something should've been done years ago to allow the support. Even if no conversion was done at a time, as soon as multi-lingual versions of Windows and Mac OS started popping out, it was obvious the conversion will be an issue. I'm not talking there should be a conversion right away, just that even then, it was obvious that storing just the information which code page is in use, would be a prudent choice. Now for really implementing the conversion: It wouldn't be needed for the OS to support anything - `libconv` can be compiled even in Watcom C (I'm not stating libconv should have been used, only stating that doing codepage conversion even in DOS was not an issue). Around 1994, I wrote a simple code page conversion routine myself, in Turbo Pascal. Not for unicode, it converted directly between a few code pages, with a few simple translation tables. It also had a function to convert to pure ASCII - replace every national character with the closest english symbol (or group of symbols). That would be good enough support for pre-unicode OSes - it wasn't really necessary to support all unicode characters, only to allow portability between platforms which LabVIEW supported. Finally, I don't think LabVIEW uses native controls (buttons etc.) from the OS - it treats the native window as a canvas, and draws its own controls. So support on of multi-lingual text in controls is not bound to the OS in any way. For implementation details within LabVIEW: That would be more tricky, and I understand possible issues with that. LabVIEW operates on binary data from various sources, and if the VI tells it to print a string, it doesn't keep track whether that string came from the VI and has known code page, or come from a serial port with a device talking in different encoding. There are still ways to solve such issues, just not completely transparent for the user. Plus, most string used in user interface are not really changing at runtime. I didn't actually knew that LabVIEW is considered "classic" version and is being replaced by NXG. That is strong argument against any refactoring of the old code. The conversion I introduced to my extractor works well, so this shouldn't be much of an issue for me.
  8. Great overview, thank you. What LabVIEW could have done is just storing the information about code page used for the VI. That would then allow conversion when the sting is displayed on screen, if necessary. But since there's no info on codepage within the VI, I implemented it as a parameter (the tool I made exports VI to XML and within the XML the encoding is UTF-8) : https://github.com/mefistotelis/pylabview/blob/master/README.md#text-code-pages I think if you don't live in western country, you might have different view on that. Even if the 90% statistics is true (it sounds iffy to me, but I have no data to subvert it), people from other countries probably mostly see VIs created near them. I've seen a lot of VIs with asian language, probably Chinese. I can't even read the alphabet, so can't tell for sure which code page is there. Sometimes when there's longer description, I can just check with Google translate; but there are often 1-2 words only, ie. in names of interfaces. The translator then either gives something plausible for many code pages, or non-technical term for all of them. When I get connector name and see "stick noodles" for Chinese translation (w/ their code page), and "fluffy neckcloth" for Japanese (w/ their code page), I still can't tell the origin of that file. Nor what the connector does. (I never got these specific words, but what I got wasn't very far). Anyway, there's a lot of people in China. And a lot of factories, which do semi-automated Quality Assurance. Such tasks might be often handled with help of LabVIEW.
  9. On LabView 2014, I see that my VI files happily store strings using current OS (testing on Windows) code page. I assume there's no conversion mechanism, and if I use the VI on another OS, or just different language Windows, I will get unreadable mish-mash instead of the proper text? Is that fixed in LV 2019, or do NI still avoid UTF? I realize this is not an issue, or at least minimal issue, when you describe things in english and avoid using ascii codes > 127. (though note that even original LV libraries contain OS-specific char codes, mostly a special variants of apostrophe and minus/pause: ` and -. I though the world has finished moving to unicode more than 15 years ago... EDIT: Verified on Windows with different language. I do get invalid characters. There is no conversion, LabView just tries to print the characters using current Windows code page, resulting in garbage. How this is still an issue today? I need to provide the ability to set code page as input parameter to my VI reader. EDIT2: Now i know everything I need - see "Character Code Issues" chapter: http://zone.ni.com/reference/en-XX/help/372614J-01/lvconcepts/porting_among_platforms/ It's funny how lack of proper string conversion is called "compatibility feature". Reading the chapter gives you a feeling that LabView supports the conversion whenever possible, but it doesn't seem to be the reality.
  10. Nope. that's not what I found. You're right with ButtonsHidden field being an integer which bits correspond to something (I assume visibility of some buttons), but sr_field22 turned out to be something else - the type of VI. This type is actually part of LV documentation: https://zone.ni.com/reference/en-XX/help/371361R-01/lvprop/vi_vi_typ/ I already did proper renaming in my code. There seem to be many properties which I could find in code based on the documentation (click "VI Properties" in the link above to see them). Below, they are listed with "property ID" of each - will check whether this can provide me with some more field names: https://labviewwiki.org/wiki/VI_class
  11. A good example I just found: void InitButtonsHidden(INSTRUMENT **a1) { (*a1)->sr_field14 = gButtonsHidden[(*a1)->sr_field22]; } Now we can rename one field to 'buttonsHidden', and can assume another field contains enum value representing either state or type.
  12. You are completely right with the assessment of what this function does. But I can't agree it is unexciting: - It provides us with full information on how to divide the LVSR block into single values, and it even names one of the values. - It gives us offsets within INSTRUMENT where each value is stored, so that we can cross-reference it with other functions and check what they do (as you see, I already named the items within INSTRUMENT to "sr_field*" so that I can easily search ehere each of these is used further. So actually, almost everything about LVSR which is in my code, comes from this single function: https://github.com/mefistotelis/pylabview/blob/master/LVblock.py#L100 Thanks! I actually downloaded that whole FTP already; and yes, this is where I got LV3.1.1 from. There are 2 binaries - Win16 and WinNT; the WinNT one is better for analysis. But, as I previously stated - before LV6.0, the blocks within VI files were a bit different - so I prefer to work on more recent code. As an example, in LV5.0 there was LVIN block instead of the LVSR discussed above.
  13. I got a 3.5 inch floppy drive with USB interface - they were very cheap at some pint. Anyway, I browsed through various releases available in obscure places of the web. There's A LOT of things created by NI which either use the standard LV runtime environment, or use parts of the LV code. I downloaded > 100GB of various files when I decided it's time to stop. There was probably way more to find, but I have to limit my time. Findings: - Files from Windows platform are the worst port to reverse engineer, mostly because Windows libraries (.DLL) define exported routines explicitly. - UNIX base releases (solaris,linux) are the best to debug - compiled for popular CPU architectures, and shared libs (.SO) have all routines exported - meaning their names are retained - For some obscure platforms, I found static libraries (.a/.lib) files included in the release. These have the most info on source code retained, but not the whole code was in that form. Not the part I need anyway. - The best version to focus on seem to be LV6.0 - the code is a lot less bloated than in newer releases, and the core of the tool didn't seem to have changed much since that release (though I didn't found much LV5.0 releases - I can tell 4.0 is too old and does not have many blocks which exist in modern VI files, for 5.0 - I'm not sure) Here's the loading of LVSR block in LabView 6.0. Unfortunately, I still don't have struct definitions. But at least I know how the structs are named, thanks to C++ name mangling. void RToVI(SAVERECORD **sr, INSTRUMENT **instr) { char fld10a; char fld10b; INSTRUMENT *dInstr; int state; (*instr)->sr_field4 = (((*sr)->field_4 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_4 >> 24) | (((*sr)->field_4 & 0xFF00) << 8) | ((*sr)->field_4 << 24); (*instr)->sr_field8 = (((*sr)->field_8 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_8 >> 24) | (((*sr)->field_8 & 0xFF00) << 8) | ((*sr)->field_8 << 24); (*instr)->sr_fieldC = (((*sr)->field_C & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_C >> 24) | (((*sr)->field_C & 0xFF00) << 8) | ((*sr)->field_C << 24); (*instr)->sr_field12 = _byteswap_ushort((*sr)->field_12); (*instr)->instrState = (((*sr)->instrState & 0xFF0000) >> 8) | ((unsigned int)(*sr)->instrState >> 24) | (((*sr)->instrState & 0xFF00) << 8) | ((*sr)->instrState << 24); (*instr)->sr_field14 = _byteswap_ushort((*sr)->field_14); (*instr)->sr_field16 = _byteswap_ushort((*sr)->field_16); (*instr)->sr_field20 = _byteswap_ushort((*sr)->field_20); (*instr)->sr_field22 = _byteswap_ushort((*sr)->field_22); (*instr)->version = (((*sr)->version & 0xFF0000) >> 8) | ((unsigned int)(*sr)->version >> 24) | (((*sr)->version & 0xFF00) << 8) | ((*sr)->version << 24); (*instr)->sr_field24 = (((*sr)->field_24 & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_24 >> 24) | (((*sr)->field_24 & 0xFF00) << 8) | ((*sr)->field_24 << 24); (*instr)->sr_field1C = (((*sr)->field_1C & 0xFF0000) >> 8) | ((unsigned int)(*sr)->field_1C >> 24) | (((*sr)->field_1C & 0xFF00) << 8) | ((*sr)->field_1C << 24); qmemcpy(&(*instr)->sr_field34_md5, (*sr)->field34_md6, 0x10u); qmemcpy(&(*instr)->sr_field28, &(*sr)->field_28, 0xCu); RevBL(&(*instr)->sr_field28); RevBL(&(*instr)->field_2C); RevBL(&(*instr)->field_30); fld10a = (*sr)->field_10; fld10b = HIBYTE((*sr)->field_10); (*instr)->is_sr_field10_flag0200 = HIBYTE((*sr)->field_10) & 2; (*instr)->is_sr_field10_flag0100 = fld10b & 1; (*instr)->is_sr_field10_flag0400 = fld10b & 4; dInstr = *instr; if ( (*instr)->sr_field4 & 0x20000 ) { state = dInstr->instrState; if ( state & 0x200 ) { dInstr->instrState = state & 0xFFFFFDFF; DBPrintf("Fixing instrState, remove viDebugCapable from subroutine VI"); } } }
  14. How cute - NI is protecting some values stored in memory at runtime by XOR'ing them with seed which depends on the VMA. Here's what it does to an MD5 checksum stored at `ptr` (hence size=16), code comes from LV14: seed = ptr ^ 0xDEADCAFE; i = 0; do { *(uint8_t *)(i++ + ptr) ^= seed; seed >>= 1; } while ( i < 16 );
  15. Thanks for all the info! Searching for various NI things on the Internet, I found quite a lot of packages which included the LV RT. Various toolsets, drivers, and labview-based solutions. Though most of these use standard release of the RT installer. Unfortunately I have no pre-release versions. And this is where I expect higher chance of having some debug info left. I've seen indications that VI Logger 1.1 had a pre-release RT in it, but I could only find the fixed 1.1.1. As of now, I couldn't find the LV 2.5 as well. I found LV 6.0 on one of my old CDs, that's the oldest version I have.
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.