links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
(Obsolete) Win32 Enhancements
Last updated at 4:46 pm UTC on 16 January 2006

NB - to the best of my knowledge all the following points are now solved. VMMaker no longer needs any alterations for win32, the image file header issue has been resolved and so on. TPR Feb 2003


512 byte Unix Header Compatibility

Recent unix builds introduce a 512 byte header (it holds a #!). The current windows VM refuses to open such an image. The changes fix that.

Some Peculiarities of the 512 Byte Header Handling

Implementations on different OS's take differing approaches to handling the header, and some of the comments in the code are a bit misleading.

The actual reading and interpreting of the image is done by system-independent code (specifically checkImageVersionFromstartingAt in interp.c) that all platforms use. Problems arise because some platforms (e.g., Win32) do their own independent check first, apparently to provide better error-handling. Win32 implements checks at SqueakImageLength in sqWin32Window.c and IsImage in SqWin32Args.c. There is only one call to the latter, which I have eliminated and replaced with SqueakImageLength()>0 (that change is not yet uploaded).

Then each platform has its own code to write images so that, for example, Unix code puts a #! in the first 512 bytes. Various functions define offsets that the writing code uses. Though some of the comments of those functions imply they are used for reading, that does not seem to be the case. For example, The unix code redefines sqImageFileStartLocation and claims this is automatically used. But the only caller I found (in interp.c) uses it when writing, not reading.


The code that checks the image appears in several places. It would be good to eliminate this duplication. As noted, I've already removed IsImage. Probably the error handling of the system-independent code needs to change before it can be used safely in place of the platform-specific checks that now exist.

File handling, esp 64 bit

The existing macros WIN32_FILE_SUPPORT and NO_STD_FILE_SUPPORT disable the usual file handling, along with calls to routines like fseek. In their place are Win32 implementations using Win32 system calls. The main motivation, apparently, was that some windows platforms (WinCE) do not have the regular calls. (One of these macros was missing from the .dsp file; my patch fixes it).

Cross/vm/sqVirtualMachine.h defines a type squeakInt64 (my patch gives this a working definition for MSVC) used for file operations. Despite the definitions referred to above, it is still used in some places, for example the fileplugin and directory logic.

win32/vm/sqPlatformSpecific.h defines squeakFileOffsetType. I initially tried the following for MSVC
#if defined(_MSC_VER)
 #define squeakFileOffsetType __int64
 #define ftell(stream) _telli64(_fileno(stream))
 #define fseek(stream, offset, origin) \
  _lseeki64(_fileno(stream), offset, origin)
 #define squeakFileOffsetType int
but backed this out because it implied I needed to redefine various FileImage functions. Also, it's not clear that ftell and fseek are ever used in Win32 builds.

win32/plugins/FilePlugin/sqWin32FilePrims.c defines the basic file operations using Win32 calls like SetFilePointer. These calls can potentially do 64 bit access, although they do so in an awkward way (you pass in the low and high bits separately) and the upper bits are not currently used. Further, some Win32 systems (e.g. Win95) do not support 64 bit addressing.

That same file also defines special handling for image file operations.

It may be possible to use __int64 for offsets, and then reinterpret the bits for use in the funky calls that have a separate low and high 32 bits. See the LARGE_INTEGER structure and the SDK docs on SetFilePointer. They seem to imply that an __int64 can be reinterpreted as a LARGE_INTEGER to pull out its two parts. Because of issues of bit ordering and the sign bit, I had some doubts whether this operation was safe. I guess windows is back to running on only one chip family, which simplifies things.

There are also extended versions of some of the system calls that work naturally with 64 bits, but these are only available starting with windows 2000.

Current Status

The windows implementation does its own file handling. Although the raw materials for 64 bit access are there, they have not been used. My patch introduces one 64 bit type, but does not change any code that uses it. So it should be treated with caution.


Implement 64 bit access. This might require first validating the safety of the LARGE_INTEGER games mentioned above. I'd also like to check on performance, though Andreas thinks its a non-issue (remember, not only file access but arithmetic with the offsets will be 64 bit).

Even if win32 implementations of the file primitives are necessary or desirable, it's a little odd that the image file access functions need to be reimplemented too. This may stem in part from the special handling of image file headers referred to in the previous section. It would be nice to avoid having file access logic appear twice, though, once for regular files and once for images.

MSVC Compatibility

As mentioned under files, squeakInt64 needs to be __int64, not long long for MSVC.

The pragma export is meaningless to MSVC. There is already a definition of the EXPORT macro so it does the right thing for MSVC.

SetDefaultPrinter is a function defined in the MS SDK. The patch renames it (not strictly an MSVC issue).

Debug Window?

For debug, but not release, builds, the bottom of the image shows a fairly large white box, perhaps 60 pixels high (clearly taller than the tabs that are usually there) and the width of the window. If I popup a menu above it, it obscures the part of the menu that goes below this. It looks as if messages might flash by very quickly in this area. Is this a bug or a feature? What is it?


The enhancements change Win32VMMaker so that basic vm files are no longer copied. Instead, the .dsp file gets links to them. Because of this, the changes will break gcc builds.

I updated the .dsp file in the sources, and this now serves as a template that is rewritten. You still need to set up the include and library paths for Direct X 7 manually.

This still works only for internal plugins; in particular, it can't build the Mpeg3Plugin.


Rather than futz with the gcc makefile, it makes more sense to figure out what the desired build behavior is, and then modify VMMaker so that both MSVC and gcc work. I would like to know more about how the non-copy builds work on other platforms to see if there are any ideas I can steal.

Likely we will need separate projects for each external dll (and perhaps for the internal ones if they are in separate directories?), with the main project having a dependency on the subprojects.

The desired build structure for Win32, as for other platforms, is to have an internal and an external plugins directories, and then put each plugin in an appropriate subdirectory. This is for two reasons: first, to have a directory structure that facilitates understanding of and operation on the plugins; second, to allow different plugins to use the same file and function names.

The core VM should build without any reference to particular plugins, and each plugin should build without reference to any other plugins. Communication to and between plugins is via generic VM facilities. However, this ideal has not been completely attained: at the moment OSProcessPlugin probably needs access to the FilePlugin headers and maybe the Socket ones.

For FooPlugin, the relevant files comprise
  1. those in either src/plugins/FooPlugin (for an external plugin) or src/vm/intplugins/FooPlugin (for an internal plugin, assuming support for the intplugins dir is up to date)
  2. those in /platforms/{your platformname}/plugins/FooPlugin, assuming any platform specific fiels are required. If they are, the plugin class must implement #requiresPlatformFiles to return true.
  3. those in /platforms/Cross/plugins/FooPlugin, assuming any cross platform files are required. If they are, the plugin class must implement #requiresCrossPlatformFiles to return true. Note that it is quite feasible to require both - see B3DAcceleratorPlugin.
  4. those headers in /platforms/Cross/vm and /platforms/{your platform name}/vm required by the C files.

Each plugin should have some new files created, as well as the existing files from SourceForge, so there should be a directory in which to write object files, project files, and the like.

Internal plugin function names are rendered unique by CCodeGenerator>cFunctionNameFor, which prefixes each function name with the module name. External plugins are compiled separately, and only accessed through VM calls that include the module name, so there is no need to make the function names unique.

Open Issues

What is the deal with the Mpeg3Plugin? John McIntosh is rumored to know.

How were the Squeak-D3D and Squeak-GL images produced? Which, if either, has the build process above produced?

Created by RossBoylan@stanfordalumni.org on 20-Feb-2002.
Updated 3-Mar-2002 by Ross, using comments from John M McIntosh, Tim Rowledge, and Lex Spoon.