home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / cmccli / pvalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  7.4 KB  |  324 lines

  1. /*
  2.  -  P V A L L O C . C
  3.  -
  4.  *  Copyright (C) 1995 Microsoft Corporation
  5.  *  Purpose:
  6.  *      Implementation of a chained memory manager.
  7.  *
  8.  */
  9.  
  10. #include <string.h>
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <pvalloc.h>
  15.  
  16. #ifdef _DEBUG
  17. static CB       cbTotalAlloc    = 0;
  18. static CB       ulTotalBlockNum = 0;
  19. #endif
  20.  
  21. /*
  22.  -  PvAlloc
  23.  -
  24.  *  Purpose:
  25.  *      Allocates a chunk of memory on the global heap.
  26.  *
  27.  *  Parameters:
  28.  *      cbSize          - Count of bytes requested.
  29.  *
  30.  *  Returns:
  31.  *      lpv             - Pointer to the allocated memory
  32.  *
  33.  */
  34.  
  35. PV PvAlloc(CB cbSize)
  36. {
  37.     PV      lpv         = pvNull;
  38.     HANDLE  hMem;
  39.     PPVINFO ppvinfo;
  40. #ifdef _DEBUG
  41.     char    szFileName[80];
  42.     LPSTR   lpszTemp    = NULL;
  43.     FILE    *pFile      = NULL;
  44.     char    szBuff[128];
  45. #endif
  46.  
  47.     /* Make sure allocations are in multiples of 4 */
  48.  
  49.     if(cbSize < 4)
  50.         cbSize = 4;
  51.     else if(cbSize & 3)
  52.         cbSize += 4 - (cbSize & 3);
  53.  
  54.     /* Allocate the block */
  55.  
  56.     hMem = GlobalAlloc(GMEM_MOVEABLE, cbSize + sizeof(PVINFO));
  57.     if(hMem)
  58.     {
  59.         ppvinfo = (PPVINFO)GlobalLock(hMem);
  60.         ppvinfo->hMem    = hMem;
  61.         ppvinfo->lpvNext = pvNull;
  62.         ppvinfo->lpvBuf  = ((PB)ppvinfo) + sizeof(PVINFO);
  63. #ifdef _DEBUG
  64.         ppvinfo->cbSize  = cbSize;
  65.         ulTotalBlockNum++;
  66.         ppvinfo->ulBlockNum = ulTotalBlockNum;
  67.         cbTotalAlloc += cbSize;
  68.         
  69.         // log to file
  70.         lpszTemp = getenv("TEMP");
  71.  
  72.         if(lpszTemp)
  73.             strcpy(szFileName, lpszTemp);
  74.         else
  75.             strcpy(szFileName, "c:\\temp");
  76.  
  77.         strcat(szFileName, "\\pvalloc.log");
  78.  
  79.         
  80.         pFile = fopen(szFileName,"a");
  81.         if (pFile == NULL)     
  82.             goto NoFile;      
  83. //           return NULL;
  84.  
  85.         fprintf(pFile, "Block: \t%lu\tPvAlloc: %ld Bytes\t\tTotal: %ld Bytes\n",
  86.                  ulTotalBlockNum, cbSize, cbTotalAlloc);
  87.  
  88.         if (pFile)
  89.             fclose(pFile);
  90.         
  91.         // log to comm port
  92.         wsprintf(szBuff,"Block: \t%lu\tPvAlloc: %ld Bytes\t\tTotal: %ld Bytes\n",
  93.                  ulTotalBlockNum, cbSize, cbTotalAlloc);
  94.         OutputDebugString(szBuff);
  95.                         
  96. NoFile:                           
  97.  
  98. #ifdef WIN32
  99.         memset(ppvinfo->lpvBuf, 0xaa, (size_t)cbSize);
  100. #else
  101.         _fmemset(ppvinfo->lpvBuf, 0xaa, (size_t)cbSize);
  102. #endif  /* WIN32 */
  103.  
  104. #endif  /* _DEBUG */
  105.         lpv = ppvinfo->lpvBuf;
  106.     }
  107.  
  108.     return lpv;
  109. }
  110.  
  111. /*
  112.  -  PvAllocMore
  113.  -
  114.  *  Purpose:
  115.  *      Allocates a chunk of memory and chains it to a parent block.
  116.  *
  117.  *  Parameters:
  118.  *      cbSize          - Count of additional bytes to allocate
  119.  *      lpvParent       - Pointer to parent in memory chain
  120.  *
  121.  *  Returns:
  122.  *      lpv             - Pointer to the allocated memory
  123.  *
  124.  */
  125.  
  126. PV PvAllocMore(CB cbSize, PV lpvParent)
  127. {
  128.     PV          lpvStep = lpvParent;
  129.     PV          lpv     = pvNull;
  130.     PPVINFO     ppvinfoMore;
  131.     HANDLE      hMem;
  132.     PPVINFO     ppvinfo;
  133.  
  134.     /* Step to the last link */
  135.     do
  136.     {
  137.         ppvinfoMore = (PPVINFO)(((PB)lpvStep) - sizeof(PVINFO));
  138.         lpvStep = ppvinfoMore->lpvNext;
  139.     }
  140.     while(ppvinfoMore->lpvNext != pvNull);
  141.  
  142.     // beginning of section that was taken from PvAlloc
  143.  
  144.     if(cbSize < 4)
  145.         cbSize = 4;
  146.     else if(cbSize & 3)
  147.         cbSize += 4 - (cbSize & 3);
  148.  
  149.  
  150.     hMem = GlobalAlloc(GMEM_MOVEABLE, cbSize + sizeof(PVINFO));
  151.     if(hMem)
  152.     {
  153.         ppvinfo = (PPVINFO)GlobalLock(hMem);
  154.         ppvinfo->hMem       = hMem;
  155.         ppvinfo->lpvNext    = pvNull;
  156.         ppvinfo->lpvBuf     = ((PB)ppvinfo) + sizeof(PVINFO);
  157. #ifdef _DEBUG
  158.         ppvinfo->cbSize     = cbSize;
  159.         ppvinfo->ulBlockNum = ppvinfoMore->ulBlockNum;
  160.         cbTotalAlloc += cbSize;
  161.  
  162. #ifdef WIN32
  163.         memset(ppvinfo->lpvBuf, 0xaa, (size_t)cbSize);
  164. #else
  165.         _fmemset(ppvinfo->lpvBuf, 0xaa, (size_t)cbSize);
  166. #endif
  167.  
  168. #endif
  169.         lpv = ppvinfo->lpvBuf;
  170.     }
  171.     else
  172.         return lpv;
  173.         
  174.     // end of section taken from pvalloc
  175.  
  176. #ifdef WIN32
  177.         memset(lpv, 0xbb, (size_t)cbSize);
  178. #else
  179.         _fmemset(lpv, 0xbb, (size_t)cbSize);
  180. #endif  /* WIN32 */
  181.  
  182.     ppvinfoMore->lpvNext = lpv;
  183.  
  184.     return lpv;
  185. }
  186.  
  187.  
  188.  
  189. /*
  190.  -  PvFree
  191.  -
  192.  *  Purpose:
  193.  *      This function frees memory allocated by PvAlloc or PvAllocMore.
  194.  *      After the call, the pointer memory will be invalid and should
  195.  *      not be referenced again.
  196.  *      When memory is allocated by PvAlloc and PvAllocMore, which can
  197.  *      contain several levels of pointers, all the application needs to
  198.  *      do to free the entire structure is call this routine with the
  199.  *      base pointer returned by the PvAlloc call.
  200.  *
  201.  *  Parameters:
  202.  *      lpv             - Pointer to memory to be freed.
  203.  *
  204.  *  Returns:
  205.  *      Void
  206.  *
  207.  */
  208.  
  209. BOOL PvFree(PV lpv)
  210. {
  211.     PPVINFO ppvinfo;
  212. #ifdef _DEBUG
  213.     CB      cbSize;
  214.     CB      ulBlockNum;
  215.     FILE    *pFile  = NULL;
  216.     CB      cbFree  = 0;
  217.     CB      cbTotalBeforeFree = cbTotalAlloc;
  218.     char    szFileName[80];
  219.     LPSTR   lpszTemp    = NULL;
  220.     char    szBuff[128];
  221. #endif
  222.  
  223.     if(!lpv)
  224.         return 0;
  225.  
  226.     ppvinfo = (PPVINFO)(((PB)lpv) - sizeof(PVINFO));
  227.  
  228.     while(ppvinfo)
  229.     {
  230.         lpv = ppvinfo->lpvNext;
  231.  
  232. #ifdef _DEBUG
  233.         cbSize      = ppvinfo->cbSize;
  234.         cbFree      += ppvinfo->cbSize;
  235.         ulBlockNum  = ppvinfo->ulBlockNum;
  236.  
  237. #ifdef WIN32
  238.         memset(ppvinfo->lpvBuf, 0xcc, (size_t)ppvinfo->cbSize);
  239. #else
  240.         _fmemset(ppvinfo->lpvBuf, 0xcc, (size_t)ppvinfo->cbSize);
  241. #endif  /* WIN32 */
  242.  
  243. #endif  /* _DEBUG */
  244.  
  245.         if(GlobalUnlock(ppvinfo->hMem))
  246.             goto err;  // Our lock count is non-zero
  247.  
  248.         if(GlobalFree(ppvinfo->hMem))
  249.             goto err;  // Failure
  250.  
  251. #ifdef _DEBUG
  252.         cbTotalAlloc -= cbSize;
  253. #endif
  254.  
  255.         if(lpv)
  256.             ppvinfo = (PPVINFO)(((PB)lpv) - sizeof(PVINFO));
  257.         else
  258.             break;
  259.     }
  260.  
  261.  
  262. #ifdef _DEBUG
  263.     
  264.     if((cbTotalBeforeFree - cbTotalAlloc) != cbFree)
  265.        goto err;
  266.        
  267.     // log to file
  268.     lpszTemp = getenv("TEMP");
  269.  
  270.     if(lpszTemp)
  271.         strcpy(szFileName, lpszTemp);
  272.     else
  273.         strcpy(szFileName, "c:\\temp");
  274.  
  275.     strcat(szFileName, "\\pvalloc.log");
  276.         
  277.     pFile = fopen(szFileName,"a");
  278.        
  279.     if (pFile == NULL)
  280.        goto err;
  281.  
  282.     fprintf(pFile, "Block: \t%lu\t\t***PvFree***,  Freeing  %lu Bytes(Alloc and AllocMore)\tUnFreed: %ld Bytes\n",
  283.                     ulBlockNum, cbFree, cbTotalAlloc);
  284.     if (pFile)
  285.         fclose(pFile);
  286.  
  287.      // log to comm port
  288.     wsprintf(szBuff,"Block: \t%lu\t\t***PvFree***,  Freeing  %lu Bytes(Alloc and AllocMore)\tUnFreed: %ld Bytes\n",
  289.                     ulBlockNum, cbFree, cbTotalAlloc);
  290.     OutputDebugString(szBuff);
  291.  
  292. #endif  /* _DEBUG */
  293.  
  294.     return 0; // Success!
  295.  
  296. err:
  297. #ifdef _DEBUG
  298.  
  299.     // find file to open
  300.     lpszTemp = getenv("TEMP");
  301.  
  302.     if(lpszTemp)
  303.         strcpy(szFileName, lpszTemp);
  304.     else
  305.         strcpy(szFileName, "c:\\temp");
  306.  
  307.     strcat(szFileName, "\\pvalloc.log");
  308.  
  309.         
  310.     pFile = fopen(szFileName,"a");
  311.  
  312.     if (pFile == NULL)
  313.        return 1;
  314.  
  315.     fprintf(pFile, "Block: %lu Failure freeing: %ld Bytes\tUnFreed: %ld Bytes\n",
  316.              ulBlockNum, cbSize, cbTotalAlloc);
  317.     if (pFile)
  318.         fclose(pFile);
  319.  
  320. #endif  /* _DEBUG */
  321.  
  322.     return 1; // Failure!
  323. }
  324.