File:  [Apple Darwin 0.x] / driverkit / libDriver / label_subr.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:37:50 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin02
Darwin 0.2 Driver Kit

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.1 (the "License").  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/* 	Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
 *
 * label_subr.c - machine-independent disk label routines
 *
 * HISTORY
 * 01-Apr-92    Doug Mitchell at NeXT
 *      Created.
 */
#import <bsd/sys/param.h> 
#import <bsd/dev/disk_label.h>
#import <driverkit/disk_label.h>
#import <driverkit/diskstruct.h>
#import <architecture/byte_order.h>


/*
 * Inlines used to manipulate m68k-style disk label fields.
 */
static inline unsigned int
get_word(const void *src)
{
	return ( NXSwapBigIntToHost(*((unsigned int *)src)));
}

static inline void
put_word(unsigned s, void *dest)
{
	*((unsigned int *)dest) = NXSwapHostIntToBig(s);
}


static inline unsigned short
get_short(const void *src)
{
	return ( NXSwapBigShortToHost(*((unsigned short *)src)));
}

static inline void
put_short(unsigned short s, void *dest)
{
	*((unsigned short *)dest) = NXSwapHostShortToBig(s);
}

/*
 * Machine-independent version of kernel's checksum_16().
 * *wp is a raw m68k-style label.
 */
unsigned short 
checksum16(unsigned short *wp, int num_shorts)
{
	int sum1 = 0;
	int sum2;

	while (num_shorts--){
		sum1 += NXSwapBigShortToHost(*wp);
		wp++;
	}
	sum2 = ((sum1 & 0xffff0000) >> 16) + (sum1 & 0xffff);
	if(sum2 > 65535) {
		sum2 -= 65535;
	}
	return sum2;
}

/*
 * Validate an m68k-style label. Returns NULL if good, else returns pointer
 * to an error string describing what is wrong with the label.
 */
char *
check_label(char *raw_label,			// as it came off disk
	int block_num)	
{
	unsigned short	sum;
	unsigned short 	cksum;
	unsigned short 	size;
	void		*dl_cksump;
	int		 version;
	int 		label_blkno;
	
	version = get_word(raw_label + DISK_LABEL_DL_VERSION);
	if(version == DL_V1 || version == DL_V2) {
		size = SIZEOF_DISK_LABEL_T;
		dl_cksump = raw_label + DISK_LABEL_DL_CHECKSUM;
	} 
	else if(version == DL_V3) {
		size = SIZEOF_DISK_LABEL_T - SIZEOF_DL_UN_T;
		dl_cksump = raw_label + DISK_LABEL_DL_UN;
	} 
	else {
		return "Bad disk label magic number";
	}
	label_blkno = get_word(raw_label + DISK_LABEL_DL_LABEL_BLKNO);
	if(label_blkno != block_num) {
		return "Label in wrong location";
	}
		
	/*
	 * Block number in label has to be 0 for checksum calculation.
	 */
	put_word(0, raw_label + DISK_LABEL_DL_LABEL_BLKNO);
	cksum = get_short(dl_cksump);
	put_short(0, dl_cksump);
	sum = checksum16((unsigned short *)raw_label, size >> 1);
	if (sum != cksum) {
		return "Label checksum error";
	}
	
	/*
	 * Success. Restore block number.
	 */
	put_word(block_num, raw_label + DISK_LABEL_DL_LABEL_BLKNO);
	put_short(cksum, dl_cksump);
	return NULL;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.