Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

344 lines
12 KiB

/*
$Log: S:\gfs32\libgfs\gfroot.c_v $
*
* Rev 1.1 19 Apr 1995 16:34:34 RWR
* Make sure WIN32_LEAN_AND_MEAN is defined (explicitly or via GFSINTRN.H)
* Also surround local include files with quotes instead of angle brackets
*
* Rev 1.0 06 Apr 1995 14:02:48 HEIDI
* Initial entry
*
* Rev 1.0 28 Mar 1995 15:53:28 JAR
* Initial entry
*/
/*
Copyright 1989, 1990 by Wang Laboratories Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of WANG not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
WANG makes no representations about the suitability of
this software for any purpose. It is provided "as is"
without express or implied warranty.
*
*/
/*
* SccsId: @(#)Source gfroot.c 1.26@(#)
*
* GFS: WIFF Root Block Handling
*
* Routines:
* initroot(), fillroot(), freeroot(), updroot()
*/
/*LINTLIBRARY*/
#define GFS_CORE
#include "gfsintrn.h"
#include <stdio.h>
#include <errno.h>
#include "gfct.h"
#include "hdbk.h"
extern long FAR PASCAL ulseek();
#if (SYSBYTEORDER == II)
extern void FAR PASCAL swaprtbk();
extern void FAR PASCAL swappmt();
extern void FAR PASCAL swappmte();
#endif
/* Given fct, create space for the root block and a header block */
int FAR PASCAL initroot(fct) /*errno_KEY*/
struct _gfct FAR *fct;
{
unsigned char FAR *bitmap;
struct _rtbk FAR *rtbk;
struct _hdbk FAR *hdbk;
rtbk = (struct _rtbk FAR *) calloc( (unsigned) 1, (unsigned) 4 * K);
if (rtbk == (struct _rtbk FAR *) NULL) {
errno = (int) ENOMEM;
return ( (int) -1);
}
hdbk = (struct _hdbk FAR *) calloc( (unsigned) 1, (unsigned) 4 * K);
if (hdbk == (struct _hdbk FAR *) NULL) {
errno = (int) ENOMEM;
free( (char FAR *) hdbk);
return ( (int) -1);
}
/* initialize the root block */
rtbk->file_id = (u_short) WIFF_ID_MM;
rtbk->file_type = (u_short) WIFF_TYPE;
rtbk->file_format = (u_short) WIFF_FORMAT;
/* initialize the page mapping table */
rtbk->pmt_map.first_free = (u_short) 0;
rtbk->pmt_map.entries = (u_short) ROOT_PMTS;
/* initialize the free block bitmap */
bitmap = (unsigned char FAR *) rtbk;
bitmap += (2 * K);
(void) memset( (char FAR *) bitmap, (int) HEXFF, (int) 2 * K);
bitmap[0] >>= 1;
fct->u.wif.root_in_mem = rtbk;
fct->u.wif.hdbk_in_mem = hdbk;
fct->u.wif.pmt_in_mem = (struct _pmt FAR *) &rtbk->pmt_map;
return( (int) 0);
}
/* Given fct, read in the root block. */
int FAR PASCAL fillroot(fct) /*errno_KEY*/
struct _gfct FAR *fct;
{
int num_read = 0;
long fp = 0;
u_long nxt_pmt = 0;
struct _pmt FAR *prv_pmt;
struct _rtbk FAR *p_rtbk;
/* Seek to start of file */
fp = ulseek(fct->fildes, (u_long) 0);
if (fp < (long) 0)
return ( (int) -1);
/* Read ROOT and 127 PMTs */
p_rtbk = (struct _rtbk FAR *) fct->u.wif.root_in_mem;
num_read = read(fct->fildes, (char FAR *) p_rtbk, (unsigned) 4 * K);
if (num_read <= 0) /* 0 is eof */
return ( (int) -1);
#if (SYSBYTEORDER == II)
(void) swaprtbk((struct _rtbk FAR *) p_rtbk);
(void) swappmt((struct _pmt FAR *) &p_rtbk->pmt_map);
#endif
/* Set Block count */
fct->u.wif.block_cnt = p_rtbk->last_blk + 1L;
/* Read other PMTs */
nxt_pmt = (u_long) p_rtbk->pmt_map.nu.vsptr;
fct->u.wif.pmt_in_mem = prv_pmt = &p_rtbk->pmt_map;
#if (SYSBYTEORDER == II)
{
char FAR *ptr1 = (char FAR *)p_rtbk;
char FAR *ptr2 = (char FAR *)prv_pmt;
LONG loffset = (LONG)((LONG)prv_pmt->entries * sizeof (struct _pmte));
if (loffset <= (4 * K)) {
ptr1 += (4 * K);
ptr2 += (unsigned int)loffset;
if (ptr1 > ptr2)
(void) swappmte((struct _pmte FAR *) &(prv_pmt->first_pmte),
(long) prv_pmt->entries);
}
else {
errno = EINVALID_DBSIZE;
return ( (int) -1);
}
}
#endif
while (nxt_pmt > 0) {
prv_pmt->nu.next_pmt =
(struct _pmt FAR *) calloc( (unsigned) 1, (unsigned) 4 * K);
if (prv_pmt->nu.next_pmt == (struct _pmt FAR *) NULL) {
errno = (int) ENOMEM;
return ( (int) -1);
}
prv_pmt = prv_pmt->nu.next_pmt;
fp = ulseek(fct->fildes, (u_long) (nxt_pmt * 4 * K));
if (fp < (long) 0)
return ( (int) -1);
num_read = read(fct->fildes, (char FAR *) prv_pmt,
(unsigned) 4 * K);
if (num_read <= 0) /* 0 is eof */
return ( (int) -1);
#if (SYSBYTEORDER == II)
(void) swappmt((struct _pmt FAR *) prv_pmt);
(void) swappmte((struct _pmte FAR *)
&(prv_pmt->first_pmte),
(long) prv_pmt->entries);
#endif
nxt_pmt = (u_long) prv_pmt->nu.vsptr;
}
prv_pmt->nu.next_pmt = (struct _pmt FAR *) NULL;
fct->num_pages = p_rtbk->full_pages;
return( (int) 0);
}
/* Given fct, free memory associated with an open WIFF file. */
void FAR PASCAL freeroot(fct) /*errno_KEY*/
struct _gfct *fct;
{
int first_one;
char FAR *p_rwbuf;
struct _rtbk FAR *p_rtbk;
struct _hdbk FAR *p_hdbk;
struct _dbt FAR *p_dbt, FAR *sav_dbt;
p_hdbk = (struct _hdbk FAR *) fct->u.wif.hdbk_in_mem;
p_dbt = (struct _dbt FAR *) &p_hdbk->first_dbt;
p_rtbk = (struct _rtbk FAR *) fct->u.wif.root_in_mem;
p_rwbuf = (char FAR *) fct->u.wif.RWbuf;
if (p_rtbk != (struct _rtbk FAR *) NULL)
free( (char FAR *) p_rtbk);
if (p_hdbk != (struct _hdbk FAR *) NULL) {
if (p_dbt->nu.next_dbt != (struct _dbt FAR *) NULL) {
first_one = (int) TRUE;
do {
sav_dbt = p_dbt->nu.next_dbt;
if (first_one)
first_one = (int) FALSE;
else
free((char FAR *) p_dbt);
p_dbt = sav_dbt;
} while(sav_dbt != (struct _dbt FAR *) NULL);
}
free( (char FAR *) p_hdbk);
}
if (p_rwbuf != (char FAR *) NULL)
free( (char FAR *) p_rwbuf);
}
/* Given fct, update the root block of an open WIFF file. */
int FAR PASCAL updroot(fct) /*errno_KEY*/
struct _gfct FAR *fct;
{
int bytes_written = 0;
long fp = (long) 0;
u_long clear_cnt = 0;
unsigned char FAR *bitmap;
struct _pmt FAR *prv_pmt, FAR *sav_pmt;
struct _rtbk FAR *p_rtbk;
p_rtbk = (struct _rtbk FAR *) fct->u.wif.root_in_mem;
/* If we have more pmt_maps to write, do so now !!! */
/* 1. next pmt ptr in root set to next block to write.
2. seek to next block to write.
3. save ptr to next pmt (if any).
4. if ptr not null, increment block cnt and set current
pmt to point to it.
5. if on an II machine, do some swapping.
6. write current pmt.
7. free the pmt's memory area.
8. point to next pmt (if any !!).
9. repeat steps 3 thru 8 until no more pmt's.
*/
if (p_rtbk->pmt_map.nu.next_pmt != (struct _pmt FAR *) NULL) {
prv_pmt = p_rtbk->pmt_map.nu.next_pmt;
p_rtbk->pmt_map.nu.vsptr = (u_long) fct->u.wif.block_cnt;
fp = ulseek(fct->fildes,
(u_long) (fct->u.wif.block_cnt * 4 * K) );
if (fp < (long) 0)
return( (int) -1 );
while (prv_pmt != (struct _pmt FAR *) NULL) {
sav_pmt = prv_pmt->nu.next_pmt;
if (sav_pmt != (struct _pmt FAR *) NULL)
prv_pmt->nu.vsptr = (u_long)
(fct->u.wif.block_cnt + 1);
#if (SYSBYTEORDER == II)
(void) swappmte((struct _pmte FAR *)
&(prv_pmt->first_pmte),
(long) prv_pmt->entries);
(void) swappmt((struct _pmt FAR *) prv_pmt);
#endif
bytes_written = write(fct->fildes,
(char FAR *) prv_pmt,
(unsigned) (4 * K) );
if (bytes_written < (int) 0) {
/* some error handling goes here */
return( (int) -1);
}
fct->u.wif.block_cnt++;
/* following added to keep O\i gfs up to date with
other gfs versions -- jar */
if ( sav_pmt == ( struct _pmt FAR *)NULL)
{
bytes_written = write( fct->fildes,
(char FAR *)prv_pmt,
( unsigned)( 4*K));
if (bytes_written < (int)0)
return ((int)-1);
}
/* end of addition -- jar */
free( (char FAR *) prv_pmt);
prv_pmt = sav_pmt;
}
} else
prv_pmt = (struct _pmt FAR *) NULL;
/* update the root block */
fp = ulseek(fct->fildes, (u_long) 0);
if (fp < (long) 0)
return( (int) -1 );
p_rtbk = (struct _rtbk FAR *) fct->u.wif.root_in_mem;
#if (SYSBYTEORDER == II)
(void) swappmte((struct _pmte FAR *) &(p_rtbk->pmt_map.first_pmte),
(long) p_rtbk->pmt_map.entries);
(void) swappmt((struct _pmt FAR *) &p_rtbk->pmt_map);
#endif
p_rtbk->last_blk = fct->u.wif.block_cnt - 1;
/* update the free block bitmap */
bitmap = (unsigned char FAR *) p_rtbk;
bitmap += (2 * K);
/* first get # of bytes to clear */
clear_cnt = (u_long) (fct->u.wif.block_cnt / 8);
if (clear_cnt != (u_long) 0) {
(void) memset( (char FAR *) bitmap,
(int) HEX0, (int) clear_cnt);
bitmap += clear_cnt;
}
/* now clear the leftover bits if any ... */
clear_cnt = (u_long) (fct->u.wif.block_cnt % 8);
if (clear_cnt != (u_long) 0)
bitmap[0] >>= (int) clear_cnt;
/* write out the root block */
#if (SYSBYTEORDER == II)
(void) swaprtbk((struct _rtbk FAR *) p_rtbk);
#endif
#undef WFLAG
#define WFLAG WRITE0
bytes_written = write(fct->fildes,
(char FAR *) p_rtbk,
(unsigned) (4 * K) );
#undef WFLAG
#define WFLAG FLUSH
if (bytes_written < (int) 0) {
/* some error handling goes here */
return( (int) -1);
}
return ( (int) 0 );
}