Beispiel #1
0
static inline int disks_to_vdisks(struct disk *ds, int nmds, struct vdisk *vds)
{
	struct disk *d_iter = ds;
	int i, j, nr_vdisks = 0;
	uint64_t hval;

	while (nmds--) {
		hval = FNV1A_64_INIT;

		for (i = 0; i < d_iter->nr_vdisks; i++) {
			hval = fnv_64a_buf(&nmds, sizeof(nmds), hval);
			for (j = strlen(d_iter->path) - 1; j >= 0; j--)
				hval = fnv_64a_buf(&d_iter->path[j], 1, hval);

			vds[nr_vdisks].id = hval;
			vds[nr_vdisks].idx = d_iter - ds;

			nr_vdisks++;
		}

		d_iter++;
	}
	qsort(vds, nr_vdisks, sizeof(*vds), vdisk_cmp);

	return nr_vdisks;
}
Beispiel #2
0
static int obj_cmp(const void *oid1, const void *oid2)
{
	const uint64_t hval1 = fnv_64a_buf((void *)oid1, sizeof(uint64_t), FNV1A_64_INIT);
	const uint64_t hval2 = fnv_64a_buf((void *)oid2, sizeof(uint64_t), FNV1A_64_INIT);

	if (hval1 < hval2)
		return -1;
	if (hval1 > hval2)
		return 1;
	return 0;
}
Beispiel #3
0
int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
	size_t len;
	int ret;
	char *sockname = &addr->sun_path[1];
	char *path;
	uint64_t hash;

	/* addr.sun_path is only 108 bytes, so we hash the full name and
	 * then append as much of the name as we can fit.
	 */
	memset(addr, 0, sizeof(*addr));
	addr->sun_family = AF_UNIX;
	len = strlen(lxcpath) + 18;
	path = alloca(len);
	ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
	if (ret < 0 || ret >= len) {
		ERROR("memory error creating monitor path");
		return -1;
	}

	len = sizeof(addr->sun_path) - 1;
	hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
	ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath);
	if (ret < 0)
		return -1;
	sockname[sizeof(addr->sun_path)-3] = '\0';
	INFO("using monitor sock name %s", sockname);
	return 0;
}
Beispiel #4
0
int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
	size_t len;
	int ret;
	char *sockname = &addr->sun_path[1];
	char path[PATH_MAX+18];
	uint64_t hash;

	/* addr.sun_path is only 108 bytes, so we hash the full name and
	 * then append as much of the name as we can fit.
	 */
	memset(addr, 0, sizeof(*addr));
	addr->sun_family = AF_UNIX;
	len = sizeof(addr->sun_path) - 1;
	ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath);
	if (ret < 0 || ret >= sizeof(path)) {
		ERROR("lxcpath %s too long for monitor unix socket", lxcpath);
		return -1;
	}

	hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
	ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath);
	if (ret < 0)
		return -1;
	sockname[sizeof(addr->sun_path)-2] = '\0';
	INFO("using monitor sock name %s", sockname);
	return 0;
}
Beispiel #5
0
static struct vdisk *oid_to_vdisk_from(struct vdisk *vds, int nr, uint64_t oid)
{
	uint64_t id = fnv_64a_buf(&oid, sizeof(oid), FNV1A_64_INIT);
	int start, end, pos;

	start = 0;
	end = nr - 1;

	if (id > vds[end].id || id < vds[start].id)
		return &vds[start];

	for (;;) {
		pos = (end - start) / 2 + start;
		if (vds[pos].id < id) {
			if (vds[pos + 1].id >= id)
				return &vds[pos + 1];
			start = pos;
		} else
			end = pos;
	}
}
Beispiel #6
0
static uint64_t shm_queue_calc_chksum(void)
{
	return fnv_64a_buf(shm_queue->events + shm_queue->pos,
			   sizeof(*shm_queue->events), FNV1A_64_INIT);
}
Beispiel #7
0
/*
 * __wt_hash_fnv64 --
 *	WiredTiger wrapper around third party hash implementation.
 */
uint64_t
__wt_hash_fnv64(const void *string, size_t len)
{
	return (fnv_64a_buf(string, len, FNV1A_64_INIT));
}
Beispiel #8
0
/*
 * test_fnv64 - test the FNV64 hash
 *
 * given:
 *	hash_type	type of FNV hash to test
 *	init_hval	initial hash value
 *	mask	  	lower bit mask
 *	v_flag	  	1 => print test failure info on stderr
 *	code	  0 ==> generate FNV test vectors
 *		  1 ==> validate against FNV test vectors
 *
 * returns:	0 ==> OK, else test vector failure number
 */
static int
test_fnv64(enum fnv_type hash_type, Fnv64_t init_hval,
	   Fnv64_t mask, int v_flag, int code)
{
    struct test_vector *t;	/* FNV test vestor */
    Fnv64_t hval;		/* current hash value */
    int tstnum;			/* test vector that failed, starting at 1 */

    /*
     * print preamble if generating test vectors
     */
    if (code == 0) {
	switch (hash_type) {
	case FNV0_64:
	    printf("struct fnv0_64_test_vector fnv0_64_vector[] = {\n");
	    break;
	case FNV1_64:
	    printf("struct fnv1_64_test_vector fnv1_64_vector[] = {\n");
	    break;
	case FNV1a_64:
	    printf("struct fnv1a_64_test_vector fnv1a_64_vector[] = {\n");
	    break;
	default:
	    unknown_hash_type(program, hash_type, 12);	/* exit(12) */
	    /*NOTREACHED*/
    	}
    }

    /*
     * loop thru all test vectors
     */
    for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) {

        /*
	 * compute the FNV hash
	 */
	hval = init_hval;
	switch (hash_type) {
	case FNV0_64:
	case FNV1_64:
	    hval = fnv_64_buf(t->buf, t->len, hval);
	    break;
	case FNV1a_64:
	    hval = fnv_64a_buf(t->buf, t->len, hval);
	    break;
	default:
	    unknown_hash_type(program, hash_type, 13);	/* exit(13) */
	    /*NOTREACHED*/
	}

	/*
	 * print the vector
	 */
#if defined(HAVE_64BIT_LONG_LONG)
	/*
	 * HAVE_64BIT_LONG_LONG testing
	 */
	switch (code) {
	case 0:		/* generate the test vector */
	    printf("    { &fnv_test_str[%d], (Fnv64_t) 0x%016llxULL },\n",
	    	   tstnum-1, hval & mask);
	    break;

	case 1:		/* validate against test vector */
	    switch (hash_type) {
	    case FNV0_64:
		if ((hval&mask) != (fnv0_64_vector[tstnum-1].fnv0_64 & mask)) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv0_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%016llx != generated: 0x%016llx\n",
			    program,
			    (hval&mask),
			    (fnv0_64_vector[tstnum-1].fnv0_64 & mask));
		    }
		    return tstnum;
		}
	    	break;
	    case FNV1_64:
		if ((hval&mask) != (fnv1_64_vector[tstnum-1].fnv1_64 & mask)) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv1_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%016llx != generated: 0x%016llx\n",
			    program,
			    (hval&mask),
			    (fnv1_64_vector[tstnum-1].fnv1_64 & mask));
		    }
		    return tstnum;
		}
	    	break;
	    case FNV1a_64:
		if ((hval&mask) != (fnv1a_64_vector[tstnum-1].fnv1a_64 &mask)) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv1a_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%016llx != generated: 0x%016llx\n",
			    program,
			    (hval&mask),
			    (fnv1a_64_vector[tstnum-1].fnv1a_64 & mask));
		    }
		    return tstnum;
		}
	    	break;
	    }
	    break;

    	default:
	    fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
	    exit(14);
    	}
#else /* HAVE_64BIT_LONG_LONG */
	/*
	 * non HAVE_64BIT_LONG_LONG testing
	 */
	switch (code) {
	case 0:		/* generate the test vector */
	    printf("    { &fnv_test_str[%d], "
	    	   "(Fnv64_t) {0x%08lxUL, 0x%08lxUL} },\n",
	    	   tstnum-1,
		   (hval.w32[0] & mask.w32[0]),
		   (hval.w32[1] & mask.w32[1]));
	    break;

	case 1:		/* validate against test vector */
	    switch (hash_type) {
	    case FNV0_64:
		if (((hval.w32[0] & mask.w32[0]) !=
		     (fnv0_64_vector[tstnum-1].fnv0_64.w32[0] &
		      mask.w32[0])) &&
		    ((hval.w32[1] & mask.w32[1]) !=
		     (fnv0_64_vector[tstnum-1].fnv0_64.w32[1] &
		      mask.w32[1]))) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv0_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%08llx%08llx != "
			    "generated: 0x%08llx%08llx\n",
			    program,
			    (hval.w32[0] & mask.w32[0]),
			    (hval.w32[1] & mask.w32[1]),
			    ((fnv0_64_vector[tstnum-1].fnv0_64.w32[0] &
			     mask.w32[0])),
			    ((fnv0_64_vector[tstnum-1].fnv0_64.w32[1] &
			     mask.w32[1])));
		    }
		    return tstnum;
		}
	    	break;
	    case FNV1_64:
		if (((hval.w32[0] & mask.w32[0]) !=
		     (fnv1_64_vector[tstnum-1].fnv1_64.w32[0] &
		      mask.w32[0])) &&
		    ((hval.w32[1] & mask.w32[1]) !=
		     (fnv1_64_vector[tstnum-1].fnv1_64.w32[1] &
		      mask.w32[1]))) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv1_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%08llx%08llx != "
			    "generated: 0x%08llx%08llx\n",
			    program,
			    (hval.w32[0] & mask.w32[0]),
			    (hval.w32[1] & mask.w32[1]),
			    ((fnv1_64_vector[tstnum-1].fnv1_64.w32[0] &
			     mask.w32[0])),
			    ((fnv1_64_vector[tstnum-1].fnv1_64.w32[1] &
			     mask.w32[1])));
		    }
		    return tstnum;
		}
	    	break;
	    case FNV1a_64:
		if (((hval.w32[0] & mask.w32[0]) !=
		     (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] &
		      mask.w32[0])) &&
		    ((hval.w32[1] & mask.w32[1]) !=
		     (fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] &
		      mask.w32[1]))) {
		    if (v_flag) {
		    	fprintf(stderr, "%s: failed fnv1a_64 test # %d\n",
				program, tstnum);
		    	fprintf(stderr, "%s: test # 1 is 1st test\n", program);
			fprintf(stderr,
			    "%s: expected 0x%08llx%08llx != "
			    "generated: 0x%08llx%08llx\n",
			    program,
			    (hval.w32[0] & mask.w32[0]),
			    (hval.w32[1] & mask.w32[1]),
			    ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[0] &
			     mask.w32[0])),
			    ((fnv1a_64_vector[tstnum-1].fnv1a_64.w32[1] &
			     mask.w32[1])));
		    }
		    return tstnum;
		}
	    	break;
	    }
	    break;

    	default:
	    fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
	    exit(15);
    	}
#endif /* HAVE_64BIT_LONG_LONG */
    }

    /*
     * print completion if generating test vectors
     */
    if (code == 0) {
#if defined(HAVE_64BIT_LONG_LONG)
	printf("    { NULL, (Fnv64_t) 0 }\n");
#else /* HAVE_64BIT_LONG_LONG */
	printf("    { NULL, (Fnv64_t) {0,0} }\n");
#endif /* HAVE_64BIT_LONG_LONG */
	printf("};\n");
    }

    /*
     * no failures, return code 0 ==> all OK
     */
    return 0;
}
Beispiel #9
0
/*
 * main - the main function
 *
 * See the above usage for details.
 */
int
main(int argc, char *argv[])
{
    char buf[BUF_SIZE+1];	/* read buffer */
    int readcnt;		/* number of characters written */
    Fnv64_t hval;		/* current hash value */
    int s_flag = 0;		/* 1 => -s was given, hash args as strings */
    int m_flag = 0;		/* 1 => print multiple hashes, one per arg */
    int v_flag = 0;		/* 1 => verbose hash print */
    int b_flag = WIDTH;		/* -b flag value */
    int t_flag = -1;		/* FNV test vector code (0=>print, 1=>test) */
    enum fnv_type hash_type = FNV_NONE;	/* type of FNV hash to perform */
    Fnv64_t bmask;		/* mask to apply to output */
    extern char *optarg;	/* option argument */
    extern int optind;		/* argv index of the next arg */
    int fd;			/* open file to process */
    char *p;
    int i;

    /*
     * parse args
     */
    program = argv[0];
    while ((i = getopt(argc, argv, "b:mst:v")) != -1) {
	switch (i) {
	case 'b':	/* bcnt bit mask count */
	    b_flag = atoi(optarg);
	    break;
	case 'm':	/* print multiple hashes, one per arg */
	    m_flag = 1;
	    break;
	case 's':	/* hash args as strings */
	    s_flag = 1;
	    break;
	case 't':	/* FNV test vector code */
	    t_flag = atoi(optarg);
	    if (t_flag < 0 || t_flag > 1) {
		fprintf(stderr, "%s: -t code must be 0 or 1\n", program);
		fprintf(stderr, usage, program, FNV_VERSION);
		exit(1);
	    }
	    m_flag = 1;
	    break;
	case 'v':	/* verbose hash print */
	    m_flag = 1;
	    v_flag = 1;
	    break;
	default:
	    fprintf(stderr, usage, program, FNV_VERSION);
	    exit(1);
	}
    }
    /* -t code incompatible with -b, -m and args */
    if (t_flag >= 0) {
    	if (b_flag != WIDTH) {
	    fprintf(stderr, "%s: -t code incompatible with -b\n", program);
	    exit(2);
	}
    	if (s_flag != 0) {
	    fprintf(stderr, "%s: -t code incompatible with -s\n", program);
	    exit(3);
	}
	if (optind < argc) {
	    fprintf(stderr, "%s: -t code incompatible args\n", program);
	    exit(4);
	}
    }
    /* -s requires at least 1 arg */
    if (s_flag && optind >= argc) {
	fprintf(stderr, usage, program, FNV_VERSION);
	exit(5);
    }
    /* limit -b values */
    if (b_flag < 0 || b_flag > WIDTH) {
	fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n",
		program, b_flag, WIDTH);
	exit(6);
    }
#if defined(HAVE_64BIT_LONG_LONG)
    if (b_flag == WIDTH) {
	bmask = (Fnv64_t)0xffffffffffffffffULL;
    } else {
	bmask = (Fnv64_t)((1ULL << b_flag) - 1ULL);
    }
#else /* HAVE_64BIT_LONG_LONG */
    if (b_flag == WIDTH) {
	bmask.w32[0] = 0xffffffffUL;
	bmask.w32[1] = 0xffffffffUL;
    } else if (b_flag >= WIDTH/2) {
	bmask.w32[0] = 0xffffffffUL;
	bmask.w32[1] = ((1UL << (b_flag-(WIDTH/2))) - 1UL);
    } else {
	bmask.w32[0] = ((1UL << b_flag) - 1UL);
	bmask.w32[1] = 0UL;
    }
#endif /* HAVE_64BIT_LONG_LONG */

    /*
     * start with the initial basis depending on the hash type
     */
    p = strrchr(program, '/');
    if (p == NULL) {
	p = program;
    } else {
	++p;
    }
    if (strcmp(p, "fnv064") == 0 || strcmp(p, "no64bit_fnv064") == 0) {
	/* using non-recommended FNV-0 and zero initial basis */
	hval = FNV0_64_INIT;
	hash_type = FNV0_64;
    } else if (strcmp(p, "fnv164") == 0 || strcmp(p, "no64bit_fnv164") == 0) {
	/* using FNV-1 and non-zero initial basis */
	hval = FNV1_64_INIT;
	hash_type = FNV1_64;
    } else if (strcmp(p, "fnv1a64") == 0 || strcmp(p, "no64bit_fnv1a64") == 0) {
	 /* start with the FNV-1a initial basis */
	hval = FNV1A_64_INIT;
	hash_type = FNV1a_64;
    } else {
	fprintf(stderr, "%s: unknown program name, unknown hash type\n",
		program);
	exit(7);
    }

    /*
     * FNV test vector processing, if needed
     */
    if (t_flag >= 0) {
	int code;		/* test vector that failed, starting at 1 */

	/*
	 * perform all tests
	 */
	code = test_fnv64(hash_type, hval, bmask, v_flag, t_flag);

	/*
	 * evaluate the tests
	 */
	if (code == 0) {
	    if (v_flag) {
	    	printf("passed\n");
	    }
	    exit(0);
	} else {
	    printf("failed vector (1 is 1st test): %d\n", code);
	    exit(8);
	}
    }

    /*
     * string hashing
     */
    if (s_flag) {

	/* hash any other strings */
	for (i=optind; i < argc; ++i) {
	    switch (hash_type) {
	    case FNV0_64:
	    case FNV1_64:
		hval = fnv_64_str(argv[i], hval);
	    	break;
	    case FNV1a_64:
		hval = fnv_64a_str(argv[i], hval);
		break;
	    default:
		unknown_hash_type(program, hash_type, 9);	/* exit(9) */
		/*NOTREACHED*/
	    }
	    if (m_flag) {
		print_fnv64(hval, bmask, v_flag, argv[i]);
	    }
	}


    /*
     * file hashing
     */
    } else {

	/*
	 * case: process only stdin
	 */
	if (optind >= argc) {

	    /* case: process only stdin */
	    while ((readcnt = read(0, buf, BUF_SIZE)) > 0) {
		switch (hash_type) {
		case FNV0_64:
		case FNV1_64:
		    hval = fnv_64_buf(buf, readcnt, hval);
		    break;
		case FNV1a_64:
		    hval = fnv_64a_buf(buf, readcnt, hval);
		default:
		    unknown_hash_type(program, hash_type, 10);	/* exit(10) */
		    /*NOTREACHED*/
		}
	    }
	    if (m_flag) {
		print_fnv64(hval, bmask, v_flag, "(stdin)");
	    }

	} else {

	    /*
	     * process any other files
	     */
	    for (i=optind; i < argc; ++i) {

		/* open the file */
		fd = open(argv[i], O_RDONLY);
		if (fd < 0) {
		    fprintf(stderr, "%s: unable to open file: %s\n",
			    program, argv[i]);
		    exit(4);
		}

		/*  hash the file */
		while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) {
		    switch (hash_type) {
		    case FNV0_64:
		    case FNV1_64:
			hval = fnv_64_buf(buf, readcnt, hval);
			break;
		    case FNV1a_64:
			hval = fnv_64a_buf(buf, readcnt, hval);
		    default:
			unknown_hash_type(program, hash_type, 11);/* exit(11) */
			/*NOTREACHED*/
		    }
		}

		/* finish processing the file */
		if (m_flag) {
		    print_fnv64(hval, bmask, v_flag, argv[i]);
		}
		close(fd);
	    }
	}
    }

    /*
     * report hash and exit
     */
    if (!m_flag) {
	print_fnv64(hval, bmask, v_flag, "");
    }
    return 0;	/* exit(0); */
}
Beispiel #10
0
BOOL CNktDvDbMerge::LoadInputDbs()
{
  CDbMergeDvDatabase *lpDb;
  HRESULT hRes;
  TNktAutoFreePtr<BYTE> aCompressedData;
  HANDLE hFile = NULL;
  SIZE_T i, k, nCount, nCompressedSize;
  Fnv64_t nHashValue, nStoredHash;
  DWORD dw;
  LPBYTE s;

  PrintAndLog(L"Loading input databases... ");
  for (k=0; k<aInputDatabases.GetCount(); k++)
  {
    lpDb = new CDbMergeDvDatabase;
    if (lpDb == NULL)
    {
err_nomem:
      if (hFile != NULL)
        ::CloseHandle(hFile);
      PrintAndLogNoMemoryError();
      return FALSE;
    }
    if (aInputDbs.AddElement(lpDb) == FALSE)
    {
      delete lpDb;
      goto err_nomem;
    }

    //open database
    hFile = ::CreateFileW(aInputDatabases[k], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == NULL || hFile == INVALID_HANDLE_VALUE)
    {
      hFile = NULL;
dbload_err:
      hRes = NKT_HRESULT_FROM_LASTERROR();
dbload_err2:
      if (hRes == E_OUTOFMEMORY)
        goto err_nomem;
      PrintAndLog(L"\nError: Cannot load database [%s] (%08X).\n", aInputDatabases[k], (ULONG)hRes);
      return FALSE;
    }
    //load into memory
    nCompressedSize = (SIZE_T)::GetFileSize(hFile, NULL);
    if (nCompressedSize <= (17 + sizeof(ULONG) + sizeof(Fnv64_t)) ||
      nCompressedSize >= 0x0FFFFFFF)
    {
dbload_err_fail:
      hRes = E_FAIL;
      goto dbload_err2;
    }
    aCompressedData.Reset();
    aCompressedData.Attach((LPBYTE)nktMemMalloc(nCompressedSize));
    if (aCompressedData == NULL)
      goto err_nomem;
    if (::ReadFile(hFile, aCompressedData.Get(), (DWORD)nCompressedSize, &dw, NULL) == FALSE)
      goto dbload_err;
    if (nCompressedSize != (SIZE_T)dw)
      goto dbload_err;
    nCompressedSize -= (17 + sizeof(ULONG) + sizeof(Fnv64_t));
    //check signature and hash
    s = aCompressedData.Get();
    if (nktMemCompare(s, "Deviare Database\x1A", 17) != 0)
      goto dbload_err_fail;
    s += 17;
    dw = *((ULONG NKT_UNALIGNED *)s);
    lpDb->nDecompressedSize = (SIZE_T)dw;
    s += sizeof(ULONG);
    nStoredHash = *((Fnv64_t NKT_UNALIGNED *)s);
    s += sizeof(Fnv64_t);
    nHashValue = fnv_64a_buf(&dw, sizeof(dw), FNV1A_64_INIT);
    nHashValue = fnv_64a_buf(s, nCompressedSize, nHashValue);
    if (nHashValue != nStoredHash)
      goto dbload_err_fail; //hash mismatch
    //create shared memory for decompressed data
    lpDb->aDecompressedData.Attach((LPBYTE)nktMemMalloc(lpDb->nDecompressedSize));
    if (lpDb->aDecompressedData == NULL)
      goto err_nomem;
    try
    {
      i = (SIZE_T)LZ4_uncompress_unknownOutputSize((char*)s, (char*)(lpDb->aDecompressedData.Get()),
                                                   (int)nCompressedSize, (int)(lpDb->nDecompressedSize));
    }
    catch (...)
    {
      i = NKT_SIZE_T_MAX; //force fail on error
    }
    if (lpDb->nDecompressedSize != i)
      goto dbload_err_fail;
    //close file
    ::CloseHandle(hFile);
    hFile = NULL;
    //initialize internal pointers
    s = lpDb->aDecompressedData.Get();
    //read super string
    nktMemCopy(&dw, s, sizeof(dw));
    s += sizeof(dw);
    lpDb->szSuperStringW = (LPWSTR)s;
    lpDb->nSuperStringSize = (SIZE_T)dw;
    s += lpDb->nSuperStringSize;
    //read DbObjects count
    nktMemCopy(&dw, s, sizeof(dw));
    s += sizeof(dw);
    lpDb->nDbObjectsListCount = (SIZE_T)dw;
    if (lpDb->nDbObjectsListCount == 0)
    {
      hRes = NKT_DVERR_CannotLoadDatabase;
      goto dbload_err2;
    }
    lpDb->aStoredDbObjects.Attach((CNktDvDbObjectNoRef::LPSTORED_DATA*)nktMemMalloc(
                          lpDb->nDbObjectsListCount * sizeof(CNktDvDbObjectNoRef::LPSTORED_DATA)));
    lpDb->aStoredDbObjects_ChildsCount.Attach((SIZE_T*)nktMemMalloc(lpDb->nDbObjectsListCount *
                                                                    sizeof(SIZE_T)));
    lpDb->aStoredDbObjects_FirstChild.Attach((CNktDvDbObjectNoRef::LPSTORED_CHILD_ITEM*)nktMemMalloc(
                          lpDb->nDbObjectsListCount * sizeof(CNktDvDbObjectNoRef::LPSTORED_CHILD_ITEM)));
    if (lpDb->aStoredDbObjects == NULL || lpDb->aStoredDbObjects_ChildsCount == NULL ||
        lpDb->aStoredDbObjects_FirstChild == NULL)
      goto err_nomem;
    //count DbObject childs
    for (i=nCount=0; i<lpDb->nDbObjectsListCount; i++)
    {
      lpDb->aStoredDbObjects[i] = (CNktDvDbObjectNoRef::LPSTORED_DATA)s;
      s += sizeof(CNktDvDbObjectNoRef::STORED_DATA);
      //read DbObject childs count
      dw = *((DWORD NKT_UNALIGNED *)s);
      s += sizeof(dw);
      lpDb->aStoredDbObjects_ChildsCount[i] = (SIZE_T)dw;
      nCount += (SIZE_T)dw;
      lpDb->aStoredDbObjects_FirstChild[i] = (CNktDvDbObjectNoRef::LPSTORED_CHILD_ITEM)s;
      s += (SIZE_T)dw * sizeof(CNktDvDbObjectNoRef::STORED_CHILD_ITEM);
    }
    /*
    //process DbObject's
    for (i=nCount=0; i<nDbObjectsListCount; i++)
    {
      {
        aDbObjectChildsList[nCount].lpStoredChildItem = (CNktDvDbObjectNoRef::LPSTORED_CHILD_ITEM)s;
        s += sizeof(CNktDvDbObjectNoRef::STORED_CHILD_ITEM);
        aDbObjectChildsList[nCount].szNameW = szSuperStringW +
          (SIZE_T)(aDbObjectChildsList[nCount].lpStoredChildItem->nNameOffset);
        nCount++;
        dw--;
      }
    }
    //replace child object ids with pointers
    for (i=0; i<nDbObjectsListCount; i++)
    {
      nCount = lpDbObjectsList[i].nChildsCount;
      for (j=0; j<nCount; j++)
      {
        nDbObjId = lpDbObjectsList[i].lpFirstChild[j].lpStoredChildItem->nDbObjectId;
        if (nDbObjId != 0)
        {
          //search object
          lpDbObj = (CNktDvDbObjectNoRef*)bsearch_s(&nDbObjId, lpDbObjectsList, nDbObjectsListCount,
            sizeof(CNktDvDbObjectNoRef), SearchDbObjectById, NULL);
          if (lpDbObj == NULL)
            goto init_err_dbloadfail;
        }
        else
        {
          lpDbObj = NULL;
        }
        lpDbObjectsList[i].lpFirstChild[j].lpObject = lpDbObj;
      }
    }
    */
    //read DB_MODULEs count
    dw = *((DWORD NKT_UNALIGNED *)s);
    s += sizeof(dw);
    lpDb->nDbModulesListCount = (SIZE_T)dw;
    if (lpDb->nDbModulesListCount == 0)
    {
      hRes = NKT_DVERR_CannotLoadDatabase;
      goto dbload_err2;
    }
    lpDb->aStoredDbModules.Attach((CNktDvDbObjectNoRef::LPSTORED_MODULE*)nktMemMalloc(
                          lpDb->nDbModulesListCount * sizeof(CNktDvDbObjectNoRef::LPSTORED_MODULE)));
    if (lpDb->aStoredDbModules == NULL)
      goto err_nomem;
    for (i=0; i<lpDb->nDbModulesListCount; i++)
    {
      lpDb->aStoredDbModules[i] = (CNktDvDbObjectNoRef::LPSTORED_MODULE)s;
      s += sizeof(CNktDvDbObjectNoRef::STORED_MODULE);
    }
    //read DB_MODULE_FUNCTIONs count
    dw = *((DWORD NKT_UNALIGNED *)s);
    s += sizeof(dw);
    lpDb->nDbModuleFunctionsCount = (SIZE_T)dw;
    if (lpDb->nDbModuleFunctionsCount > 0)
    {
      lpDb->aStoredDbModuleFunctions.Attach((ULONG*)nktMemMalloc(lpDb->nDbModuleFunctionsCount * 2 *
                                                                 sizeof(ULONG)));
      if (lpDb->aStoredDbModuleFunctions == NULL)
        goto err_nomem;
    }
    for (i=0; i<lpDb->nDbModuleFunctionsCount; i++)
    {
      //read DB_MODULE_FUNCTION
      lpDb->aStoredDbModuleFunctions[i<<1] = *((ULONG NKT_UNALIGNED *)s);
      s += sizeof(ULONG);
      lpDb->aStoredDbModuleFunctions[(i<<1)+1] = *((ULONG NKT_UNALIGNED *)s);
      s += sizeof(ULONG);
    }
    /*
    //sort modules by name
    cDbModuleNameIndex.Attach((ULONG*)nktMemMalloc(nDbModulesListCount*sizeof(ULONG)));
    if (cDbModuleNameIndex == NULL)
      goto err_nomem;
    for (i=0; i<nDbModulesListCount; i++)
      cDbModuleNameIndex[i] = (ULONG)i;
    qsort_s(cDbModuleNameIndex.Get(), nDbModulesListCount, sizeof(ULONG), SortDbModuleByName,
      lpDbModulesList);
    //sort module functions by name
    for (i=0; i<nDbModulesListCount; i++)
    {
      qsort_s(lpDbModulesList[i].aFunctionsList.GetBuffer(), lpDbModulesList[i].aFunctionsList.GetCount(),
        sizeof(CNktDvDbObjectNoRef*), SortDbModuleFunctionsByName, NULL);
    }
    //sort objects by name
    cDbObjectNameIndex.Attach((ULONG*)nktMemMalloc(nDbObjectsListCount*sizeof(ULONG)));
    if (cDbObjectNameIndex == NULL)
      goto err_nomem;
    for (i=0; i<nDbObjectsListCount; i++)
      cDbObjectNameIndex[i] = (ULONG)i;
    qsort_s(cDbObjectNameIndex.Get(), nDbObjectsListCount, sizeof(ULONG), SortDbObjectByName,
      lpDbObjectsList);
    //sort objects by class and name
    cDbObjectClassAndNameIndex.Attach((ULONG*)nktMemMalloc(nDbObjectsListCount*sizeof(ULONG)));
    if (cDbObjectClassAndNameIndex == NULL)
      goto err_nomem;
    for (i=0; i<nDbObjectsListCount; i++)
      cDbObjectClassAndNameIndex[i] = (ULONG)i;
    qsort_s(cDbObjectClassAndNameIndex.Get(), nDbObjectsListCount, sizeof(ULONG), SortDbObjectByClassAndName,
      lpDbObjectsList);
    //get the first item of each class
    nktMemSet(&sDbObjectClassPos, 0, sizeof(sDbObjectClassPos));
    nLastClass = -1;
    for (i=0; i<nDbObjectsListCount; i++)
    {
      nCurrClass = (int)(lpDbObjectsList[cDbObjectClassAndNameIndex[i]].lpStoredData->nClass);
      if (nCurrClass != nLastClass)
      {
        sDbObjectClassPos[nCurrClass+1].nStart = (ULONG)i;
        sDbObjectClassPos[nCurrClass+1].nCount = 1;
        nLastClass = nCurrClass;
      }
      else
      {
        sDbObjectClassPos[nLastClass+1].nCount++;
      }
    }
    */
  }
  PrintAndLog(L"OK\n");
  return TRUE;
}