Hacker News new | past | comments | ask | show | jobs | submit login
Rust9x: Compile Rust code for Windows 95, NT and above (seri.tools)
186 points by seritools 3 months ago | hide | past | favorite | 47 comments



I wonder if this might be even more useful for ReactOS, which is still actively supporting 32-bit x86, while Windows 11 no longer does.


Just grabbed the latest ISO to test it out :) - rust9x_sample.exe sadly only works in 98/Me compatibility mode. https://i.imgur.com/nWCfTtV.png

In regular mode it seems there's a problem with the system not setting the file pointer to the end when OpenOptions::append is used: https://i.imgur.com/vvbEnWh.png https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#met...


This sounds like you've found a bug in either the Rust standard library or the ReactOS API implementation. It might be worth looking into this!


To clarify, it works in 98/Me mode because I added a fallback implementation to Rust9x for these systems, as the flag in question is not supported.

AFAICT it is supported since NT 3.1, though, and it worked fine on all NT-based systems I've tested so far, so my guess would be a ReactOS API bug.

The commit adding the 9x/Me fallback implementation:

https://github.com/rust9x/rust/commit/3a3eddb0044c6d03357a75...


You spooked me that Win11 had dropped support for 32-bit applications, but it seems they still work fine. There's no 32-bit version of the OS though.


Rather confusingly the death of the 32-bit version of Windows in practice just means they are dropping support for 16-bit DOS applications.

There is a WoW (windows on windows) subsystem which permitted you to either run 16-bit binaries on your 32-bit system, or 32-bit binaries on your 64-bit system; but there's no 16-on-64 or 16-on-32-on-64.

If you have a 64-bit version of Windows the compatibility layer[1] lives at `%SYSTEMROOT%\SysWoW64`.

[1]: https://en.wikipedia.org/wiki/Windows_on_Windows


You can use winevdm for this though, https://github.com/otya128/winevdm


I'm waiting for the day when people run Linux on windows via a hypervisor to run old programs under wine. This is pretty close.


People already do this. There is a very old strategy game (Stars!) that still (barely) has an active community. As it's a 16-bit windows app, the standard advice on how to run it on modern systems is to run it under wine in a VM.


I actually have already done this -- or, rather, helped someone else to do this. The individual in question was an academic with a license for a rather old version of a particular piece of domain-specific software, which would only run on Windows 95/98/ME. As he taught at a small school, his budget wasn't exactly infinite, so he kept an old Windows 98 machine around to run that software.

Turned out, it ran great on Wine. Actually, the performance even improved because the hardware was so much newer.


I used to read about wine for windows, but I haven't seen anything in a while (but there is winevdm, which might be wine for windows for 16-bit)


> There is a WoW (windows on windows) subsystem

Oh my god, I always wondered why the WOW6432NODE registry key was named that but was never bothered enough to look it up. Thank you for triggering the random insight.


Yeah they worded that confusingly. That said, I feel like the writing is probably on the wall for 32-bit. My guess is this might be the real reason why they pushed for making Visual Studio 64-bit.


I commend you for finding a use-case for this because I'm scratching my head over if this is a toy project or filling some necessity.

Still a very awesome project!


Can confirm, toy project. But hey, if it helps someone who might actually need this, even better!


This is a really interesting point. I can imagine that being able to use Rust for ReactOS (and wine!) would bring lots of interesting opportunities for developers and new contributors.


Hopefully we'll get support within Rust/Cargo for easily rebuilding the rust-std from source with custom features as part of compiling a project. Then this legacy system support could simply become part of the official Rust distribution.


This is already pretty easy with -Zbuild-std, but requires nightly unfortunately. You need to do this to get simd support in the standard lib in wasm for instance.


I think the rust-std code added for this project could already be pulled into rust, then. The target names should probably be something like i586-windows-msvc-old. (BTW, if LLVM supports building for plain i386 or i486, support for this should also be considered.)


Although I find it unlikely it would get upstreamed (but would love if it was), I think it could be called i586-windows-msvc-chicago instead.


I approve of ureq being used on Windows 95 :)

(I'm the original author)


Heck yeah! Thanks for writing it!


Thank you for ureq! And thank you for keeping it async less :)


Next step: Windows 3.11 using the win32s API :)


Oh trust me I've thought about that :)

It depends on two things:

- is the supported API surface big enough?

- is there an msvc runtime that can be linked with a somewhat modern linker (so that rust/llvm don't get angry) but that still works under Win32s. I'm not sure that exists, though :c


I know that Win32s requires that the EXE have a RELOC section, so it must be built with relocation enabled.

I hope you don't need to go all the way to /NODEFAULTLIB though, that kind of configuration is a big headache to build on.

Is there a .lib file for "msvcrt.dll" that will work with /NODEFAULTLIB? If so, I wonder if there is a Win32s compatible binary for that.


> that kind of configuration is a big headache to build on

Not really, I've done just that (though in the end I didn't need full /NODEFAULTLIB):

https://github.com/rust9x/rust9x-sample/blob/main/.cargo/con...

With older msvcrt libraries you only need to link `libcmt.lib`/`msvcrt.lib`, that's it. Visual C++ 4.0 is apparently the last version to support Win32s, so if you can make it link to its libraries you might have a chance!


Biggest difference would probably be the complete lack of multithreading.


Win32s applications (like Win16 applications more generally) run in a shared address space with cooperative multitasking. They're basically async applications within an OS-provided runtime.


Oh right, that's also a thing :v


How did you generate the Visual Rust cover image? I love it.


Vector graphics tool and manually changed the kerning on each letter to match the OG Visual Studio covers. The background effect is just the regular rust logo copied twice :)


Seeing that splash screen really tickled my brain. It’s likely rose tinted glasses, but I really miss the Visual C++ 6 on Win9x experience and all its associated aesthetic.


Very cool, I love the idea of feeding some rust code to my retirement community of old PCs, native PEs that I don't have to use Win32 and C to use.


This reminds me that I keep meaning to see how much Rust toolchain support there is for legacy consoles like the GameBoy Advance.



Thanks for the link!


The FreePascal Compiler does and a bunch of platforms I probably will never run any code I write on.


I wonder is there any option for async for NT-based legacy system like 2000 or XP? They have fibers and preliminary multicore support far as I remember. On other platforms slapping a simple single threaded runtime is probably fine.


NT has always been an SMT system, so full-on tokio should probably be runnable with a bit of patching.


This looks really neat!

I wonder if it has been tested on Win32s or HXDOS. HXDOS is very friendly about that kinds of program it accepts, for example, the console version of 7-zip will run fine on HXDOS.


If you go `no_std` I'm confident both would work - I think the current windows stdlib implementation still might be too much for those.


Wow, I wonder if these will work in DOS via the HX DOS Extender ?


Haven't looked into it too much, but yes, the files themselves should be compatible. I'd probably use no_std on targets like this or Win32s.


Ok, now do DOS, with IPX networking


DOS with DPMI would be relatively easy. 16-bit support (real mode or protected mode on 80286) would require significant changes in LLVM, impacting frontend as well as backend code due to the requirement for separately defined _near, _far and _huge pointers and different "memory models".


Needs to be 386 and up with DOS extender then, but sounds fun…




Applications are open for YC Winter 2023

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: