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