This code RELIES on the Microsoft specific functionality of __try
and __except
. There is no other way to solve this, as doing an IN
instruction from a user-mode process in Windows will normally fail. In VMWare, any such operation is intercepted by the VMWare VMM (Virtual Machine Monitor, sometimes also called Hypervisor). It then checks the special values in some registers and "accepts" the instruction with a new value in ebx
to indicate that "Yes, I'm a VMWare system". If you run this on a plain old Windows system, it will get an General Protection Fault for trying to use a IO-port that isn't available to the application [in general, IO ports aren't availbe to the user-mode application code].
You need to compile this using a Microsoft compiler (and with the suitable "enable exception handling" flag set - sorry, can't remember what that flag is, but it will tell you if it's not on that it's wrong). GCC doesn't support this feature.
However, you can test for VMWare using the CPUID instruction instead of using IN
. This will work much better in a GCC compiler, as it will not fault the processor if there is no VM present [For the pedants: As long as the processor is later than some version of 486 from the 1990's]. Instead, it will just not give the right values in the registers (no change to the register values). You may need to write a cpuid
inline assembler function, but that shouldn't be too difficult to google up.
See this KB-article on VMwares site:
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Alternatively, if you really insist on using Windows Structured exception handling, you can do it yourself:
push handler // Save address of your handler.
push fs:[0] // Save address of any previous handler
mov fs:[0], esp // Save pointer to current exception record.
... // all the stuff setting registers, doing IN, etc.
jmp cleanup
handler:
mov [rc], 0 // Set "rc= false".
cleanup:
pop fs:[0]
add esp, 4 // Remove handler
(Note, I just wrote that from a bit of googling - it's a LONG time since I used anything like that on Windows, so it may not work)