summaryrefslogblamecommitdiffstats
path: root/private/sdktools/damage/map.c
blob: e99115903fa7b96037aec12ad786a9f8cde71735 (plain) (tree)


























































































































































































































































































                                                                                
/*****************************************************************/ 
/**		     Microsoft LAN Manager			**/ 
/**	       Copyright(c) Microsoft Corp., 1988-1990		**/ 
/*****************************************************************/ 
/***	MAP.C - Routines to manipulate disk maps and allocate memory
 *
 *	DAMAGE
 *	Gregory A. Jones
 *
 *	Modification history:
 *	G.A. Jones	06/02/88	Original for Pinball 1.0.
 *	G.A. Jones	09/07/88	Adapted from CHKDSK's MAP.C and MEM.C.
 *	G.A. Jones	09/08/88	Coded get_object.
 *	G.A. Jones	09/19/88	Set dirty flag to FALSE on new object.
 */

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "defs.h"
#include "types.h"
#include "globals.h"

/***	clr_bit - clear a bit in a bitmap
 *
 *	This routine is called to clear a bit in a bitmap.  This
 *	indicates a sector in use by the file system.
 *
 *	clr_bit (lsn)
 *
 *	ENTRY		lsn - sector number to allocate
 *
 *	EXIT		Return value 0 if success, 1 if no bitmap,
 *			2 if bad sector number
 *
 *	CALLS		None
 *
 *	EFFECTS         Clears a bit in the global bitmap
 *
 *	WARNINGS	Bitmap should be allocated first
 */
USHORT clr_bit (ULONG lsn)
{
  register ULONG byte;
  register USHORT bit;

#ifdef TRACE_BITS
  fprintf (stderr, "clr_bit (%lx)\n", lsn);
  fflush (stderr);
#endif

  if (!bitmap)			/* bitmap is not allocated yet */
    return (1);                 /* return error condition */

  if (lsn > number_of_sectors)	/* sector outside bitmap */
    return (2);                 /* return error condition */

  byte = lsn >> 3;		/* divide by 8 without a DIV */
  bit = (USHORT)(lsn & 7);      /* "mod" by 8 without a DIV */
  bitmap [byte] &= ~(1 << bit); /* clear the bit by ANDing with its inverse */

  return (0);
}

/***	set_bit - set a bit in a bitmap
 *
 *	This routine is called to set a bit in a bitmap.  This
 *	indicates a sector not in use by the file system.
 *
 *	set_bit (lsn)
 *
 *	ENTRY		lsn - sector number to free
 *
 *	EXIT		Return value 0 if success, 1 if no bitmap,
 *			2 if bad sector number
 *
 *	CALLS		None
 *
 *	EFFECTS         Sets a bit in the global bitmap
 *
 *	WARNINGS	Bitmap should be allocated first
 */
USHORT set_bit (ULONG lsn)
{
  register ULONG byte;
  register USHORT bit;

#ifdef TRACE_BITS
  fprintf (stderr, "set_bit (%lx)\n", lsn);
  fflush (stderr);
#endif

  if (!bitmap)			/* bitmap is not allocated yet */
    return (1);                 /* return error condition */

  if (lsn > number_of_sectors)	/* sector outside bitmap */
    return (2);                 /* return error condition */

  byte = lsn >> 3;		/* divide by 8 without a DIV */
  bit = (USHORT)(lsn & 7);      /* "mod" by 8 without a DIV */
  bitmap [byte] |= (1 << bit);  /* set the bit by ORing with it */

  return (0);
}

/***	allocate_block - allocate a memory chunk in multiples of 512 bytes
 *
 *	This function is called to allocate a block of memory which is
 *	a multiple of 512 bytes (one sector).  This is a useful tool for
 *	allocating a memory structure to store a run of sectors in.
 *
 *	BUGBUG - make this a macro to save stack and execution time?
 *
 *	allocate_block (nblocks)
 *
 *	ENTRY		nblocks - number of 512-byte blocks to allocate
 *
 *	EXIT		Returns NULL if insufficient memory, pointer if success
 *
 *      CALLS           malloc
 *
 *	EFFECTS         Allocates memory
 *
 *	WARNINGS	May return NULL pointer
 */
void *allocate_block (USHORT nblocks)
{
#ifdef TRACE
  fprintf (stderr, "allocate_block (%d)\n", nblocks);
  fflush (stderr);
#endif

  return (malloc (nblocks * BYTES_PER_SECTOR));
}

/***	free_block - free a memory chunk allocated by allocate_block
 *
 *	This function is called to free a block of memory which was
 *	allocated by the allocate_block function.
 *
 *	BUGBUG - make this a macro to save stack and execution time?
 *
 *	free_block (mem)
 *
 *	ENTRY		mem - pointer to memory to free
 *
 *	EXIT		No return value
 *
 *	CALLS		_ffree
 *
 *	EFFECTS         Deallocates memory
 *
 *	WARNINGS	"mem" will point to free space after this call
 */
void free_block (void *mem)
{
#ifdef TRACE
  fprintf (stderr, "free_block ()\n");
  fflush (stderr);
#endif

  free (mem);
}

/***	allocate_maps - allocate bit maps and disk map
 *
 *	This function is called to allocate memory for both copies of
 *	the bitmap, as well as CHKDSK's internal disk map.  The bit
 *	maps are not initialized, since they will be filled with disk
 *	data;  the disk map is initialized to DISK_UNKNOWN.
 *
 *	Memory for the bitmaps is allocate one block (2K) overlong so
 *	that reading the maps in will not overflow them.
 *
 *	allocate_maps (nsects)
 *
 *	ENTRY		nsects - number of sectors in partition
 *
 *	EXIT		No return value
 *
 *      CALLS           malloc
 *			memset
 *
 *	EFFECTS         Allocates memory
 *			Initializes disk map
 *
 *	WARNINGS	May exit program if insufficient memory
 */
void allocate_maps (ULONG nsects)
{
  ULONG i;

#ifdef TRACE
  fprintf (stderr, "allocate_maps ()\n");
  fflush (stderr);
#endif

  i = (nsects - 1L) / ((ULONG)BYTES_PER_BITMAP * 8L) + 2L;
  if (((bitmap  = calloc (i, 2048)) == NULL) ||
      ((bitmap2 = calloc (i, 2048)) == NULL))
    exit_error (INSF_MEM_ERROR);
}

/***	free_map - free a huge map
 *
 *	This function is called to free memory allocated for a bit
 *	map with halloc.
 *
 *	free_map (p)
 *
 *	ENTRY		p - pointer to memory to free
 *
 *	EXIT		No return value
 *
 *	CALLS		hfree
 *
 *	EFFECTS         Deallocates memory
 */
void free_map (void * p)
{
#ifdef TRACE
  fprintf (stderr, "free_map ()\n");
  fflush (stderr);
#endif

  if (p)
    free (p);
}

/***	get_object - fill in currobj with information about an object
 *
 *	This function is called to get a filesystem object off the disk
 *	and store information about it in the current object structure.
 *	It allocates memory for the object (or part of it, if it is a
 *	large object such as a big data run), and reads the object into
 *	memory.  "currobj" is filled in with information about the object.
 *
 *	If the memory pointer in currobj is already filled in, the memory
 *	is re-used, and data is read from the offset stored in currobj.
 *	This allows large data runs to be examined without reading the
 *	entire run into memory.
 *
 *	This routine expects the "sec" and "len" fields of currobj to
 *	be set to point to the desired object before being called.  If
 *	a new portion of an object is being paged in, "offset" must also
 *	be set;  otherwise, "offset" is set to zero.
 *
 *	The offset passed must be a multiple of one sector;  allowing
 *	byte granularity would complicate this routine tremendously.
 *
 *	get_object ()
 *
 *	ENTRY		No parameters
 *			currobj.sec, .len, and .offset set appropriately
 *
 *	EXIT		No return value
 *			currobj.mem, .offset filled in
 *
 *	CALLS		allocate_block
 *			read_scratch
 *
 *	WARNINGS	if (currobj.mem), offset % 512 must be zero
 *
 *	EFFECTS         Allocates memory
 *			Reads disk
 *			Changes global variable "currobj"
 */
void get_object ()
{
  ULONG l;

  if (currobj.mem) {			/* get different portion of object */
    l = currobj.sec + currobj.offset;	/* get sector address of what we want */
    read_scratch (l, currobj.mem, SECTORS_PER_BLOCK);	/* read 2K */
  }
  else {				/* get new object */
    l = (currobj.len > SECTORS_PER_BLOCK) ? SECTORS_PER_BLOCK : currobj.len;
    currobj.mem = allocate_block (l);
    read_scratch (currobj.sec, currobj.mem, l);
    currobj.offset = 0L;
    currobj.dirty = FALSE;
  }
}