home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / os2 / vmm / vmm_user.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  27KB  |  654 lines

  1. /*static char *SCCSID = "@(#)vmm_user.c    6.11 92/02/19";*/
  2. /*==================================================================*\
  3.  *  VMM_USER.C - routines for handling messages not processed       *
  4.  *              by the standard message processing routine          *
  5.  *      (C) Copyright IBM Corporation 1992                          *
  6.  *------------------------------------------------------------------*
  7.  *                                                                  *
  8.  *  This module contains the code for processing messages sent      *
  9.  *  to the standard window that the standard window does not        *
  10.  *  process.  The application developer need only modify this       *
  11.  *  file in order to implement new menu items or process            *
  12.  *  messages not handled by the standard message routine.           *
  13.  *                                                                  *
  14.  *  This module also contains some routines that demonstate the     *
  15.  *  various dialog box controls and message box types that can      *
  16.  *  be used.  The sample code should be deleted when this           *
  17.  *  module is modified for an application.  The demonstration       *
  18.  *  code is identified by comments.                                 *
  19.  *                                                                  *
  20.  *------------------------------------------------------------------*
  21.  *                                                                  *
  22.  *  This source file contains the following functions:              *
  23.  *                                                                  *
  24.  *      UserCommand(mp1, mp2) - user WM_COMMAND processor           *
  25.  *      VMM_Error(pszFunction, ulErrorCode) - Error processing      *
  26.  *      CleanUpArray(pvAddress) - Page table maintenance            *
  27.  *      StoreInArray(pvAddress, ulNumPages) - Page table maintenance*
  28.  *                                                                  *
  29. \*==================================================================*/
  30. /*------------------------------------------------------------------*\
  31.  *  Include files, macros, defined constants, and externs           *
  32. \*------------------------------------------------------------------*/
  33. #include "vmm.h"
  34.  
  35. /*--------------------------------------------------------------*\
  36.  *  Global variables                                            *
  37. \*--------------------------------------------------------------*/
  38. MSGENTRY    amsgentry[] =
  39.     {
  40.         { ERROR_INVALID_PARAMETER,
  41.           "%s\n\nInvalid Parameter",
  42.           MB_ICONASTERISK
  43.         },
  44.  
  45.         { ERROR_ACCESS_DENIED,
  46.           "%s\n\nAccess to Memory Denied",
  47.           MB_ICONASTERISK
  48.         },
  49.  
  50.         { ERROR_NOT_ENOUGH_MEMORY,
  51.           "%s\n\nInsufficient Memory",
  52.           MB_ICONASTERISK
  53.         },
  54.  
  55.         { ERROR_INVALID_ACCESS,
  56.           "%s\n\nAn Invalid access to memory was"
  57.           " attempted.",
  58.           MB_ICONASTERISK
  59.         },
  60.  
  61.         { ERROR_INVALID_ADDRESS,
  62.           "%s\n\nAddress Given is Invalid.",
  63.           MB_ICONASTERISK
  64.         },
  65.  
  66.         { ERROR_INTERRUPT,
  67.           "%s\n\nThe call was interrupted by an external"
  68.           " event and was not completed. Please retry the"
  69.           " operation.",
  70.           MB_ICONASTERISK
  71.         },
  72.  
  73.     /* Errors following are application defined */
  74.  
  75.         { VMERR_MAX_ALLOCATED,
  76.           "%s\n\nThe allocation has surpassed"
  77.           " this application's maximum number of displayable"
  78.           " pages of %u. Each page contains 4096 bytes"
  79.           " of data.",
  80.           MB_ICONASTERISK
  81.         },
  82.  
  83.         { VMERR_ZERO_ALLOCATED,
  84.           "%s\n\nA minimum of 1 byte must be specified for"
  85.           " an allocation.",
  86.           MB_ICONASTERISK
  87.         },
  88.  
  89.         { VMERR_TILE_ONLY,
  90.           "%s\n\nAllocation attempted with"
  91.           " tiled attribute and no access"
  92.           " protection specifed. Access protection required to"
  93.           " properly allocate memory.",
  94.           MB_ICONASTERISK
  95.         },
  96.  
  97.         { VMERR_COMMIT_AND_TILE_ONLY,
  98.           "%s\n\nAllocation attempted with no access"
  99.           " protection specified. Access protection required to"
  100.           " properly allocate memory.",
  101.           MB_ICONASTERISK
  102.         },
  103.  
  104.         { VMERR_ALREADY_FREED,
  105.           "%s\n\nThe memory address specified to be"
  106.           " freed has not been allocated. Only previously"
  107.           " allocated memory may be freed.",
  108.           MB_ICONASTERISK
  109.         },
  110.  
  111.         { VMERR_NOT_BASEPAGE,
  112.           "%s\n\nThe memory address specified to be"
  113.           " freed is not a base-page address. Only"
  114.           " base pages"
  115.           " may be freed.",
  116.           MB_ICONASTERISK
  117.         },
  118.  
  119.         { VMERR_DECOMMIT_RESERVED,
  120.           "%s\n\nThe memory specified to be"
  121.           " decommitted is in a reserved"
  122.           " state. Memory must"
  123.           " be committed before it can be decommitted.",
  124.           MB_ICONASTERISK
  125.         },
  126.  
  127.         { VMERR_ACCESS_ON_RESERVED,
  128.           "%s\n\nAccess protection specified for"
  129.           " reserved memory. Access protection may "
  130.           " only be specified for committed memory.",
  131.           MB_ICONASTERISK
  132.         },
  133.  
  134.         { VMERR_ACCESS_AND_DECOMMIT,
  135.           "%s\n\nAccess protection specified when"
  136.           " attempting to decommit memory. No access protection"
  137.           " may be specified when decommitting memory.",
  138.           MB_ICONASTERISK
  139.         },
  140.  
  141.         { VMERR_COMMIT_ON_COMMITTED,
  142.           "%s\n\nCommit Memory specified for"
  143.           " previously"
  144.           " committed memory. Choose \"Default\" or \""
  145.           "Decommit\" for committed memory.",
  146.           MB_ICONASTERISK
  147.         },
  148.  
  149.         { VMERR_COMMIT_ONLY,
  150.           "%s\n\nCommit Memory specified with"
  151.           " no access"
  152.           " protection specifed. Access protection required when"
  153.           " committing memory.",
  154.           MB_ICONASTERISK
  155.         },
  156.  
  157.         { VMERR_SET_NO_PARMS,
  158.           "%s\n\nNo parameters specified. Parameters"
  159.           " must be specified when using %s.",
  160.           MB_ICONASTERISK
  161.         },
  162.  
  163.         { VMERR_SET_ZERO_SIZE,
  164.           "%s\n\nSetting allocation attributes and/or access protection"
  165.           " on zero bytes is not permitted."
  166.           " A minimum size of one byte must be specified to set"
  167.           " allocation attributes and/or access protection on memory.",
  168.           MB_ICONASTERISK
  169.         },
  170.  
  171.         { VMERR_SET_ON_FREE,
  172.           "%s\n\nSetting allocation attributes and/or access protection"
  173.           " on non-allocated memory is not"
  174.           " permitted. Memory must be allocated before allocation attributes"
  175.           " or access protection may be specified for it.",
  176.           MB_ICONASTERISK
  177.         },
  178.  
  179.         { VMERR_DEFAULT,
  180.           "%s\n\n Error #%u occured during the call.",
  181.           MB_ICONASTERISK
  182.         }
  183.     };
  184.  
  185. /****************************************************************\
  186.  *  DOS API and Application Specific Error reporting routine    *
  187.  *--------------------------------------------------------------*
  188.  *                                                              *
  189.  *  Name:    VMM_Error(pszFunction, ulErrorCode)                *
  190.  *                                                              *
  191.  *  Purpose: Display errors returned by system calls to         *
  192.  *           the user when they occur. All other error handling *
  193.  *           is done inside the functions themselves            *
  194.  *                                                              *
  195.  *  Usage:   Routine is called for each error that the dialog   *
  196.  *           functions do not process                           *
  197.  *                                                              *
  198.  *  Method:  A switch statement branches control based upon     *
  199.  *           the error number passed. Any message that comes    *
  200.  *           in that is not known is given a generic message.   *
  201.  *           The message is displayed with WinMessageBox        *
  202.  *                                                              *
  203.  *  Returns: VOID                                               *
  204.  *                                                              *
  205. \****************************************************************/
  206. VOID VMM_Error(PSZ pszFunction, ULONG ulErrorCode)
  207. {
  208.     CHAR    szTempBuf[BUFF_SIZE];
  209.     ULONG   ulMsgIndex;
  210.  
  211.     ulMsgIndex = 0L;
  212.                                                  /* Serach error message */
  213.     while((amsgentry[ulMsgIndex].ulMsgNum != ulErrorCode) &&
  214.           (amsgentry[ulMsgIndex].ulMsgNum != VMERR_DEFAULT))
  215.         ulMsgIndex++;
  216.  
  217.     strcpy(szTempBuf,amsgentry[ulMsgIndex].szMsgText);
  218.  
  219.     if (amsgentry[ulMsgIndex].ulMsgNum == VMERR_DEFAULT)
  220.     {
  221.         sprintf(szBuffer,szTempBuf,pszFunction,ulErrorCode);
  222.     }
  223.     else if (amsgentry[ulMsgIndex].ulMsgNum == VMERR_MAX_ALLOCATED)
  224.     {
  225.         sprintf(szBuffer,szTempBuf,pszFunction,MAXPAGES);
  226.     }
  227.     else if (amsgentry[ulMsgIndex].ulMsgNum == VMERR_SET_NO_PARMS)
  228.     {
  229.         sprintf(szBuffer,szTempBuf,pszFunction,pszFunction);
  230.     }
  231.     else
  232.     {
  233.         sprintf(szBuffer,szTempBuf,pszFunction);
  234.     }
  235.     WinAlarm(HWND_DESKTOP, WA_ERROR);
  236.     WinMessageBox(HWND_DESKTOP,
  237.                   hwndMain,
  238.                   szBuffer,
  239.                   szAppName,
  240.                   0,
  241.                   MB_OK | MB_MOVEABLE | amsgentry[ulMsgIndex].usMsgIcon);
  242.     return;
  243. }
  244.  
  245. /****************************************************************\
  246.  *  Procedure to remove freed pages from array                  *
  247.  *--------------------------------------------------------------*
  248.  *                                                              *
  249.  *  Name:    CleanUpArray(pvAddress)                            *
  250.  *                                                              *
  251.  *  Purpose: Remove pages that the user indicated from the      *
  252.  *           array of pages stored                              *
  253.  *                                                              *
  254.  *  Usage:   Routine is called after each successful free       *
  255.  *           memory call issued by the user                     *
  256.  *                                                              *
  257.  *  Method:  Pages are removed by finding the address in the    *
  258.  *           array that matches what the user input, and then   *
  259.  *           removing all subsequent pages until another base   *
  260.  *           page is found or the last stored page is reached   *
  261.  *                                                              *
  262.  *  Returns: VOID                                               *
  263.  *                                                              *
  264. \****************************************************************/
  265. VOID CleanUpArray(PVOID pvAddress)
  266. {
  267.     ULONG   ulIndexLow;
  268.     ULONG   ulIndexHigh;
  269.  
  270.     /* At entry, we know that the pvAddress page is a base page and we
  271.        need to free up the pages associated with the base page for the
  272.        object. To do this, we find the next base address. We then make
  273.        the copies. */
  274.  
  275.     ulIndexLow = 0;
  276.                                             /* Look for the pointed page */
  277.     while((apgentry[ulIndexLow].pvAddress != pvAddress) &&
  278.           (ulIndexLow < ulFreePage))
  279.         ulIndexLow++;
  280.  
  281.     if (ulIndexLow < ulFreePage)
  282.     {
  283.         apgentry[ulIndexLow].fBaseAddr = FALSE;
  284.         ulIndexHigh = ulIndexLow + 1;
  285.                                           /* Look for the next base page */
  286.         while((apgentry[ulIndexHigh].fBaseAddr == FALSE) &&
  287.               (ulIndexHigh < ulFreePage))
  288.             ulIndexHigh++;
  289.  
  290.         while(ulIndexHigh < ulFreePage)
  291.             apgentry[ulIndexLow++] = apgentry[ulIndexHigh++];
  292.  
  293.         ulFreePage -= (ulIndexHigh-ulIndexLow);/* Reset the starting page */
  294.         MessageBox(HWND_DESKTOP, IDMSG_SUCCESSFREE, "Note !",  MB_OK, FALSE);
  295.     }
  296.               /* If DosFreeMem worked but the address is not in our page
  297.               array, then don't modify the array or the ulFreePage count. */
  298.  
  299.     if (!ulFreePage)         /* No memory is allocated */
  300.     {
  301.        EnableMenuItem(hwndMain,IDM_VMMFREE,FALSE);
  302.        EnableMenuItem(hwndMain,IDM_VMMSET,FALSE);
  303.        EnableMenuItem(hwndMain,IDM_VMMWRITE,FALSE);
  304.        EnableMenuItem(hwndMain,IDM_VMMREAD,FALSE);
  305.     }
  306.     return;
  307. }
  308.  
  309. /****************************************************************\
  310.  *  Procedure to store allocated pages in array                 *
  311.  *--------------------------------------------------------------*
  312.  *                                                              *
  313.  *  Name:    StoreInArray(pvAddress,ulNumPages)                 *
  314.  *                                                              *
  315.  *  Purpose: Store pages that were just successfully allocated  *
  316.  *           in our array so we can track them                  *
  317.  *                                                              *
  318.  *  Usage:   Routine is called after each successful allocation *
  319.  *           of memory by the user                              *
  320.  *                                                              *
  321.  *  Method:  The pages are added to the end of the array based  *
  322.  *           upon the current status of our global end of array *
  323.  *           index variable (ulFreePage)                        *
  324.  *                                                              *
  325.  *  Returns: VOID                                               *
  326.  *                                                              *
  327. \****************************************************************/
  328. VOID StoreInArray(PVOID pvAddress, ULONG ulNumPages )
  329. {
  330.     ULONG   temp;
  331.  
  332.     /* Set all base indicators for the new pages to FALSE, and set the
  333.        addresses for the pages. */
  334.  
  335.     for(temp = 0L; temp < ulNumPages; temp++)
  336.     {
  337.         apgentry[temp+ulFreePage].pvAddress = (PVOID)((ULONG)pvAddress +
  338.                                               (PAGESIZE * temp));
  339.         apgentry[temp+ulFreePage].fBaseAddr = FALSE;
  340.     }
  341.     /* Set the base indicator of the first page in the object to be
  342.        TRUE */
  343.     apgentry[ulFreePage].fBaseAddr = TRUE;
  344.     ulFreePage += ulNumPages;       /* Move to new starting of free page */
  345.  
  346.     EnableMenuItem(hwndMain,IDM_VMMFREE,TRUE);
  347.     EnableMenuItem(hwndMain,IDM_VMMSET,TRUE);
  348.     EnableMenuItem(hwndMain,IDM_VMMWRITE,TRUE);
  349.     EnableMenuItem(hwndMain,IDM_VMMREAD,TRUE);
  350.     return;
  351. }
  352.  
  353. /****************************************************************\
  354.  *  Non-standard menu item command processing procedure         *
  355.  *--------------------------------------------------------------*
  356.  *                                                              *
  357.  *  Name:   UserCommand(mp1, mp2)                               *
  358.  *                                                              *
  359.  *  Purpose: Process any WM_COMMAND messages send to hwndMain   *
  360.  *              that are not processed by MainCommand           *
  361.  *                                                              *
  362.  *  Usage:  Routine is called for each WM_COMMAND that is       *
  363.  *          not posted by a standard menu item                  *
  364.  *                                                              *
  365.  *  Method: A switch statement branches control based upon      *
  366.  *          the id of the control which posted the message      *
  367.  *                                                              *
  368.  *  Returns:                                                    *
  369. \****************************************************************/
  370. VOID UserCommand(MPARAM mp1, MPARAM mp2)
  371. {
  372.    PVOID   pvMemAddress=0L;
  373.  
  374.    ULONG   ulTempRegionSize;
  375.    ULONG   flTempAttributes=0L;
  376.  
  377.    ULONG   ulPages;                /* Number of pages requested by user */
  378.    ULONG   rc;                      /* Return Code variable from calls  */
  379.    ULONG   rc2;         /* Return Code variable for investigative calls */
  380.  
  381.    switch(SHORT1FROMMP(mp1))
  382.    {
  383.    /*--------------------------------------------------------------*\
  384.     *  Add case statements for menuitem ids you wish to process    *
  385.    \*--------------------------------------------------------------*/
  386.       case IDM_VMMALLOC:
  387.           ObjAlloc.ulSize = 4;         /* Default size 4 k to allocate */
  388.           ObjAlloc.ulAttr =                          /* Default attrib */
  389.                     PAG_READ | PAG_WRITE | PAG_EXECUTE;
  390.           ObjAlloc.pvAddress = '\000';
  391.  
  392.           if(WinDlgBox(HWND_DESKTOP,
  393.                        hwndMain,
  394.                        (PFNWP) AllocMemDlgProc,
  395.                        (HMODULE)0,
  396.                        (ULONG) IDD_ALLOCMEM,
  397.                        (PVOID) &ObjAlloc) )
  398.           {
  399.                           /* Figure out the number of pages requested. */
  400.               ulPages = (ObjAlloc.ulSize / PAGESIZE);
  401.               if ((ObjAlloc.ulSize % PAGESIZE) != 0L)
  402.                   ulPages++;                          /* One more page */
  403.  
  404.               /* If the number of pages requested is zero (zero
  405.                  bytes specified), or the number of pages is greater
  406.                  than the number left in the array, report the error
  407.                  condition. Otherwise, make the DosAllocMem call and
  408.                  set any error condition returned by the call. */
  409.  
  410.               if (ulPages == 0L)
  411.               {
  412.                   rc = VMERR_ZERO_ALLOCATED;
  413.               }
  414.               else if (ulPages + ulFreePage > MAXPAGES + 1)
  415.               {
  416.                   rc = VMERR_MAX_ALLOCATED;
  417.               }
  418.               else
  419.               {
  420.                   rc = DosAllocMem(&pvMemAddress,
  421.                                    ObjAlloc.ulSize,
  422.                                    ObjAlloc.ulAttr);
  423.               }
  424.               /* If an error has occured, display it. Otherwise,
  425.                  process the request. */
  426.  
  427.               if (rc != 0L)
  428.               {
  429.                   if (ObjAlloc.ulAttr == 0L)
  430.                   {
  431.                       rc = VMERR_SET_NO_PARMS;
  432.                   }
  433.                   else if (ObjAlloc.ulAttr == PAG_COMMIT)
  434.                   {
  435.                       rc = VMERR_COMMIT_ONLY;
  436.                   }
  437.                   else if (ObjAlloc.ulAttr == (PAG_COMMIT | OBJ_TILE))
  438.                   {
  439.                       rc = VMERR_COMMIT_AND_TILE_ONLY;
  440.                   }
  441.                   else if (ObjAlloc.ulAttr == OBJ_TILE)
  442.                   {
  443.                       rc = VMERR_TILE_ONLY;
  444.                   }
  445.                   VMM_Error("DosAllocMem()",rc);
  446.               }
  447.               else
  448.               {
  449.                   StoreInArray(pvMemAddress,ulPages);
  450.                   WinInvalidateRect(hwndMain, NULL, TRUE);
  451.               }
  452.           }
  453.           break;
  454.  
  455.       case IDM_VMMFREE:
  456.  
  457.           ObjAlloc.pvAddress = '\000';
  458.           if (WinDlgBox(HWND_DESKTOP,
  459.                     hwndMain,
  460.                     (PFNWP) FreeMemDlgProc,
  461.                     (HMODULE)0,
  462.                     (ULONG) IDD_FREEMEM,
  463.                     (PVOID) &ObjAlloc ) != 0)
  464.           {
  465.               rc = DosFreeMem(ObjAlloc.pvAddress);
  466.  
  467.               if (rc != 0L)
  468.               {                                  /* DosFreeMem is fail */
  469.                   /* Try to figure out why the error occured based
  470.                      on actual page attributes of page requested to be
  471.                      freed. */
  472.                   rc2 = DosQueryMem(ObjAlloc.pvAddress,
  473.                                     &ulTempRegionSize,
  474.                                     &flTempAttributes);
  475.                   if (rc2 == 0L)
  476.                   /* If the page requested to be freed was already
  477.                      in the freed state, or the requested page in the
  478.                      object to be freed is not the base page of the
  479.                      object, set the appropriate error condition. */
  480.                   {
  481.                       if ((flTempAttributes & PAG_FREE) != 0L)
  482.                       {
  483.                           rc = VMERR_ALREADY_FREED;
  484.                       }
  485.                       else if ((flTempAttributes & PAG_BASE) == 0L)
  486.                       {
  487.                           rc = VMERR_NOT_BASEPAGE;
  488.                       }
  489.                   }
  490.                   VMM_Error("DosFreeMem()",rc);
  491.               }
  492.               else
  493.               {
  494.                   CleanUpArray(ObjAlloc.pvAddress);
  495.                   WinInvalidateRect(hwndMain, NULL, TRUE);
  496.               }
  497.           }
  498.           break;
  499.  
  500.       case IDM_VMMSET:
  501.  
  502.           ObjAlloc.pvAddress = '\000';
  503.           if (WinDlgBox(HWND_DESKTOP,
  504.                         hwndMain,
  505.                         (PFNWP) SetMem1DlgProc,
  506.                         (HMODULE)0,
  507.                         (ULONG) IDD_SETMEM1,
  508.                         (PVOID) &ObjAlloc ))
  509.           {
  510.               if (WinDlgBox(HWND_DESKTOP,
  511.                             hwndMain,
  512.                             (PFNWP) SetMem2DlgProc,
  513.                             (HMODULE)0,
  514.                             (ULONG) IDD_SETMEM2,
  515.                             (PVOID) &ObjAlloc ))
  516.               {
  517.                   rc = DosSetMem(ObjAlloc.pvAddress,
  518.                                  ObjAlloc.ulSize,
  519.                                  ObjAlloc.ulAttr);
  520.  
  521.                   /* If an error occured making the DosSetMem call,
  522.                      try to figure out the cause of the error by
  523.                      studying the requested access and the access on
  524.                      the memory prior to the DosSetMem call. */
  525.  
  526.                   if (rc != 0L)
  527.                   {
  528.                       ulTempRegionSize = 1L;
  529.  
  530.                       rc2 = DosQueryMem(ObjAlloc.pvAddress,
  531.                                         &ulTempRegionSize,
  532.                                         &flTempAttributes);
  533.                       if (rc2 == 0L)
  534.                       {
  535.                           rc = 0L;
  536.                           /* If no attributes, commit with no other
  537.                              attributes, or a size of zero was
  538.                              specified, set the appropriate error
  539.                              condition. */
  540.  
  541.                           if (ObjAlloc.ulAttr == 0L)
  542.                           {
  543.                               rc = VMERR_SET_NO_PARMS;
  544.                           }
  545.                           else if (ObjAlloc.ulAttr == PAG_COMMIT)
  546.                           {
  547.                               rc = VMERR_COMMIT_ONLY;
  548.                           }
  549.                           else if (ObjAlloc.ulSize == 0L)
  550.                           {
  551.                               rc = VMERR_SET_ZERO_SIZE;
  552.                           }
  553.                           /* If memory is not allocated then set
  554.                              error condition. */
  555.  
  556.                           else if ((ObjAlloc.ulAttr & PAG_FREE) != 0L)
  557.                           {
  558.                               rc = VMERR_SET_ON_FREE;
  559.                           }
  560.                           /* If the memory was already in the
  561.                              reserved state and the user attempted to
  562.                              decommit it or set attributes for it, set
  563.                              the error condition. */
  564.  
  565.                           else if ((flTempAttributes & PAG_COMMIT) == 0L)
  566.                           {
  567.                               if ((ObjAlloc.ulAttr & PAG_DECOMMIT) != 0L)
  568.                               {
  569.                                   rc = VMERR_DECOMMIT_RESERVED;
  570.                               }
  571.                               else if ((ObjAlloc.ulAttr & ~PAG_COMMIT) != 0L)
  572.                               {
  573.                                   rc = VMERR_ACCESS_ON_RESERVED;
  574.                               }
  575.                           }
  576.                           /* If the memory was in a committed state
  577.                              and the user attempted to decommit it and
  578.                              set attributes, or the user attempts to
  579.                              commit the memory, set the appropriate
  580.                              error condition. */
  581.                           else
  582.                           {
  583.                               if (((ObjAlloc.ulAttr &  PAG_DECOMMIT) != 0L)
  584.                                 && ((ObjAlloc.ulAttr & ~PAG_DECOMMIT) != 0L))
  585.                               {
  586.                                   rc = VMERR_ACCESS_AND_DECOMMIT;
  587.                               }
  588.                               else if ((ObjAlloc.ulAttr & PAG_COMMIT) != 0L)
  589.                               {
  590.                                   rc = VMERR_COMMIT_ON_COMMITTED;
  591.                               }
  592.                           }
  593.                       }
  594.                       VMM_Error("DosSetMem()",rc);
  595.                   }
  596.                   else
  597.                   {
  598.                       WinInvalidateRect(hwndMain, NULL, TRUE);
  599.                   }
  600.               }
  601.           }
  602.           break;
  603.  
  604.       case IDM_VMMWRITE:
  605.  
  606.           ObjAlloc.pvAddress = '\000';
  607.           if (WinDlgBox(HWND_DESKTOP,
  608.                         hwndMain,
  609.                         (PFNWP) WriteMemDlgProc,
  610.                         (HMODULE)0,
  611.                         (ULONG) IDD_WRITEMEM,
  612.                         (PVOID) NULL))
  613.  
  614.               WinInvalidateRect(hwndMain, NULL, TRUE);
  615.           break;
  616.  
  617.       case IDM_VMMREAD:
  618.  
  619.           ObjAlloc.pvAddress = '\000';
  620.           if (WinDlgBox(HWND_DESKTOP,
  621.                         hwndMain,
  622.                         (PFNWP) ReadMemDlgProc,
  623.                         (HMODULE)0,
  624.                         (ULONG) IDD_READMEM,
  625.                         (PVOID) &ObjAlloc ))
  626.           {
  627.              if ( *( (CHAR *)(ObjAlloc.pvAddress) )== 0L )
  628.              {
  629.               sprintf(szBuffer, "Address %p doesn't contain data.",
  630.                                     ObjAlloc.pvAddress);
  631.              } else {
  632.                      sprintf(szBuffer, "Address %p contains\n %s",
  633.                                ObjAlloc.pvAddress, ObjAlloc.pvAddress);
  634.                     }
  635.               WinMessageBox(HWND_DESKTOP,
  636.                             hwndMain,
  637.                             szBuffer,
  638.                             "Read Memory",
  639.                             0,
  640.                             MB_INFORMATION| MB_OK | MB_MOVEABLE);
  641.  
  642.               WinInvalidateRect(hwndMain, NULL, TRUE);
  643.           }
  644.           break;
  645.  
  646.       default:
  647.           break;
  648.    }
  649.    /* This routine currently doesn't use the mp2 parameter but       *\
  650.     *  it is referenced here to prevent an 'Unreferenced Parameter'  *
  651.    \*  warning at compile time.                                      */
  652.    return;
  653. }                                                    /* UserCommand() */
  654.