[twinBASIC] x64-compatible port of Event Tracing for Windows File Activity Monitor
TBEventTrace v2.2.2 (released 16 Sep 2022)
Using Event Tracing for Windows in twinBASIC
This is a port of [VB6] Event Tracing for Windows - Monitoring File Activity with ETW. See that page for project description. The requirements here differ in that 32bit Windows is also supported, and 64bit Windows is not supported by a 32bit build. You should always use the latest release of twinBASIC; for 2.2.2 you at least 0.15.122. Note: Their www site has a much earlier version, so make sure to grab it from their GitHub if you don't already have it.
A few days ago I looked into twinBASIC (Current info on GitHub), and was pleasantly surprised to see that it is a lot further along than I thought it would be, after so many similar projects never got off the ground or made little progress over years. While the IDE is barebones and it's missing some fairly important features like menus for forms and the PictureBox control (Update The IDE has improved greatly and now has menus and PictureBox), the language itself, which is the most important and difficult part, seems to be nearly fully developed to full compatibility with a few additional features, like a real LongLong datatype, CDecl support for API, multithreading (via API only for now but Wayne is adding native language support soon), and including compiling VB/TB code into native x64 executables, if you convert your code to VBA 64bit. It's far enough along that I've been able to fully port VBEventTrace, which demonstrates using the extremely complicated ETW API to implement a File Activity Monitor, into a codebase that can be compiled to target x86 and x64.
Overall, I was able to implement 100% of the features and functionality. Here's the changes I had to make, or in the case of x64 and threading got to make;
-tB can't open VB Forms yet, so I had to manually recreate the layout. UPDATE: NOW SUPPORTED
-All code was converted to x64 VBA-syntax code. This was mainly changing pointers and handles to LongPtr and marking APIs PtrSafe, but note that if you have structs with manual alignment padding like this project, you may need to alter it and create conditional alignment, see EVENT_TRACE and EVENT_RECORD. Be careful, because x64 has an additional rule: Pointer types must be at 8-byte offsets, and tB is doing that behind the scenes. It also exposed an interesting widespread issue with nearly every VBA code sample of PROCESSENTRY32 online.
-As part of the x64 conversion, I updated the MOF data structures to a single definition that compiles properly for either x86 or x64. So while as the original program shows, it's possible to handle x64 Windows in an x86 Event Tracer, it also meant the program wouldn't work on 32bit Windows, because it was hard-coded for x64, and supporting both would require major work to write separate handlers for each. But as a result of making a single handler work for both, a 32bit build will no longer work on 64bit Windows. If you really wanted that, you could convert the LongPtr's back to LongLong or Currency like the original.
-Self-subclassing classes/Forms/UCs isn't practically supported yet, AddressOf works on class members, but only for Subs, and many many things need to return values. VBEventTrace used a hack that relied on the VB runtime, so that was a non-starter, so I changed the subclassing method to use a module. UPDATED: Now supported.
-CreateThread can be called without crashing, eliminating the need for the brilliant hack in The trick's module (which wouldn't be support anyway as it manipulates the runtime and VB exe structures TB doesn't have).
-twinBASIC doesn't yet have control arrays, so I had to manually program the OptionButton logic. UPDATE: NOW SUPPORTED
-I don't like hardcoding object references, but in the ListView WndProc you'll see Form1.FormatTime; there's a bug in TB related to DateSerial (and possible Format) under x64 in Modules. UPDATED: Fixed.
-The situation with GetWindowLong/SetWindowLong is a little wonky. I don't know if HWND's can always be guaranteed to fit into 4 bytes on x64, so for this API I provided separate definitions with the #If Win64 Then conditional compilation argument, which TB provides natively.
-No PictureBox yet so for the popup More Options I used the Frame as a base; it's still draggable, but doesn't have the little TitleBar, since I'd have had to put that inside the Frame. UPDATED: Now supported.
-A few controls in the original had Tooltips, those are not implemented in TB yet (you can of course add them via API, I haven't done that yet). UPDATE: NOW SUPPORTED
-TextBox controls in TB support Unicode.
-App object lacking most members; needed to replace App.Title with AppTitle manually defined const. UPDATE: NOW SUPPORTED
-Currency types for things that were 8 bytes regardless of x86 or x64 were changed to use LongLong. Remember if you do this to check where you divide or multiple by 10000 to get the right result!
-tB currently marks processes dpi aware because it's controls are, but that means if you have API-created controls (like this project's API-created ListView), it throws off measuring, so I also had to add manual positioning for the ListView. You can correct this issue without code changes by using the compatibility options in the file properties to force system scaling. Also related, there's no .ScaleWidth properties. UPDATE: NOW SUPPORTED (Can turn off marking process DPI aware, and ScaleMode/ScaleWidth/ScaleHeight supported)
As you can see, these are all improvements or fairly minor issues.
I'd also note that the original 32bit code ran fine with only the changes to the Form/Controls and threading/subclassing methods. There's no need to update your projects to x64 if you don't want to.
(Project also has bug fixes not present in the current public version of VBEventTrace: Unicode process filenames are now supported; Process32First/NextW weren't being used previously; and PrebuildFullProcessCache exited after loading a single process, although it's not called in the default code)
If this kind of work keeps up, twinBASIC I believe is the first actually viable direct successor to VB6, and I wanted to post this project to help show off how far along it is. While the missing features and IDE are limiting, I think Wayne did it right to focus on parsing and compiling the language first, that's the more difficult and most important part.
(Side note, twinBASIC also now has built in support for creating kernel mode drivers, which VB6 was shown to do with some hacks, so we're living in some interesting times.)
Update - Version 2.2.2
-twinBASIC now allows AddressOf on Function class members, and now has a PictureBox control. The project has been updated to put all subclassing and related back in the main form and use a PictureBox for the More Options popup now identical to the VB version.
Update - Version 2.2
This is an update only for the twinBASIC version. I've added the option to have a column that shows the command line of the process (under More... in the options box). Since no special effort is needed for an x64 app to read process memory of a 32bit process, it was easy to implement here, but the reverse isn't true so while it's possible to read x64 process memory from x86, it's far far more complicated. Also fixed the bug with SimpleOp failing due to a size mismatch; MOF structures don't have alignment padding, but tB added it. But tB has a new option to manually set UDT alignment, so I was able to turn that off. Also removed incorrect manual padding; the need was just a relic of the structures being handed off unmodified to the kernel, so on WOW64 you needed to manually align it, but now no alignment is needed (besides turning it off for MOF structures). Note: This update also relies on bug fixes to twinBASIC; you'll need Beta 122 or newer to correctly run/compile this project.
Last edited by fafalone; Sep 2nd, 2024 at 01:43 AM.
Reason: Updated description to note features tB now has
Re: [twinBASIC] x64-compatible port of Event Tracing for Windows File Activity Monito
The original VB6 code is in the VB6 CodeBank post linked right up top... do you mean before I updated it to support x64?
I'll attach it here.
This is a bit less polished; just the bare minimum to get it running. It doesn't have the custom icon/manifest/version properties, uses the default font in the tB IDE, and doesn't manually correct a current bug that results in the TextBox not having the cursor change to I-Beam.
The form events have "Private Sub Command1_Click() Handles Command1.Click"... but although I initially thought it was the 'Handles...' addition doesn't appear to be strictly necessary.
But apart from using a subclassing method not involving asm thunks only applicable to VB exes, calling CreateThread directly, and working around the few controls/control properties not yet present, the code is virtually unchanged. tB supports the entire VB6/VBA language.
Note: This still has the original MOF definitions so only works with 64bit Windows.
Last edited by fafalone; Jul 28th, 2022 at 12:30 PM.
Re: [twinBASIC] x64-compatible port of Event Tracing for Windows File Activity Monito
Update - Version 2.2
This is an update only for the twinBASIC version. I've added the option to have a column that shows the command line of the process (under More... in the options box). Since no special effort is needed for an x64 app to read process memory of a 32bit process, it was easy to implement here, but the reverse isn't true so while it's possible to read x64 process memory from x86, it's far far more complicated. Also fixed the bug with SimpleOp failing due to a size mismatch; MOF structures don't have alignment padding, but tB added it. But tB has a new option to manually set UDT alignment, so I was able to turn that off. Also removed incorrect manual padding; the need was just a relic of the structures being handed off unmodified to the kernel, so on WOW64 you needed to manually align it, but now no alignment is needed (besides turning it off for MOF structures).
Re: [twinBASIC] x64-compatible port of Event Tracing for Windows File Activity Monito
Update - Version 2.2.2
-twinBASIC now allows AddressOf on Function class members, and now has a PictureBox control. The project has been updated to put all subclassing and related back in the main form and use a PictureBox for the More Options popup now identical to the VB version.