Esempio n. 1
0
    // 消息包的格式是
    // | 后面包长 | 消息类别 | 消息内容 | 校验码 |
    // | 2 Byte   | 2 Byte   | ~~~~ | 2 Byte |
    bool checksum(const char* msg, size_t len)
    {
        uint32_t expectedCheckSum = asNetInt32(msg + len - TAIL_LENGTH);
        uint32_t checkedSum = adler32((const unsigned char*)msg, len - TAIL_LENGTH);
        if(expectedCheckSum != checkedSum)
        {
            return false;
        }

        return true;
    }
void embed_checksum( u8* data, int len )
{
	FWHeader *header;
	u32 cksum=0,i,readaddr,readword;
	header=(FWHeader*)((int)data+FW_HEADER_OFFSET);

	header->BinaryLength=len;
	
	//header->Checksum=(u32)adler32(data,len,(u32)&header->Checksum);
	header->Checksum=(u32)adler32(data,len,FW_HEADER_OFFSET);//addr 0x188 is skipped 32bit dword from input data as it will be checsum store position
}
Esempio n. 3
0
static int
zlwrite(void *vzw, void *buf, int n)
{
	ZWrite *zw;

	zw = vzw;
	zw->adler = adler32(zw->adler, buf, n);
	n = (*zw->w)(zw->wr, buf, n);
	if(n <= 0)
		return n;
	return n;
}
Esempio n. 4
0
static u32 sceAdler32(u32 adler, u32 data, u32 datalen) {
	if (!Memory::IsValidAddress(data) || !Memory::IsValidAddress(data + datalen - 1)) {
		ERROR_LOG(HLE, "sceAdler32(adler=%08x, data=%08x, datalen=%08x) - bad address(es)", adler, data, datalen);
		return -1;
	}
	INFO_LOG(HLE, "sceAdler32(adler=%08x, data=%08x, datalen=%08x)", adler, data, datalen);

	u8 *buf = Memory::GetPointerUnchecked(data);
	u32 ret = adler32(adler, buf, datalen);

	return ret;
}
/*
 * Start with CHECKSUM and update the checksum by processing a chunk
 * of DATA sized LEN.
 */
apr_uint32_t
svn__adler32(apr_uint32_t checksum, const char *data, apr_off_t len)
{
  /* The actual limit can be set somewhat higher but should
   * not be lower because the SIMD code would not be used
   * in that case.
   *
   * However, it must be lower than 5552 to make sure our local
   * implementation does not suffer from overflows.
   */
  if (len >= 80)
    {
      /* Larger buffers can be effiently handled by Marc Adler's
       * optimized code. Also, new zlib versions will come with
       * SIMD code for x86 and x64.
       */
      return adler32(checksum, (const Bytef *)data, len);
    }
  else
    {
      const unsigned char *input = (const unsigned char *)data;
      apr_uint32_t s1 = checksum & 0xFFFF;
      apr_uint32_t s2 = checksum >> 16;
      apr_uint32_t b;

      /* Some loop unrolling
       * (approx. one clock tick per byte + 2 ticks loop overhead)
       */
      for (; len >= 8; len -= 8, input += 8)
      {
        s1 += input[0]; s2 += s1;
        s1 += input[1]; s2 += s1;
        s1 += input[2]; s2 += s1;
        s1 += input[3]; s2 += s1;
        s1 += input[4]; s2 += s1;
        s1 += input[5]; s2 += s1;
        s1 += input[6]; s2 += s1;
        s1 += input[7]; s2 += s1;
      }

      /* Adler-32 calculation as a simple two ticks per iteration loop.
       */
      while (len--)
        {
          b = *input++;
          s1 += b;
          s2 += s1;
        }

      return ((s2 % ADLER_MOD_BASE) << 16) | (s1 % ADLER_MOD_BASE);
    }
}
Esempio n. 6
0
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
{
    if (len == 0)
        return adler;
    assert(buf != NULL);
#if 0
    return adler32(adler, (const Bytef *) buf, len); // zlib
#elif (WITH_UCL)
    return ucl_adler32(adler, (const ucl_bytep) buf, len);
#else
#  error
#endif
}
Esempio n. 7
0
File: debug.c Progetto: srodrig1/lk
static int cmd_adler32(int argc, const cmd_args *argv)
{
	if (argc < 3) {
		printf("not enough arguments\n");
		printf("usage: %s <address> <size>\n", argv[0].str);
		return -1;
	}

	uint32_t crc = adler32(0, argv[1].p, argv[2].u);

	printf("0x%x\n", crc);

	return 0;
}
Esempio n. 8
0
adler32_t file_adler32( FILE *f, long buffsize  )
{
  ASSERT( f );

  char *buff = (char*)malloc( buffsize );
  if (buff == NULL) return 0;

  adler32_t adler = adler32( 0, NULL, 0 );
  while(42)
    {
    long res = fread( buff, 1, buffsize, f );
    if (res == -1)
      {
      fclose( f );
      return 0;
      }
    adler = adler32( adler, buff, res );
    if ( res != buffsize ) break;
    }
  free( buff );

  return adler;
};
static uLong gtkhash_hash_lib_zlib_checksum(const enum hash_func_e id,
	const uLong csum, const uint8_t *buffer, const size_t size)
{
	switch (id) {
		case HASH_FUNC_CRC32:
			return crc32(csum, buffer, size);
		case HASH_FUNC_ADLER32:
			return adler32(csum, buffer, size);
		default:
			g_assert_not_reached();
	}

	return 0;
}
Esempio n. 10
0
int main(int argc, char* argv[]) {
    long bufsize;

    if (argc != 2) {
	fputs("Need 1 argument\n", stderr);
	return (EXIT_FAILURE);
    }

    unsigned char *source = NULL;
    FILE *fp = fopen(argv[1], "rb");
    if (fp != NULL) {
        /* Go to the end of the file. */
        if (fseek(fp, 0L, SEEK_END) == 0) {
            /* Get the size of the file. */
            bufsize = ftell(fp);
            if (bufsize == -1) { fputs("Couldn't get size\n", stderr); return (EXIT_FAILURE); }
    
            /* Allocate our buffer to that size. */
            source = malloc(sizeof(char) * (bufsize + 1));
            if (source == NULL) { fputs("Couldn't allocate\n", stderr); return (EXIT_FAILURE); }
    
            /* Go back to the start of the file. */
            if (fseek(fp, 0L, SEEK_SET) == -1) { fputs("Couldn't seek\n", stderr); return (EXIT_FAILURE); }
    
            /* Read the entire file into memory. */
            size_t newLen = fread(source, sizeof(char), bufsize, fp);
            if (newLen == 0) {
                fputs("Error reading file\n", stderr);
                //return (EXIT_FAILURE);
            } else {
                source[++newLen] = '\0'; /* Just to be safe. */
            }
        } else {
          fputs("Couldn't seek to end\n", stderr);
          return (EXIT_FAILURE);
        }
        fclose(fp);
    } else {
      fputs("Couldn't open\n", stderr);
      return (EXIT_FAILURE);
    }

    printf("%d\n", (uint32_t) adler32(source, bufsize));
    
    free(source); /* Don't forget to call free() later! */

    return (EXIT_SUCCESS);

}
Esempio n. 11
0
static PyObject *
PyZlib_adler32(PyObject *self, PyObject *args)
{
    unsigned int adler32val = 1;  /* adler32(0L, Z_NULL, 0) */
    Byte *buf;
    int len, signed_val;

    if (!PyArg_ParseTuple(args, "s#|I:adler32", &buf, &len, &adler32val))
        return NULL;
    /* In Python 2.x we return a signed integer regardless of native platform
     * long size (the 32bit unsigned long is treated as 32-bit signed and sign
     * extended into a 64-bit long inside the integer object).  3.0 does the
     * right thing and returns unsigned. http://bugs.python.org/issue1202 */
    signed_val = adler32(adler32val, buf, len);
    return PyInt_FromLong(signed_val);
}
Esempio n. 12
0
void page_check_checksum(char* page) {
    if (!checksum_verify)
      return;
    else {
      int computed_cs = adler32(0, (unsigned char*) page + PAGE_DATA_OFFSET, PAGE_DATA_BYTES);
      int stored_cs = (int) deserialize_int(page + PAGE_CHECKSUM_OFFSET);
      /* int stored_page_num = (int) deserialize_int(page + PAGE_NUM_OFFSET); */

      if (checksum_assert && computed_cs != stored_cs) {
        fprintf(stderr,
                "Cannot validate page, checksum stored(%d) and computed(%d)\n",
                stored_cs, computed_cs);
        exit(-1);
      }
    }
}
Esempio n. 13
0
static
void *
compress_worker_thread_func(void *arg)
{
	comp_thread_ctxt_t *thd = (comp_thread_ctxt_t *) arg;

	pthread_mutex_lock(&thd->ctrl_mutex);

	pthread_mutex_lock(&thd->data_mutex);

	thd->started = TRUE;
	pthread_cond_signal(&thd->ctrl_cond);

	pthread_mutex_unlock(&thd->ctrl_mutex);

	while (1) {
		thd->data_avail = FALSE;
		pthread_cond_signal(&thd->data_cond);

		while (!thd->data_avail && !thd->cancelled) {
			pthread_cond_wait(&thd->data_cond, &thd->data_mutex);
		}

		if (thd->cancelled)
			break;

		thd->to_len = qlz_compress(thd->from, thd->to, thd->from_len,
					   &thd->state);

		/* qpress uses 0x00010000 as the initial value, but its own
		Adler-32 implementation treats the value differently:
		  1. higher order bits are the sum of all bytes in the sequence
		  2. lower order bits are the sum of resulting values at every
		     step.
		So it's the other way around as compared to zlib's adler32().
		That's why  0x00000001 is being passed here to be compatible
		with qpress implementation. */

		thd->adler = adler32(0x00000001, (uchar *) thd->to,
				     thd->to_len);
	}

	pthread_mutex_unlock(&thd->data_mutex);

	return NULL;
}
Esempio n. 14
0
unsigned long Core99NVRAM::validateGeneration(unsigned char *nvramBuffer)
{
  Core99NVRAMHeader *header = (Core99NVRAMHeader *)nvramBuffer;
  
  // First validate the signature.
  if (header->signature != kCore99NVRAMSignature) return 0;
  
  // Next make sure the header's checksum matches.
  if (header->checksum != chrpCheckSum(nvramBuffer)) return 0;
  
  // Make sure the adler checksum matches.
  if (header->adler32 != adler32(nvramBuffer + kCore99NVRAMAdlerStart,
				 kCore99NVRAMAdlerSize))
    return 0;
  
  return header->generation;
}
Esempio n. 15
0
File: debug.c Progetto: srodrig1/lk
static int cmd_cksum_bench(int argc, const cmd_args *argv)
{
#define BUFSIZE 0x1000
#define ITER 16384
	void *buf;
	bool freebuf;

	if (argc > 1) {
		buf = argv[1].p;
		freebuf = false;
	} else {
		buf = malloc(BUFSIZE);
		freebuf = true;
	}

	if (!buf)
		return -1;

	lk_bigtime_t t;
	uint32_t crc;

	printf("buffer at %p, size %u\n", buf, BUFSIZE);

	t = current_time_hires();
	crc = 0;
	for (int i = 0; i < ITER; i++) {
		crc = crc32(crc, buf, BUFSIZE);
	}
	t = current_time_hires() - t;

	printf("took %llu usecs to crc32 %d bytes (%lld bytes/sec)\n", t, BUFSIZE * ITER, (BUFSIZE * ITER) * 1000000ULL / t);
	thread_sleep(500);

	t = current_time_hires();
	crc = 0;
	for (int i = 0; i < ITER; i++) {
		crc = adler32(crc, buf, BUFSIZE);
	}
	t = current_time_hires() - t;

	printf("took %llu usecs to adler32 %d bytes (%lld bytes/sec)\n", t, BUFSIZE * ITER, (BUFSIZE * ITER) * 1000000ULL / t);

	if (freebuf)
		free(buf);
	return 0;
}
Esempio n. 16
0
/* ========================================================================= */
EXPORT_C int ZEXPORT deflateSetDictionary (
    z_streamp strm,
    const Bytef *dictionary,
    uInt  dictLength)
{
    // Line to stop compiler warning about unused mandatory global variable
    char __z=deflate_copyright[0];
    __z=__z;

    deflate_state *s;
    uInt length = dictLength;
    uInt n;
    IPos hash_head = 0;

    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
            strm->state->status != INIT_STATE) return Z_STREAM_ERROR;

    s = strm->state;
    strm->adler = adler32(strm->adler, dictionary, dictLength);

    if (length < MIN_MATCH) return Z_OK;
    if (length > MAX_DIST(s)) {
        length = MAX_DIST(s);
#ifndef USE_DICT_HEAD
        dictionary += dictLength - length; /* use the tail of the dictionary */
#endif
    }
    zmemcpy(s->window, dictionary, length);
    s->strstart = length;
    s->block_start = (long)length;

    /* Insert all strings in the hash table (except for the last two bytes).
     * s->lookahead stays null, so s->ins_h will be recomputed at the next
     * call of fill_window.
     */
    s->ins_h = s->window[0];
    UPDATE_HASH(s, s->ins_h, s->window[1]);
    for (n = 0; n <= length - MIN_MATCH; n++) {
        INSERT_STRING(s, n, hash_head);
    }
    if (hash_head) hash_head = 0;  /* to make compiler happy */
    return Z_OK;
}
JNIEXPORT jlong JNICALL
Java_java_util_zip_Adler32_updateImpl (JNIEnv * env, jobject recv,
                                       jbyteArray buf, int off, int len,
                                       jlong crc)
{
  jbyte *b;
  jboolean isCopy;
  jlong result;

  b = (*env)->GetPrimitiveArrayCritical (env, buf, &isCopy);
  if (b == NULL) {
    throwNewOutOfMemoryError(env, "");
    return 0;
  }
  result = (jlong) adler32 ((uLong) crc, (Bytef *) (b + off), (uInt) len);
  (*env)->ReleasePrimitiveArrayCritical (env, buf, b, JNI_ABORT);

  return result;
}
Esempio n. 18
0
static u4 fileAdler32(int fd, u4 adler, off_t start, size_t size)
{
    unsigned char buff[8192];

    if (lseek(fd, start, SEEK_SET) != start) {
        pr_red_info("Unable to seek to start of checksum area (%ld): %s", (long) start, strerror(errno));
		return 0;
    }

    while (size != 0) {
        ssize_t rdLen = read(fd, buff, size < sizeof(buff) ? size : sizeof(buff));
        if (rdLen <= 0) {
            pr_red_info("Read failed (%d) while computing checksum (len=%zu): %s", (int) rdLen, size, strerror(errno));
			return 0;
        }

        adler = adler32(adler, buff, rdLen);
        size -= rdLen;
    }

	return adler;
}
Esempio n. 19
0
static int do_bulk_checksum_adler32(struct ptlrpc_bulk_desc *desc, void *buf)
{
        struct page    *page;
        int             off;
        char           *ptr;
        __u32           adler32 = 1;
        int             len, i;

        for (i = 0; i < desc->bd_iov_count; i++) {
                page = desc->bd_iov[i].kiov_page;
                off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK;
                ptr = cfs_kmap(page) + off;
                len = desc->bd_iov[i].kiov_len;

                adler32 = adler32(adler32, ptr, len);

                cfs_kunmap(page);
        }

        adler32 = cpu_to_le32(adler32);
        memcpy(buf, &adler32, sizeof(adler32));
        return 0;
}
Esempio n. 20
0
bool FileTransferServiceImpl::SaveSliceRequest(
    const FileTransfer::SliceRequest *slice_request) {
  const FileTransfer::Slice &slice = slice_request->slice();
  const string &content = slice_request->content();
  uint32 adler;
  adler = adler32(slice.previous_adler(),
                  reinterpret_cast<const Bytef*>(content.c_str()),
                  content.size());
  if (adler != slice.adler()) {
    LOG(WARNING) << "slice: " << slice.index() << " checksum error";
    return false;
  }

  boost::filesystem::path filename(doc_root_);
  filename /= GetSliceName(&slice_request->slice());
  ofstream output(filename.string().c_str(), ios::out | ios::trunc | ios::binary);
  if (!slice_request->SerializeToOstream(&output)) {
    LOG(WARNING) << "Failed to save the CheckBook to:" << filename
                 << " error: " << strerror(errno);
    return false;
  }
  return true;
}
Esempio n. 21
0
ulong
writeBlock(uchar *b, int type)
{
	uchar *cb, *ob;
	int n;
	PaqBlock bh;
	uchar buf[BlockSize];
	ulong offset;

	offset = Boffset(out);

	bh.magic = BlockMagic;
	bh.size = blocksize;	
	bh.type = type;
	bh.encoding = NoEnc;
	bh.adler32 = adler32(0, b, blocksize);
	ob = b;

	if(!uflag) {
		cb = emallocz(blocksize);
		n = deflateblock(cb, blocksize, b, blocksize, 6, 0);
		if(n > 0 && n < blocksize) {
			bh.encoding = DeflateEnc;
			bh.size = n;
			ob = cb;
		}	
	}

	putBlock(buf, &bh);
	outWrite(buf, sizeof(buf));
	outWrite(ob, bh.size);
	
	if(ob != b)
		free(ob);
	return offset;
}
Esempio n. 22
0
int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
                              void *buf, int buflen)
{
        __u32   csum32;
        int     i;

        LASSERT(alg == BULK_HASH_ALG_ADLER32 || alg == BULK_HASH_ALG_CRC32);

        if (alg == BULK_HASH_ALG_ADLER32)
                csum32 = 1;
        else
                csum32 = ~0;

        for (i = 0; i < desc->bd_iov_count; i++) {
                unsigned char *ptr = desc->bd_iov[i].iov_base;
                int len = desc->bd_iov[i].iov_len;

                switch (alg) {
                case BULK_HASH_ALG_ADLER32:
#ifdef HAVE_ADLER
                        csum32 = adler32(csum32, ptr, len);
#else
                        CERROR("Adler32 not supported\n");
                        return -EINVAL;
#endif
                        break;
                case BULK_HASH_ALG_CRC32:
                        csum32 = crc32_le(csum32, ptr, len);
                        break;
                }
        }

        csum32 = cpu_to_le32(csum32);
        memcpy(buf, &csum32, sizeof(csum32));
        return 0;
}
Esempio n. 23
0
File: zlib.c Progetto: nbouteme/rtv1
void		*zlib_stream(void *data, int s, int *osize)
{
	t_size_pair	**seg;
	char		*kek[3];
	int			os;

	os = 0;
	seg = make_arr(data, s, 0xffff);
	ft_memset(kek, 0, sizeof(kek));
	kek[2] = (void*)seg;
	while (*seg)
	{
		process_segment(seg, kek, &os);
		++seg;
	}
	free(kek[2]);
	*osize = 2 + os + 4;
	kek[2] = malloc(*osize);
	ft_memcpy(kek[2], "\x78\x01", 2);
	ft_memcpy(&kek[2][2], kek[0], os);
	free(kek[0]);
	*(unsigned*)&kek[2][2 + os] = bswap_32(adler32(data, s));
	return (kek[2]);
}
Esempio n. 24
0
//  hf            - MPQ File handle.
//  pbBuffer      - Pointer to target buffer to store sectors.
//  dwByteOffset  - Position of sector in the file (relative to file begin)
//  dwBytesToRead - Number of bytes to read. Must be multiplier of sector size.
//  pdwBytesRead  - Stored number of bytes loaded
static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead)
{
    ULONGLONG RawFilePos;
    TMPQArchive * ha = hf->ha;
    TFileEntry * pFileEntry = hf->pFileEntry;
    LPBYTE pbRawSector = NULL;
    LPBYTE pbOutSector = pbBuffer;
    LPBYTE pbInSector = pbBuffer;
    DWORD dwRawBytesToRead;
    DWORD dwRawSectorOffset = dwByteOffset;
    DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize;
    DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize;
    DWORD dwSectorsDone = 0;
    DWORD dwBytesRead = 0;
    int nError = ERROR_SUCCESS;

    // Note that dwByteOffset must be aligned to size of one sector
    // Note that dwBytesToRead must be a multiplier of one sector size
    // This is local function, so we won't check if that's true.
    // Note that files stored in single units are processed by a separate function

    // If there is not enough bytes remaining, cut dwBytesToRead
    if((dwByteOffset + dwBytesToRead) > hf->dwDataSize)
        dwBytesToRead = hf->dwDataSize - dwByteOffset;
    dwRawBytesToRead = dwBytesToRead;

    // Perform all necessary work to do with compressed files
    if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
    {
        // If the sector positions are not loaded yet, do it
        if(hf->SectorOffsets == NULL)
        {
            nError = AllocateSectorOffsets(hf, true);
            if(nError != ERROR_SUCCESS)
                return nError;
        }

        // If the sector checksums are not loaded yet, load them now.
        if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC))
        {
            nError = AllocateSectorChecksums(hf, true);
            if(nError != ERROR_SUCCESS)
                return nError;
        }

        // If the file is compressed, also allocate secondary buffer
        pbInSector = pbRawSector = ALLOCMEM(BYTE, dwBytesToRead);
        if(pbRawSector == NULL)
            return ERROR_NOT_ENOUGH_MEMORY;

        // Assign the temporary buffer as target for read operation
        dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];
        dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset;
    }

    // Calculate raw file offset where the sector(s) are stored.
    CalculateRawSectorOffset(RawFilePos, hf, dwRawSectorOffset);

    // Set file pointer and read all required sectors
    if(!FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead))
        return GetLastError();
    dwBytesRead = 0;

    // Now we have to decrypt and decompress all file sectors that have been loaded
    for(DWORD i = 0; i < dwSectorsToRead; i++)
    {
        DWORD dwRawBytesInThisSector = ha->dwSectorSize;
        DWORD dwBytesInThisSector = ha->dwSectorSize;
        DWORD dwIndex = dwSectorIndex + i;

        // If there is not enough bytes in the last sector,
        // cut the number of bytes in this sector
        if(dwRawBytesInThisSector > dwBytesToRead)
            dwRawBytesInThisSector = dwBytesToRead;
        if(dwBytesInThisSector > dwBytesToRead)
            dwBytesInThisSector = dwBytesToRead;

        // If the file is compressed, we have to adjust the raw sector size
        if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
            dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex];

        // If the file is encrypted, we have to decrypt the sector
        if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
        {
            BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);

            // If we don't know the key, try to detect it by file content
            if(hf->dwFileKey == 0)
            {
                hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector);
                if(hf->dwFileKey == 0)
                {
                    nError = ERROR_UNKNOWN_FILE_KEY;
                    break;
                }
            }

            DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex);
            BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector);
        }

        // If the file has sector CRC check turned on, perform it
        if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL)
        {
            DWORD dwAdlerExpected = hf->SectorChksums[dwIndex];
            DWORD dwAdlerValue = 0;

            // We can only check sector CRC when it's not zero
            // Neither can we check it if it's 0xFFFFFFFF.
            if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF)
            {
                dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector);
                if(dwAdlerValue != dwAdlerExpected)
                {
                    nError = ERROR_CHECKSUM_ERROR;
                    break;
                }
            }
        }

        // If the sector is really compressed, decompress it.
        // WARNING : Some sectors may not be compressed, it can be determined only
        // by comparing uncompressed and compressed size !!!
        if(dwRawBytesInThisSector < dwBytesInThisSector)
        {
            int cbOutSector = dwBytesInThisSector;
            int cbInSector = dwRawBytesInThisSector;
            int nResult = 0;

            // Is the file compressed by PKWARE Data Compression Library ?
            if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
                nResult = SCompExplode((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector);

            // Is the file compressed by Blizzard's multiple compression ?
            if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
                nResult = SCompDecompress((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector);

            // Did the decompression fail ?
            if(nResult == 0)
            {
                nError = ERROR_FILE_CORRUPT;
                break;
            }
        }
        else
        {
            if(pbOutSector != pbInSector)
                memcpy(pbOutSector, pbInSector, dwBytesInThisSector);
        }

        // Move pointers
        dwBytesToRead -= dwBytesInThisSector;
        dwByteOffset += dwBytesInThisSector;
        dwBytesRead += dwBytesInThisSector;
        pbOutSector += dwBytesInThisSector;
        pbInSector += dwRawBytesInThisSector;
        dwSectorsDone++;
    }

    // Free all used buffers
    if(pbRawSector != NULL)
        FREEMEM(pbRawSector);
    
    // Give the caller thenumber of bytes read
    *pdwBytesRead = dwBytesRead;
    return nError; 
}
Esempio n. 25
0
UINT32 Checksum(UINT8 *lpData, UINT32 uiSize)
{
	//return (adler32(0, lpData, uiSize) ^ CRC32(lpData, uiSize));
	return (adler32(0, lpData, uiSize) ^ crc32(0, lpData, uiSize));
}
Esempio n. 26
0
// ==============================================================
// Extract License & Notes files
// These are stored as 4-bytes length, followed by length-bytes of compressed data
int	ExtractTextFile(BLOCK_DATA *Blk, ULONG FileType)
{
		ULONG n, m;
		BYTE *zSrcBuf = (BYTE *) Blk->SrcBuf;
		BYTE *zDstBuf = (BYTE *) Blk->DstBuf;

		const char *FileExt;
		if (FileType == FLAGS_License)
			FileExt = LicenseExt;
		else if (FileType == FLAGS_Notes)
			FileExt = NotesExt;
		else
			return 0;

		// NB:Can't use BioReadBuf... aligment problems? Yet it works for ProcessNextBlock() !!??
		// Ok, can use ReadInputFile here cause everythjing is whole no. of bytes...

		//BioReadBuf((BYTE *)&n, sizeof(n));					// Read length of block from file
	  ReadInputFile((BYTE *)&n, sizeof(n));					// Read length of block from file
	  FixEndian(&n, sizeof(n));										// Fix endian

		if (n <= 0  ||  n > ZBUF_SIZE)								// Check for valid block length
		{
			sprintf(MsgTxt, "ERROR - Invalid length for %s file (apparently %ld bytes) %s", FileExt, n, CorruptedMsg);
			msg(MsgTxt, MSG_PopUp);
			GlobalErrorFlag = SFARKLIB_ERR_CORRUPT;
			return 0;
		}

		//BioReadBuf(zSrcBuf, n);																					// Read the block
	  ReadInputFile((BYTE *)zSrcBuf, n);																// Read the block
		m = UnMemcomp(zSrcBuf, n, zDstBuf, ZBUF_SIZE);										// Uncompress
		Blk->FileCheck = adler32(Blk->FileCheck, zDstBuf, m);	   					// Accumulate checksum
		if (GlobalErrorFlag  ||  m > ZBUF_SIZE)														// Uncompressed ok & size is valid?
			return 0;

		// Write file - Use original file name plus specified extension for OutFileName...
		char OutFileName[MAX_FILENAME];
		strncpy(OutFileName, Blk->FileHeader.FileName, sizeof(OutFileName));	// copy output filename
		ChangeFileExt(OutFileName, FileExt, sizeof(OutFileName));
		OpenOutputFile(OutFileName);	// Create notes / license file
		WriteOutputFile(zDstBuf, m);																			// and write to output file
		CloseOutputFile();
		if (FileType == FLAGS_License)
		{
                    sprintf(MsgTxt, "Created license file: %s", OutFileName);
                    msg(MsgTxt, 0);
			if (GetLicenseAgreement((const char *)zDstBuf, OutFileName) == 0)
			{
				GlobalErrorFlag = SFARKLIB_ERR_LICENSE;
				return EndProcess(0);
			}
		}
		else if (FileType == FLAGS_Notes)
                {
                    sprintf(MsgTxt, "Created notes file: %s", OutFileName);
                    msg(MsgTxt, 0);
                    DisplayNotes((const char *)zDstBuf, OutFileName);
                }

		return 1;
}
Esempio n. 27
0
// ==============================================================
int ProcessNextBlock(BLOCK_DATA *Blk)
{
    //int	TotBytesRead = 0;						// Total bytes read in file
    int	NumWords;							//

    uint32_t	n, m;							// NB: Must be 32-bit integer

    #define	AWBYTES	(sizeof(AWORD))
    BYTE *zSrcBuf = (BYTE *) Blk->SrcBuf;
    BYTE *zDstBuf = (BYTE *) Blk->DstBuf;

    switch (Blk->FileSection)
    {
      case AUDIO:
      {
	NumWords = Blk->ReadSize;					// Number of words we will read in this block
	n = NumWords * AWBYTES;						// ... and number of bytes

	if (Blk->TotBytesWritten + n >= Blk->FileHeader.PostAudioStart)			// Short block? (near end of file)
	{
	    n = Blk->FileHeader.PostAudioStart - Blk->TotBytesWritten;				// Get exact length in bytes
	    NumWords = n / AWBYTES;																						// ... and words
	    Blk->FileSection = POST_AUDIO;		// End of Audio -- PostAudio section is next
	}
    
	//printf("AUDIO, read %ld bytes\n", n);

	if (Blk->FileHeader.CompMethod == COMPRESSION_v2Turbo)						// If using Turbo compression
	  DecompressTurbo(Blk, NumWords);									// Decompress
	else																															// For all other methods
	  DecompressFast(Blk, NumWords);										// Decompress

	//printf("B4 WriteOutputFile: %ld\n", adler32(0, (const BYTE *) Blk->SrcBuf, n) & 0xffff);
	/*#ifdef __BIG_ENDIAN__
	#define	WFIX(I)		s = bp[I+0]; bp[I+0] = bp[I+1]; bp[I+1] = s;
	BYTE *bp = (BYTE *) Blk->SrcBuf; BYTE *ep = bp + n;
	do {						
	  BYTE s;					
	  WFIX(0); WFIX(2); WFIX(4); WFIX(6);		
	  WFIX(8); WFIX(10); WFIX(12); WFIX(14);	
	  bp += 16;					
	} while (bp < ep);				
	#undef WFIX
	#endif*/
	
	WriteOutputFile((const BYTE *)Blk->SrcBuf, n);										// Write to output file
	Blk->TotBytesWritten += n;																				// Accumulate total bytes written
	break;
      }
	
      case PRE_AUDIO: case POST_AUDIO: case NON_AUDIO:
      {
	BioReadBuf((BYTE *) &n, sizeof(n));	
	FixEndian(&n, sizeof(n));
	//printf("Reading PRE/POST AUDIO block, compressed %ld bytes\n", n);
	if (n > ZBUF_SIZE)	// Check for valid block length
	{
	  sprintf(MsgTxt, "ERROR - Invalid length for Non-audio Block (apparently %d bytes) %s", n, CorruptedMsg);
	  msg(MsgTxt, MSG_PopUp);
	  return (GlobalErrorFlag = SFARKLIB_ERR_CORRUPT);
	}

	BioReadBuf(zSrcBuf, n);		// Read the block
	m = UnMemcomp(zSrcBuf, n, zDstBuf, ZBUF_SIZE);											//printf("PRE/POST AUDIO block, compressed %ld bytes, uncompressed %ld bytes\n", n, m);

	// Uncompress
	if (GlobalErrorFlag != SFARKLIB_SUCCESS)  return(GlobalErrorFlag);
	if (m <= ZBUF_SIZE)														// Uncompressed ok & size is valid?
	{
	  //printf("writing uncompressed block %ld bytes\n", m);
	  Blk->FileCheck = adler32(Blk->FileCheck, zDstBuf, m);	// Accumulate checksum
	  WriteOutputFile(zDstBuf, m);				// and write to output file
	  Blk->TotBytesWritten += m;				// Accumulate byte count
	}
	else
	  return SFARKLIB_ERR_CORRUPT;

	#if	DB_BLOCKCHECK					// If debug mode block check enabled
	ULONG BlockCheck = BioRead(16);				// Read block check bits
	FixEndian(&BlockCheck, sizeof(Blockcheck));
	ULONG CalcBlockCheck = adler32(0, zDstBuf, m) & 0xFFFF;
	printf("NonAudio Block Checks Read: %ld, Calc %ld Length=%d\n", BlockCheck, CalcBlockCheck, m);
	if (BlockCheck != CalcBlockCheck)			// Compare to calculated cheksum
	{
	  printf("*** NonAudio Block check FAIL\n");
	}
	else
	  printf("NonAudio Block check Ok\n");
	#endif

	//printf("PRE/POST AUDIO, read %ld bytes, writing %ld bytes...", n, m);

        if (Blk->TotBytesWritten >= Blk->FileHeader.OriginalSize)	// Have we finished the file?
	  Blk->FileSection = FINISHED;
	else if (Blk->FileSection == PRE_AUDIO && Blk->TotBytesWritten >= Blk->FileHeader.AudioStart)	// finished Pre-Audio?
	  Blk->FileSection = AUDIO;					// .. then next section is Audio

	break;
      } // case
    } //switch

    //sprintf(MsgTxt, "BytesWritten: %ld of %ld", Blk->TotBytesWritten, Blk->FileHeader.OriginalSize);
    //msg(MsgTxt, 0);
    return SFARKLIB_SUCCESS;
}
Esempio n. 28
0
int DecompressFast(BLOCK_DATA *Blk, USHORT NumWords)
{
    int	i, EncodeCount;
    short	ShiftVal[NSHIFTS];						// Shift values (one per SHIFTWIN words)
    USHORT	Method[MAX_DIFF_LOOPS];				// Block processing methods used per iteration

    #if	DB_BLOCKCHECK											// If debug mode block check enabled
        ULONG BlockCheck = BioRead(16);				// Read block check bits
    #endif

    int UsingShift = CheckShift(ShiftVal, NumWords, &Blk->PrevShift, &Blk->PrevUsedShift);
    int UsingBD4 = BioReadFlag();			// See if using BD4

    if (UsingBD4)
    {
        EncodeCount = InputDiff(Blk->BD4PrevEncodeCount);
        if (InvalidEncodeCount(EncodeCount, Blk->MaxBD4Loops))  return(GlobalErrorFlag = SFARKLIB_ERR_CORRUPT);
        Blk->BD4PrevEncodeCount = EncodeCount;
    }
    else	// Using BD2/3
    {
        EncodeCount = InputDiff(Blk->PrevEncodeCount);
        if (InvalidEncodeCount(EncodeCount, Blk->MaxLoops))  return(GlobalErrorFlag = SFARKLIB_ERR_CORRUPT);
        Blk->PrevEncodeCount = EncodeCount;

        for(i = 0; i < EncodeCount; i++)
            Method[i] = BioReadFlag();			// Read flags for BD2/3
    }

    // If using LPC, check for and read flags...
    ULONG LPCflags;
    int UsingLPC = (Blk->FileHeader.CompMethod != COMPRESSION_v2Fast);
    if (UsingLPC)
    {
        if (BioReadFlag())	// Any flags?
            LPCflags = BioRead(16) | (BioRead(16) << 16);	// Then read them (32 bits)
	else																						// else
            LPCflags = 0;
    }

    // Read the file and unpack the bitstream into buffer at Buf1p...
    if (int UnCrunchResult = UnCrunchWin(Blk->SrcBuf, NumWords, OPTWINSIZE) < 0)		// failed?
    {
        sprintf(MsgTxt, "ERROR - UnCrunchWin returned: %d %s", UnCrunchResult, CorruptedMsg);
	msg(MsgTxt, MSG_PopUp);
        return(GlobalErrorFlag = SFARKLIB_ERR_CORRUPT);
    }

    if (UsingLPC)
    {
        UnLPC(Blk->DstBuf, Blk->SrcBuf, NumWords, Blk->nc, &LPCflags);
	AWORD *SwapBuf = Blk->SrcBuf;  Blk->SrcBuf = Blk->DstBuf; Blk->DstBuf = SwapBuf;
    }
    
    if (UsingBD4)
    {
        for (i = EncodeCount-1; i >= 0; i--)
	{
            UnBufDif4(Blk->DstBuf, Blk->SrcBuf, NumWords, &(Blk->PrevIn[i]));
            AWORD *SwapBuf = Blk->SrcBuf;  Blk->SrcBuf = Blk->DstBuf; Blk->DstBuf = SwapBuf;
	}
    }
    else
    {
        for (i = EncodeCount-1; i >= 0; i--)
	{
            switch (Method[i])
            {
                case 0: UnBufDif2(Blk->DstBuf, Blk->SrcBuf, NumWords, &(Blk->PrevIn[i])); break;
                case 1: UnBufDif3(Blk->DstBuf, Blk->SrcBuf, NumWords, &(Blk->PrevIn[i])); break;
            }
            AWORD *SwapBuf = Blk->SrcBuf;  Blk->SrcBuf = Blk->DstBuf; Blk->DstBuf = SwapBuf;
	}
    }

    if (UsingShift)  UnBufShift(Blk->SrcBuf, NumWords, ShiftVal);

    #if	DB_BLOCKCHECK											// If debug mode block check enabled
	ULONG CalcBlockCheck = adler32(0, (const BYTE *) Blk->SrcBuf, 2*NumWords) & 0xffff;
	//ULONG CalcBlockCheck = Blk->FileCheck & 0xffff;
	//printf("Audio Block Checks Read: %ld, Calc %ld  Length=%d\n", BlockCheck, CalcBlockCheck, 2*NumWords);
	//getc(stdin);
	if (BlockCheck != CalcBlockCheck)			// Compare to calculated cheksum
	{
            msg("*** Audio Block check FAIL");
	}
	//else
        //  printf("Audio Block check Ok\n");
    #endif

    Blk->FileCheck = 2 * Blk->FileCheck + BufSum(Blk->SrcBuf, NumWords);
    return SFARKLIB_SUCCESS;
}
Esempio n. 29
0
// Read the File Header....
int ReadHeader(V2_FILEHEADER *FileHeader, BYTE *fbuf, int bufsize)
{
  int HeaderLen = 0, HdrOffset;
  char	CreatedByProg[HDR_NAME_LEN +1],  CreatedByVersion[HDR_VERS_LEN +1];
  ULONG	CalcHdrCheck = 0;
  BYTE *HdrBuf, *bpFileHeader = (BYTE *) FileHeader;

  // Find and process the Header:  This could be a plain sfArk file, a self-extracting file or some other (invalid) file.
  // Also, it could be a sfArk V1 file, which we can't decompress, but should at least recognise.
  // We locate the header by looking for the string "sfArk" within the first HEADER_MAX_OFFSET bytes of the file
  // but because self-extractor code is likely to contain that string, we look for its final occurence
  // by searching backwards.
  // To speed things up, we first check at offset 0 (the case for a standard sfArk file)
  // If we think we've found a (V2) header, we veryify it using the Header checksum.  If the checksum fails,
  // chances are it was a corrupt file, but could conceivably be a non-sfArk file.  either way we report it as corrupt.
  
  int fbufsize = HEADER_MAX_OFFSET + V2_FILEHEADER_SIZE;		// Amount data to read
  if (fbufsize > bufsize)  fbufsize = bufsize;				// Buffer too small (should never happen)

  SetInputFilePosition(0);						// set to logical start (maybe a predefined offset) 
  RETURN_ON_ERROR();
  ReadInputFile(fbuf, fbufsize);					// Read a chunk of data from the start of the file
  RETURN_ON_ERROR();

  int SigFound = 0, SeemsV1 = 0, HdrCheckDone = 0;		// Some flags to remember what we're doing

  for(int TryOffset = 0; TryOffset < HEADER_MAX_OFFSET; TryOffset++)
  {
    HdrOffset = (TryOffset == 0)? 0 : HEADER_MAX_OFFSET - TryOffset; // Check offset = 0 first, then backwards from end  
    
    BYTE *sigpos = fbuf + HdrOffset + HEADER_SIG_POS;
    if (*sigpos != 's'  ||  memcmp(sigpos, "sfArk", 5) != 0)  continue;
    
    SigFound = 1;					// Set a flag to remember that we at least got this far
    HdrBuf = fbuf + HdrOffset; 
       
    if (V2_FILEHEADER_SIZE != sizeof(V2_FILEHEADER))	// Compare structure size to real size
    {
      // The compiler has messed with structure (alignment), so copy the data to the structure byte by byte...
      BYTE *bptr = HdrBuf;		// Point to start
      // Copy all fields...
      #define CPF(f) memcpy(&(FileHeader->f), bptr, sizeof(FileHeader->f)); bptr += sizeof(FileHeader->f)
      CPF(Flags); CPF(OriginalSize); CPF(CompressedSize); CPF(FileCheck); CPF(HdrCheck);
      CPF(ProgVersionNeeded); CPF(ProgVersion); CPF(ProgName); CPF(CompMethod);
      CPF(FileType); CPF(AudioStart); CPF(PostAudioStart); CPF(FileName);
      #undef CPF
      if (bptr != HdrBuf+V2_FILEHEADER_SIZE)	return (GlobalErrorFlag = SFARKLIB_ERR_OTHER);	// Sanity check
    }
    else
      memcpy(bpFileHeader, HdrBuf, V2_FILEHEADER_SIZE);	// Copy entire data block to structure
      
    if (FileHeader->CompMethod < COMPRESSION_v2)	// Looks like a sfArk V1 file?
    {
      SeemsV1 = 1;					// set a flag
      continue;						// and keep searching
    }

    // Header->FileName is a null-terminated string, we need it's length to calculate actual length of header data...
    FileHeader->FileName[sizeof(FileHeader->FileName) -1] = '\0'; // Ensure strlen finds a terminator (string may be junk)
    HeaderLen = V2_FILEHEADER_SIZE - sizeof(FileHeader->FileName) + strlen(FileHeader->FileName) + 1;

    // If we get this far, there's a good chance we've got the header...
    /*#ifdef	__BIG_ENDIAN__
      // FixEndians of all multi-byte integers (currently only relevent to Mac)
      #define FIXENDIAN(field)	FixEndian(&(FileHeader->field), sizeof(FileHeader->field))
      FIXENDIAN(Flags); 	FIXENDIAN(OriginalSize); 	FIXENDIAN(CompressedSize);
      FIXENDIAN(FileCheck);	FIXENDIAN(HdrCheck); 		FIXENDIAN(FileType);
      FIXENDIAN(AudioStart);	FIXENDIAN(PostAudioStart);
      #undef FIXENDIAN
    #endif*/
      
    // Ok now, we know the HeaderLength and have the FileHeader structure properly populated...
    #if 0
    // debug, display header...
    printf("Flags %lx  OrignalSize %ld  CompressedSize %ld\n", FileHeader->Flags, FileHeader->OriginalSize, FileHeader->CompressedSize);
    printf("FileCheck %lx  HdrCheck %lx  ProgVersionNeeded %d\n", FileHeader->FileCheck, FileHeader->HdrCheck, FileHeader->ProgVersionNeeded);
    printf("AudioStart %ld  PostAudioStart %ld  Orginal filename %s\n", FileHeader->AudioStart, FileHeader->PostAudioStart, FileHeader->FileName);
    #endif
    *(uint32_t *)(HdrBuf+HEADER_HDRCHECK_POS) = 0;			// Zero-out the HeaderChecksum position in the buffer
    CalcHdrCheck = adler32(0, HdrBuf, HeaderLen);		// and recalculate the header checksum
    HdrCheckDone = 1;
    if (CalcHdrCheck == FileHeader->HdrCheck)  break;		// Check passed: Yes, we've found the header!
  }

  // When we get here, see what happened:
  if (SigFound && HdrCheckDone && CalcHdrCheck == FileHeader->HdrCheck)	// Everything Ok!  File is V2 and valid
    ; 							// Fall through to below (everything else is an error)
  else if (SeemsV1)					// Seems to be a sfArkV1 file
  {
    sprintf(MsgTxt, "This file was created with sfArk V1, and this program only handles sfArk V2+ files.  Unfortunately sfArk V1 uses a proprietary compression algorithm for the non-audio metadata, so we cannot really support that. You might try running the Windows sfArk program from http://melodymachine.com/sfark.htm under Wine."); 
    msg(MsgTxt, MSG_PopUp);
    return (GlobalErrorFlag = SFARKLIB_ERR_INCOMPATIBLE);
  }
  else if (SigFound)					// Apparently a corrupt sfArk file (well, it had "sfArk" in it!)
  {
    sprintf(MsgTxt, "File Header fails checksum!%s", CorruptedMsg);
    msg(MsgTxt, MSG_PopUp);
    return (GlobalErrorFlag = SFARKLIB_ERR_HEADERCHECK);
  }
  else							// Either very corrupted, or not a sfArk file
  {
    sprintf(MsgTxt, "This does not appear to be a sfArk file!");
    msg(MsgTxt, MSG_PopUp);
    return (GlobalErrorFlag = SFARKLIB_ERR_SIGNATURE);
  }

  // Get CreatedBy program name and version number (need null-terminated strings)...
  strncpy(CreatedByProg, FileHeader->ProgName, HDR_NAME_LEN);			// Copy program name
  CreatedByProg[HDR_NAME_LEN] = 0;																		// Terminate string
  strncpy(CreatedByVersion, FileHeader->ProgVersion, HDR_VERS_LEN);		// Copy version string
  CreatedByVersion[HDR_VERS_LEN] = 0;																	// Terminate string

  // Check for compatible version...
  if (FileHeader->ProgVersionNeeded > ProgVersionMaj)
  {
    sprintf(MsgTxt, "You need %s version %2.1f (or higher) to decompress this file (your version is %s) %s", 
		ProgName, (float)FileHeader->ProgVersionNeeded/10, ProgVersion, UpgradeMsg);
    msg(MsgTxt, MSG_PopUp);
    return (GlobalErrorFlag = SFARKLIB_ERR_INCOMPATIBLE);
  }

  // Warn if file was created by a newer version than this version...
  float fProgVersion = (float) atof(ProgVersion);
  float fCreatedByVersion = (float) atof(CreatedByVersion);
  if (fCreatedByVersion > fProgVersion)
  {
    sprintf(MsgTxt, "This file was created with %s %s.  Your version of %s (%s) can uncompress this file, "
			"but you might like to obtain the latest version.  %s",
			CreatedByProg, CreatedByVersion, ProgName, ProgVersion, UpgradeMsg);
    msg(MsgTxt, MSG_PopUp);
  }

  SetInputFilePosition(HdrOffset + HeaderLen);	// re-wind file to start of post-header data
  RETURN_ON_ERROR();
  return SFARKLIB_SUCCESS;
}
Esempio n. 30
0
void
dkcsumattach(void)
{
	struct device *dv;
	struct buf *bp;
	struct bdevsw *bdsw;
	dev_t dev;
	int error;
	u_int32_t csum;
	bios_diskinfo_t *bdi, *hit;

	/* do nothing if no diskinfo passed from /boot, or a bad length */
	if (bios_diskinfo == NULL || bios_cksumlen * DEV_BSIZE > MAXBSIZE)
		return;

	/*
	 * XXX Whatif DEV_BSIZE is changed to something else than the BIOS
	 * blocksize?  Today, /boot doesn't cover that case so neither need
	 * I care here.
	 */
	bp = geteblk(bios_cksumlen * DEV_BSIZE);	/* XXX error check?  */

	for (dv = alldevs.tqh_first; dv; dv = dv->dv_list.tqe_next) {

		if (dv->dv_class != DV_DISK)
			continue;
		bp->b_dev = dev = dev_rawpart(dv);
		if (dev == NODEV)
			continue;
		bdsw = &bdevsw[major(dev)];

		/*
		 * This open operation guarantees a proper initialization
		 * of the device, for future strategy calls.
		 */
		error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc);
		if (error) {
			/* XXX What to do here? */
			if (error != EIO)
				printf("dkcsum: open of %s failed (%d)\n",
				    dv->dv_xname, error);
			continue;
		}

		/* Read blocks to cksum.  XXX maybe a d_read should be used. */
		bp->b_blkno = 0;
		bp->b_bcount = bios_cksumlen * DEV_BSIZE;
		bp->b_flags = B_BUSY | B_READ;
		bp->b_cylin = 0;
		(*bdsw->d_strategy)(bp);
		if (biowait(bp)) {
			/* XXX What to do here? */
			printf("dkcsum: read of %s failed (%d)\n",
			    dv->dv_xname, error);
			error = (*bdsw->d_close)(dev, 0, S_IFCHR, curproc);
			if (error)
				printf("dkcsum: close of %s failed (%d)\n",
				    dv->dv_xname, error);
			continue;
		}
		error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
		if (error) {
			/* XXX What to do here? */
			printf("dkcsum: close of %s failed (%d)\n",
			    dv->dv_xname, error);
			continue;
		}

		csum = adler32(0, bp->b_data, bios_cksumlen * DEV_BSIZE);
#ifdef DEBUG
		printf("dkcsum: checksum of %s is %x\n", dv->dv_xname, csum);
#endif

		/* Find the BIOS device */
		hit = 0;
		for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++) {
			/* Skip non-harddrives */
			if (!(bdi->bios_number & 0x80))
				continue;
#ifdef DEBUG
			printf("dkcsum: "
			    "attempting to match with BIOS drive %x csum %x\n",
			    bdi->bios_number, bdi->checksum);
#endif
			if (bdi->checksum == csum) {
				if (!hit && !(bdi->flags & BDI_PICKED))
					hit = bdi;
				else {
					/* XXX add other heuristics here.  */
					printf("dkcsum: warning: "
					    "dup BSD->BIOS disk mapping\n");
				}
			}
		}

		/*
		 * If we have no hit, that's OK, we can see a lot more devices
		 * than the BIOS can, so this case is pretty normal.
		 */
		if (hit) {
#ifdef DIAGNOSTIC
			printf("dkcsum: %s matched BIOS disk %x\n",
			    dv->dv_xname, hit->bios_number);
#endif
		} else {
#ifdef DIAGNOSTIC
			printf("dkcsum: %s had no matching BIOS disk\n",
			    dv->dv_xname);
#endif
			continue;
		}

		/* Fixup bootdev if units match.  This means that all of
		 * hd*, sd*, wd*, will be interpreted the same.  Not 100%
		 * backwards compatible, but sd* and wd* should be phased-
		 * out in the bootblocks.
		 */
		if (B_UNIT(bootdev) == (hit->bios_number & 0x7F)) {
			int type, ctrl, adap, part, unit;

			/* Translate to MAKEBOOTDEV() style */
			type = major(bp->b_dev);
			adap = B_ADAPTOR(bootdev);
			ctrl = B_CONTROLLER(bootdev);
			unit = DISKUNIT(bp->b_dev);
			part = B_PARTITION(bootdev);

			bootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
		}

		/* This will overwrite /boot's guess, just so you remember */
		hit->bsd_dev = MAKEBOOTDEV(major(bp->b_dev), 0, 0,
		    DISKUNIT(bp->b_dev), RAW_PART);
		hit->flags |= BDI_PICKED;
	}
	bp->b_flags |= B_INVAL;
	brelse(bp);
}