home *** CD-ROM | disk | FTP | other *** search
- /*
- BASED.C -- based pointer routines for Windows
-
- See also WINHEAP.C
-
- Copyright (c) Andrew Schulman, 1990-1992.
- All Rights Reserved.
-
- Contact: Andrew Schulman (CompuServe 76320,302)
-
- From "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- NOTE: This is for Microsoft C only. Would require some
- tweaking to make work with Borland.
- */
-
- #include <windows.h>
- #include <malloc.h>
- #include "winio.h"
-
- #ifdef __BORLANDC__
- #include "based.h"
- #endif
-
- /* Allocate a based heap, and return a segment value that should be used
- by subsequent based-heap functions */
- _segment _bheapseg(size_t size)
- {
- WORD blk;
- blk = GlobalAlloc(GMEM_FIXED | GMEM_NODISCARD | GMEM_ZEROINIT, size);
- if (blk == 0)
- return -1;
- if (LocalInit(blk, 0, size-1) == 0) /* calls GlobalLock */
- return -1;
- /* succeeded */
- return blk;
- }
-
- /* Free a based heap */
- int _bfreeseg(_segment seg)
- {
- GlobalUnlock(seg);
- return (GlobalFree(seg) == NULL) ? 0 : -1;
- }
-
- /* Allocate a block of memory from a heap; the segment value must have
- been previously returned by _bheapseg */
- void _based(void) *_bmalloc(_segment segm, size_t size)
- {
- unsigned ret;
- if (segm) // if (segm==0) use default data segment
- {
- _asm push ds
- _asm mov ax, segm
- _asm mov ds, ax
- }
- if (ret = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, size))
- ret = (unsigned) LocalLock(ret);
- if (segm)
- _asm pop ds
- return (void _based(void) *) ret;
- }
-
- /* Allocate storage for an array, zero-initialize the elements of the
- array, and return a based pointer to the array */
- void _based(void) *_bcalloc(_segment segm, size_t num, size_t size)
- {
- return _bmalloc(segm, num * size);
- }
-
- /* Free an allocated block */
- void _bfree(_segment segm, void _based(void) *memblock)
- {
- if (((unsigned) memblock) == 0xFFFF)
- return;
- if (segm)
- {
- _asm push ds
- _asm mov ax, segm
- _asm mov ds, ax
- }
- LocalUnlock((WORD) memblock);
- LocalFree((WORD) memblock);
- if (segm)
- _asm pop ds
- }
-
- /* Helper function used by _bexpand and _brealloc */
- static void _based(void) *_bresize(_segment segm,
- void _based(void) *memblock, size_t size, WORD wFlags)
- {
- unsigned ret;
- if (segm)
- {
- _asm push ds
- _asm mov ax, segm
- _asm mov ds, ax
- }
- ret = (unsigned) LocalReAlloc((char near *) memblock, size,
- wFlags | LMEM_ZEROINIT);
- if (segm)
- _asm pop ds
- return (void _based(void) *) ret;
- }
-
- /* Expand or shrink an allocated block in place */
- void _based(void) *_bexpand(_segment segm,
- void _based(void) *memblock, size_t size)
- {
- return _bresize(segm, memblock, size, LMEM_FIXED);
- }
-
- /* Expand or shrink an allocated block, possibly moving it */
- void _based(void) *_brealloc(_segment segm,
- void _based(void) *memblock, size_t size)
- {
- return _bresize(segm, memblock, size, LMEM_MOVEABLE);
- }
-
- /* Return the size of a previously allocated block */
- size_t _bmsize(_segment segm, void _based(void) *memblock)
- {
- WORD ret;
- if (segm)
- {
- _asm push ds
- _asm mov ax, segm
- _asm mov ds, ax
- }
- ret = LocalSize((WORD) memblock);
- if (segm)
- _asm pop ds
- return ret;
- }
-