The management of memory for resources in 16-bit Windows

Date:February 2, 2004 / year-entry #46
Tags:history
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20040202-00/?p=40783
Comments:    13
Summary:In a previous entry I threatened to discuss the way resources were managed in 16-bit Windows. In 16-bit Windows, resources were not loaded until explicitly requested. The FindResource function located the entry for the resource in the resource directory and returned it in the form of a HRSRC. The LoadResource function took that resource handle,...

In a previous entry I threatened to discuss the way resources were managed in 16-bit Windows.

In 16-bit Windows, resources were not loaded until explicitly requested.

  • The FindResource function located the entry for the resource in the resource directory and returned it in the form of a HRSRC.
  • The LoadResource function took that resource handle, allocated some movable memory (HGLOBAL), and loaded the referenced resources off the disk into that memory.
  • The LockResource function took that global handle and locked it, returning a pointer to the resource bytes themselves.
  • The UnlockResource function unlocked the global handle.
  • The FreeResource function freed the memory that had been allocated to hold the resource.

Actually, it was more complicated than this. Additional bookkeeping ensure that if two people tried to load the same resource, the same memory block got used for both, and the FreeResource didn't actually free the memory until the reference count went back to zero.

Actually, it was even more complicated than this. If the resource was marked DISCARDABLE, then the memory wasn't actually freed when the reference count dropped to zero. Instead, the global handle was marked as discardable (GMEM_DISCARDABLE), so the handle remained valid, but when the system came under memory pressure, the memory behind the handle would get freed, and the next time you did a LoadResource, it would get reloaded from disk.

So now you know what that DISCARDABLE keyword in resource files means. Or at least what it used to mean. Win32 doesn't do any of this; the DISCARDABLE flag is ignored but remains for compatibility.


Comments (13)
  1. Mike Kolitz says:

    Raymond – love your blog! Thanks for all your valuable information, I find it most refreshing.

    Out of curiosity, I was wondering what your take would be – from a technical standpoint – on removing 16-bit compatibility from next-gen versions of Windows. Do you believe this would increase performance in the OS, or make it more stable and secure?

    In general, would a move like that be more helpful or harmful to Windows from a purely technical standpoint?

  2. Jack Mathews says:

    So in Win32, LoadResource just basically returns a pointer, and LockResource, UnlockResource, and FreeResource are pretty much no-ops, right?

  3. 2/2/2004 7:17 AM Mike Kolitz:

    > on removing 16-bit compatibility from

    > next-gen versions of Windows

    You mean like this?:

    http://support.microsoft.com/default.aspx?scid=kb;en-us;282423&Product=winxp

  4. Mike Kolitz says:

    Norman – Yeah, that’s pretty close to what I’m talking about. I’m guessing that since Win64 doesn’t seem to suffer from any problems from the lack of Win16 support, Win32 wouldn’t either. Nice to know :)

  5. Thomas Fogglebottom. says:

    Hi Raymond. After your recent entry on programmers using incorrect calling conventions(http://blogs.msdn.com/oldnewthing/archive/2004/01/15/58973.aspx), I had to laugh when I read this prototype on MSDN:

    int WinMain(

    HINSTANCE hInstance,

    HINSTANCE hPrevInstance,

    LPSTR lpCmdLine,

    int nCmdShow

    );

    Something missing!?

  6. Raymond Chen says:

    Jack: "Try it and see". And if you did, you’d find that LockResource does do something. FindResource returns a resource handle, and LockResource turns it into a pointer. But UnlockResource and FreeResource don’t do anything any more.

    Mike: From a technical standpoint, I would be overjoyed if Win16 support were finally to go away. It would significant reduce attack surface, since there’s an awful lot of code which exists solely to support Win16. But from a practical standpoint, the world is not ready to abandon Win16 yet (alas).

  7. Mike Kolitz says:

    Thanks Raymond. That’s kind of what I figured :P Maybe someday…

  8. Will says:

    Very late message I know, but I wanted to comment on the "LockResource turns it into a pointer". When I stepped through the disassembly of LockResource, all it did was pass back the passed in value unverified and unaltered. In other words the code for LockResource could be written as–

    MOV EAX, [hResData]

    RET

    So, at least on Win32, you could get rid of LockResource calls altogether by simply typecasting the passed in HGLOBAL to a pointer. Of course this isn’t advisable for code that’s meant to run on other platforms (Win64 or, shudder, Win16) but if you’re bent on performance, it’s worth knowing.

  9. Raymond Chen says:

    I challenge you to find any scenario where the extra memory access is even measureable in a real-world program. If you’re looking for performance improvements, this is the wrong place to optimize.

  10. They mean the same thing today, but at one time they were quite different.

  11. The SZ (a.k.a. Steffen) asked in the suggestion box:

    What is the prefered way to select the "most…

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index