mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
7.3 KiB
283 lines
7.3 KiB
/*****************************************************************/
|
|
/** 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;
|
|
}
|
|
}
|