Creating Dynamic Code Segments Using PrestoChangoSelector

Last reviewed: July 23, 1997
Article ID: Q89560
3.00 3.10 WINDOWS kbprg

The information in this article applies to:

  • Microsoft Windows Software Development Kit (SDK) for Windows versions 3.1 and 3.0

SUMMARY

Some problems arise when an application for the Microsoft Windows graphical environment uses a segment addressed by a selector that is not allocated by the Windows kernel. This article describes the correct method of building selectors at run time. While the text below describes the problems that arise when an application calls the PrestoChangoSelector() function to alias a selector, it does not discuss other difficulties involved in building a code segment at run time. Note that the techniques in this article are specific to the current implementation of 16-bit Windows.

Note that version 3.0 of the Windows Software Development Kit (SDK) "Reference: Volume 1" manual refers to the PrestoChangoSelector() function as the ChangeSelector() function.

MORE INFORMATION

If a callback function, for example, a window procedure, is located in a dynamic code segment, the Windows user module encounters some problems when any application exits because the selector for the segment was not allocated by the kernel. To work around this problem, the application must save the original selector used to access the segment [obtained from the AllocSelector() function] and use the original selector to execute the code in the segment [using PrestoChangoSelector()]. The code fragment below demonstrates this technique. Note that DATA_SELECTOR is a selector obtained from the GlobalAlloc() function.

   WORD wCopyOfDataSelector;
   WORD wSelectorToCode;

   // When an application calls AllocSelector() with a valid selector,
   // the function copies the information associated with the selector
   // to a new location in the descriptor table used by Windows and
   // returns the new location. In the code below, wCopyOfDataSelector
   // is a second entry in the descriptor table that points to a
   // globally allocated block of memory.

   if ((wCopyOfDataSelector = AllocSelector(DATA_SELECTOR)))
      {
      // PrestoChangoSelector() toggles the bit in the descriptor table
      // that indicates whether the associated block of memory is code
      // or data. Therefore, in the code below, wSelectorToCode is a
      // code selector to the wCopyOfDataSelector (and DATA_SELECTOR)
      // block of memory.
      if ((wSelectorToCode = PrestoChangoSelector(DATA_SELECTOR,
                                                  DATA_SELECTOR)))
         {
         // Call code through wSelectorToCode
         // Read or write using wCopyOfDataSelector

         return TRUE; // Everything worked!
         }
      else
         return FALSE; // Changing the selector failed
      }
   else
      return FALSE;    // Unable to allocate selector

   // Be sure to free the allocated selector before the application
   // terminates.
   if (FreeSelector(wCopyOfDataSelector))
      return FALSE;  // Selector not freed


Additional reference words: 3.00 3.10
KBCategory: kbprg
KBSubcategory: KrMm
Keywords : kb16bitonly


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 23, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.