예제 #1
0
int
kdba_removebp(kdb_bp_t *bp)
{
	/*
	 * For hardware breakpoints, remove it from the active register,
	 * for software breakpoints, restore the instruction stream.
	 */
	if (KDB_DEBUG(BP)) {
		kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
	}
	if (bp->bp_installed) {
		if (bp->bp_hardtype) {
			if (KDB_DEBUG(BP)) {
				kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
					   bp->bp_hard->bph_reg, bp->bp_addr);
			}
			kdba_removedbreg(bp);
		} else {
			if (KDB_DEBUG(BP))
				kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
					   bp->bp_inst, bp->bp_addr);
			if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
				return(1);
		}
		bp->bp_installed = 0;
	}
	return(0);
}
예제 #2
0
int
kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
{
	if (KDB_DEBUG(AR))
		kdb_printf("kdbgetsymval: symname=%s, symtab=%p\n", symname, symtab);
	memset(symtab, 0, sizeof(*symtab));

	if ((symtab->sym_start = kallsyms_lookup_name(symname))) {
		if (KDB_DEBUG(AR))
			kdb_printf("kdbgetsymval: returns 1, symtab->sym_start=0x%lx\n", symtab->sym_start);
		return 1;
	}
	if (KDB_DEBUG(AR))
		kdb_printf("kdbgetsymval: returns 0\n");
	return 0;
}
예제 #3
0
static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp)
{
	int ret;
	/*
	 * Install the breakpoint, if it is not already installed.
	 */

	if (KDB_DEBUG(BP))
		kdb_printf("%s: bp_installed %d\n",
			   __func__, bp->bp_installed);
	if (!KDB_STATE(SSBPT))
		bp->bp_delay = 0;
	if (bp->bp_installed)
		return 1;
	if (bp->bp_delay || (bp->bp_delayed && KDB_STATE(DOING_SS))) {
		if (KDB_DEBUG(BP))
			kdb_printf("%s: delayed bp\n", __func__);
		kdb_handle_bp(regs, bp);
		return 0;
	}
	if (!bp->bp_type)
		ret = dbg_set_sw_break(bp->bp_addr);
	else
		ret = arch_kgdb_ops.set_hw_breakpoint(bp->bp_addr,
			 bp->bph_length,
			 bp->bp_type);
	if (ret == 0) {
		bp->bp_installed = 1;
	} else {
		kdb_printf("%s: failed to set breakpoint at 0x%lx\n",
			   __func__, bp->bp_addr);
#ifdef CONFIG_DEBUG_RODATA
		if (!bp->bp_type) {
			kdb_printf("Software breakpoints are unavailable.\n"
				   "  Change the kernel CONFIG_DEBUG_RODATA=n\n"
				   "  OR use hw breaks: help bph\n");
		}
#endif
		return 1;
	}
	return 0;
}
예제 #4
0
파일: kdb.cpp 프로젝트: ZTMC/kitserver
// parses a RRGGBB string into array of bytes
// that specify Konami color: r,0,g,0,b,0.
void MakeKonamiColor(char* str, BYTE* buf)
{
	ZeroMemory(buf, 6);
	if (lstrlen(str) != 6) return;
	int num = 0;
	if (sscanf(str,"%x",&num)!=1) return;
	buf[0] = (BYTE)((num >> 16) & 0xff);
	buf[2] = (BYTE)((num >> 8) & 0xff);
	buf[4] = (BYTE)(num & 0xff);
	KDB_DEBUG(klog, (klog, "Konami color: %x,%x,%x,%x,%x,%x\n",
				buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]));
}
예제 #5
0
int
kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
{
	/*
	 * Install the breakpoint, if it is not already installed.
	 */

	if (KDB_DEBUG(BP)) {
		kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
	}
	if (!KDB_STATE(SSBPT))
		bp->bp_delay = 0;
	if (!bp->bp_installed) {
		if (bp->bp_hardtype) {
			kdba_installdbreg(bp);
			bp->bp_installed = 1;
			if (KDB_DEBUG(BP)) {
				kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
					   bp->bp_hard->bph_reg, bp->bp_addr);
			}
		} else if (bp->bp_delay) {
			if (KDB_DEBUG(BP))
				kdb_printf("kdba_installbp delayed bp\n");
			kdba_handle_bp(regs, bp);
		} else {
			if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
			    kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
				kdb_printf("kdba_installbp failed to set software breakpoint at " kdb_bfd_vma_fmt "\n", bp->bp_addr);
				return(1);
			}
			bp->bp_installed = 1;
			if (KDB_DEBUG(BP))
				kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
					   IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
		}
	}
	return(0);
}
예제 #6
0
파일: kdb_bp.c 프로젝트: AlexShiLucky/linux
/*
 * kdb_bp_remove
 *
 *	Remove kdb_breakpoints upon entry to the kernel debugger.
 *
 * Parameters:
 *	None.
 * Outputs:
 *	None.
 * Returns:
 *	None.
 * Locking:
 *	None.
 * Remarks:
 */
void kdb_bp_remove(void)
{
	int i;

	for (i = KDB_MAXBPT - 1; i >= 0; i--) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("%s: bp %d bp_enabled %d\n",
				   __func__, i, bp->bp_enabled);
		}
		if (bp->bp_enabled)
			_kdb_bp_remove(bp);
	}
}
예제 #7
0
파일: kdb_bp.c 프로젝트: AlexShiLucky/linux
/*
 * kdb_bp_install
 *
 *	Install kdb_breakpoints prior to returning from the
 *	kernel debugger.  This allows the kdb_breakpoints to be set
 *	upon functions that are used internally by kdb, such as
 *	printk().  This function is only called once per kdb session.
 */
void kdb_bp_install(struct pt_regs *regs)
{
	int i;

	for (i = 0; i < KDB_MAXBPT; i++) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("%s: bp %d bp_enabled %d\n",
				   __func__, i, bp->bp_enabled);
		}
		if (bp->bp_enabled)
			_kdb_bp_install(regs, bp);
	}
}
예제 #8
0
파일: kdb_bp.c 프로젝트: AlexShiLucky/linux
static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
{
	if (KDB_DEBUG(BP))
		kdb_printf("regs->ip = 0x%lx\n", instruction_pointer(regs));

	/*
	 * Setup single step
	 */
	kdb_setsinglestep(regs);

	/*
	 * Reset delay attribute
	 */
	bp->bp_delay = 0;
	bp->bp_delayed = 1;
}
예제 #9
0
void
kdb_bp_remove_global(void)
{
	int i;

	for(i=KDB_MAXBPT-1; i>=0; i--) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("kdb_bp_remove_global bp %d bp_enabled %d bp_global %d\n",
				i, bp->bp_enabled, bp->bp_global);
		}
		if (kdb_is_installable_global_bp(bp))
			kdba_removebp(bp);
	}
}
예제 #10
0
void
kdb_bp_install_global(struct pt_regs *regs)
{
	int i;

	for(i=0; i<KDB_MAXBPT; i++) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("kdb_bp_install_global bp %d bp_enabled %d bp_global %d\n",
				i, bp->bp_enabled, bp->bp_global);
		}
		/* HW BP local or global are installed in kdb_bp_install_local*/
		if (kdb_is_installable_global_bp(bp))
			kdba_installbp(regs, bp);
	}
}
예제 #11
0
void
kdb_bp_install_local(struct pt_regs *regs)
{
	int i;

	for(i=0; i<KDB_MAXBPT; i++) {
		kdb_bp_t *bp = &kdb_breakpoints[i];

		if (KDB_DEBUG(BP)) {
			kdb_printf("kdb_bp_install_local bp %d bp_enabled %d bp_global %d cpu %d bp_cpu %d\n",
				i, bp->bp_enabled, bp->bp_global,
				smp_processor_id(), bp->bp_cpu);
		}
		if (kdb_is_installable_local_bp(bp))
			kdba_installbp(regs, bp);
	}
}
예제 #12
0
kdb_dbtrap_t
kdba_bp_trap(struct pt_regs *regs, int error_unused)
{
	int i;
	kdb_dbtrap_t rv;
	kdb_bp_t *bp;

	if (KDB_NULL_REGS(regs))
		return KDB_DB_NOBPT;
	/*
	 * Determine which breakpoint was encountered.
	 */
	if (KDB_DEBUG(BP))
		kdb_printf("kdba_bp_trap: rip=0x%lx (not adjusted) "
			   "eflags=0x%lx ef=0x%p rsp=0x%lx\n",
			   regs->rip, regs->eflags, regs, regs->rsp);

	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */

	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
		if (bp->bp_free)
			continue;
		if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
			continue;
		 if ((void *)bp->bp_addr == (void *)(regs->rip - bp->bp_adjust)) {
			/* Hit this breakpoint.  */
			regs->rip -= bp->bp_adjust;
			kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
				  i, regs->rip);
			kdb_id1(regs->rip);
			rv = KDB_DB_BPT;
			bp->bp_delay = 1;
			/* SSBPT is set when the kernel debugger must single
			 * step a task in order to re-establish an instruction
			 * breakpoint which uses the instruction replacement
			 * mechanism.  It is cleared by any action that removes
			 * the need to single-step the breakpoint.
			 */
			KDB_STATE_SET(SSBPT);
			break;
		}
	}

	return rv;
}
예제 #13
0
static void
kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
{

	if (KDB_NULL_REGS(regs))
		return;

	if (KDB_DEBUG(BP))
		kdb_printf("regs->rip = 0x%lx\n", regs->rip);

	/*
	 * Setup single step
	 */
	kdba_setsinglestep(regs);

	/*
	 * Reset delay attribute
	 */
	bp->bp_delay = 0;
	bp->bp_delayed = 1;
}
예제 #14
0
/*
 * kdbnearsym -	Return the name of the symbol with the nearest address
 *	less than 'addr'.
 *
 * Parameters:
 *	addr	Address to check for symbol near
 *	symtab  Structure to receive results
 * Returns:
 *	0	No sections contain this address, symtab zero filled
 *	1	Address mapped to module/symbol/section, data in symtab
 * Remarks:
 *	2.6 kallsyms has a "feature" where it unpacks the name into a
 *	string.  If that string is reused before the caller expects it
 *	then the caller sees its string change without warning.  To
 *	avoid cluttering up the main kdb code with lots of kdb_strdup,
 *	tests and kfree calls, kdbnearsym maintains an LRU list of the
 *	last few unique strings.  The list is sized large enough to
 *	hold active strings, no kdb caller of kdbnearsym makes more
 *	than ~20 later calls before using a saved value.
 */
int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
{
	int ret = 0;
	unsigned long symbolsize = 0;
	unsigned long offset = 0;
#define knt1_size 128		/* must be >= kallsyms table size */
	char *knt1 = NULL;

	if (KDB_DEBUG(AR))
		kdb_printf("kdbnearsym: addr=0x%lx, symtab=%p\n", addr, symtab);
	memset(symtab, 0, sizeof(*symtab));

	if (addr < 4096)
		goto out;
	knt1 = debug_kmalloc(knt1_size, GFP_ATOMIC);
	if (!knt1) {
		kdb_printf("kdbnearsym: addr=0x%lx cannot kmalloc knt1\n",
			   addr);
		goto out;
	}
	symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset,
				(char **)(&symtab->mod_name), knt1);
	if (offset > 8*1024*1024) {
		symtab->sym_name = NULL;
		addr = offset = symbolsize = 0;
	}
	symtab->sym_start = addr - offset;
	symtab->sym_end = symtab->sym_start + symbolsize;
	ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0';

	if (ret) {
		int i;
		/* Another 2.6 kallsyms "feature".  Sometimes the sym_name is
		 * set but the buffer passed into kallsyms_lookup is not used,
		 * so it contains garbage.  The caller has to work out which
		 * buffer needs to be saved.
		 *
		 * What was Rusty smoking when he wrote that code?
		 */
		if (symtab->sym_name != knt1) {
			strncpy(knt1, symtab->sym_name, knt1_size);
			knt1[knt1_size-1] = '\0';
		}
		for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) {
			if (kdb_name_table[i] &&
			    strcmp(kdb_name_table[i], knt1) == 0)
				break;
		}
		if (i >= ARRAY_SIZE(kdb_name_table)) {
			debug_kfree(kdb_name_table[0]);
			memcpy(kdb_name_table, kdb_name_table+1,
			       sizeof(kdb_name_table[0]) *
			       (ARRAY_SIZE(kdb_name_table)-1));
		} else {
			debug_kfree(knt1);
			knt1 = kdb_name_table[i];
			memcpy(kdb_name_table+i, kdb_name_table+i+1,
			       sizeof(kdb_name_table[0]) *
			       (ARRAY_SIZE(kdb_name_table)-i-1));
		}
		i = ARRAY_SIZE(kdb_name_table) - 1;
		kdb_name_table[i] = knt1;
		symtab->sym_name = kdb_name_table[i];
		knt1 = NULL;
	}

	if (symtab->mod_name == NULL)
		symtab->mod_name = "kernel";
	if (KDB_DEBUG(AR))
		kdb_printf("kdbnearsym: returns %d symtab->sym_start=0x%lx, "
		   "symtab->mod_name=%p, symtab->sym_name=%p (%s)\n", ret,
		   symtab->sym_start, symtab->mod_name, symtab->sym_name,
		   symtab->sym_name);

out:
	debug_kfree(knt1);
	return ret;
}
예제 #15
0
kdb_dbtrap_t
kdba_db_trap(struct pt_regs *regs, int error_unused)
{
	kdb_machreg_t  dr6;
	kdb_machreg_t  dr7;
	int rw, reg;
	int i;
	kdb_dbtrap_t rv = KDB_DB_BPT;
	kdb_bp_t *bp;

	if (KDB_NULL_REGS(regs))
		return KDB_DB_NOBPT;

	dr6 = kdba_getdr6();
	dr7 = kdba_getdr7();

	if (KDB_DEBUG(BP))
		kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
	if (dr6 & DR6_BS) {
		if (KDB_STATE(SSBPT)) {
			if (KDB_DEBUG(BP))
				kdb_printf("ssbpt\n");
			KDB_STATE_CLEAR(SSBPT);
			for(i=0,bp=kdb_breakpoints;
			    i < KDB_MAXBPT;
			    i++, bp++) {
				if (KDB_DEBUG(BP))
					kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
						   bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
				if (!bp->bp_enabled)
					continue;
				if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
					continue;
				if (KDB_DEBUG(BP))
					kdb_printf("bp for this cpu\n");
				if (bp->bp_delayed) {
					bp->bp_delayed = 0;
					if (KDB_DEBUG(BP))
						kdb_printf("kdba_installbp\n");
					kdba_installbp(regs, bp);
					if (!KDB_STATE(DOING_SS)) {
						regs->eflags &= ~EF_TF;
						return(KDB_DB_SSBPT);
					}
					break;
				}
			}
			if (i == KDB_MAXBPT) {
				kdb_printf("kdb: Unable to find delayed breakpoint\n");
			}
			if (!KDB_STATE(DOING_SS)) {
				regs->eflags &= ~EF_TF;
				return(KDB_DB_NOBPT);
			}
			/* FALLTHROUGH */
		}

		/*
		 * KDB_STATE_DOING_SS is set when the kernel debugger is using
		 * the processor trap flag to single-step a processor.  If a
		 * single step trap occurs and this flag is clear, the SS trap
		 * will be ignored by KDB and the kernel will be allowed to deal
		 * with it as necessary (e.g. for ptrace).
		 */
		if (!KDB_STATE(DOING_SS))
			goto unknown;

		/* single step */
		rv = KDB_DB_SS;		/* Indicate single step */
		if (KDB_STATE(DOING_SSB)) {
			unsigned char instruction[2];

			kdb_id1(regs->rip);
			if (kdb_getarea(instruction, regs->rip) ||
			    (instruction[0]&0xf0) == 0xe0 ||	/* short disp jumps */
			    (instruction[0]&0xf0) == 0x70 ||	/* Misc. jumps */
			    instruction[0]        == 0xc2 ||	/* ret */
			    instruction[0]        == 0x9a ||	/* call */
			    (instruction[0]&0xf8) == 0xc8 ||	/* enter, leave, iret, int, */
			    ((instruction[0]      == 0x0f) &&
			     ((instruction[1]&0xf0)== 0x80))
			   ) {
				/*
				 * End the ssb command here.
				 */
				KDB_STATE_CLEAR(DOING_SSB);
				KDB_STATE_CLEAR(DOING_SS);
			} else {
				rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
			}
		} else {
			/*
			 * Print current insn
			 */
			kdb_printf("SS trap at ");
			kdb_symbol_print(regs->rip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
			kdb_id1(regs->rip);
			KDB_STATE_CLEAR(DOING_SS);
		}

		if (rv != KDB_DB_SSB)
			regs->eflags &= ~EF_TF;
	}

	if (dr6 & DR6_B0) {
		rw = DR7_RW0(dr7);
		reg = 0;
		goto handle;
	}

	if (dr6 & DR6_B1) {
		rw = DR7_RW1(dr7);
		reg = 1;
		goto handle;
	}

	if (dr6 & DR6_B2) {
		rw = DR7_RW2(dr7);
		reg = 2;
		goto handle;
	}

	if (dr6 & DR6_B3) {
		rw = DR7_RW3(dr7);
		reg = 3;
		goto handle;
	}

	if (rv > 0)
		goto handled;

	goto unknown;	/* dismiss */

handle:
	/*
	 * Set Resume Flag
	 */
	regs->eflags |= EF_RF;

	/*
	 * Determine which breakpoint was encountered.
	 */
	for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
		if (!(bp->bp_free)
		 && (bp->bp_global || bp->bp_cpu == smp_processor_id())
		 && (bp->bp_hard)
		 && (bp->bp_hard->bph_reg == reg)) {
			/*
			 * Hit this breakpoint.
			 */
			kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
				  kdba_rwtypes[rw],
				  i, bp->bp_addr);
			/*
			 * For an instruction breakpoint, disassemble
			 * the current instruction.
			 */
			if (rw == 0) {
				kdb_id1(regs->rip);
			}

			goto handled;
		}
	}

unknown:
	regs->eflags |= EF_RF;	/* Supress further faults */
	rv = KDB_DB_NOBPT;	/* Cause kdb() to return */

handled:

	/*
	 * Clear the pending exceptions.
	 */
	kdba_putdr6(0);

	return rv;
}
예제 #16
0
int
kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
{
	int		nextarg = *nextargp;
	int		diag;
	kdbhard_bp_t 	*bph = &bp->bp_template;

	bph->bph_mode = 0;		/* Default to instruction breakpoint */
	bph->bph_length = 0;		/* Length must be zero for insn bp */
	if ((argc + 1) != nextarg) {
		if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
			bph->bph_mode = 3;
		} else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
			bph->bph_mode = 1;
		} else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
			bph->bph_mode = 2;
		} else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
			bph->bph_mode = 0;
		} else {
			return KDB_ARGCOUNT;
		}

		bph->bph_length = 3;	/* Default to 4 byte */

		nextarg++;

		if ((argc + 1) != nextarg) {
			unsigned long len;

			diag = kdbgetularg((char *)argv[nextarg],
					   &len);
			if (diag)
				return diag;


			if ((len > 4) || (len == 3))
				return KDB_BADLENGTH;

			bph->bph_length = len;
			bph->bph_length--; /* Normalize for debug register */
			nextarg++;
		}

		if ((argc + 1) != nextarg)
			return KDB_ARGCOUNT;

		/*
		 * Indicate to architecture independent level that
		 * a hardware register assignment is required to enable
		 * this breakpoint.
		 */

		bph->bph_free = 0;
	} else {
		if (KDB_DEBUG(BP))
			kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
		if (bp->bp_forcehw) {
			/*
			 * We are forced to use a hardware register for this
			 * breakpoint because either the bph or bpha
			 * commands were used to establish this breakpoint.
			 */
			bph->bph_free = 0;
		} else {
			/*
			 * Indicate to architecture dependent level that
			 * the instruction replacement breakpoint technique
			 * should be used for this breakpoint.
			 */
			bph->bph_free = 1;
			bp->bp_adjust = 1;	/* software, int 3 is one byte */
		}
	}

	if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
		kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
		return KDB_BADADDR;
	}

	*nextargp = nextarg;
	return 0;
}
예제 #17
0
파일: kdb.cpp 프로젝트: ZTMC/kitserver
KitEntry* buildKitList(char* dir, int kitType)
{
	WIN32_FIND_DATA fData;
	char pattern[4096];
	ZeroMemory(pattern, 4096);

	KitEntry* list = NULL;
	KitEntry* p = NULL;
	HANDLE heap = GetProcessHeap();

	lstrcpy(pattern, dir); 
	if (kitType == PLAYERS) lstrcat(pattern, "KDB\\players\\uni???*.bin");
	else if (kitType == GOALKEEPERS) lstrcat(pattern, "KDB\\goalkeepers\\uni???*.bin");

	KDB_DEBUG(klog, (klog, "pattern = {%s}\n", pattern));

	HANDLE hff = FindFirstFile(pattern, &fData);
	if (hff == INVALID_HANDLE_VALUE) 
	{
		// none found.
		return NULL;
	}

	while(true)
	{
		// build new list element
		Kit* kit = (Kit*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(Kit));
		if (kit != NULL)
		{
			ZeroMemory(kit->fileName, 255);
			lstrcpy(kit->fileName, fData.cFileName);
			ZeroMemory(kit->shirtBackNumber, 6);
			ZeroMemory(kit->shirtBackName, 6);
			ZeroMemory(kit->shirtFrontNumber, 6);
			ZeroMemory(kit->shortsNumber, 6);
			kit->collar = 2;
			kit->attDefined = 0;

			p = (KitEntry*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(KitEntry));
			if (p != NULL)
			{
				// insert new element
				p->kit = kit;
				p->next = list;
				list = p;

				KDB_DEBUG(klog, (klog, "list->kit->fileName = {%s}\n", list->kit->fileName));
			}
			else 
			{
				HeapFree(heap, 0, kit);
			}
		}

		// proceed to next file
		if (!FindNextFile(hff, &fData)) break;
	}

	FindClose(hff);
	return list;
}
예제 #18
0
파일: kdb.cpp 프로젝트: ZTMC/kitserver
KDB* kdbLoad(char* dir)
{
	KDB_DEBUG_OPEN(klog, dir);
	KDB_DEBUG(klog, (klog, "Loading KDB...\n"));

	// initialize an empty database
	KDB* kdb = (KDB*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KDB));
	if (kdb == NULL) { fclose(klog); return NULL; }
	kdb->playerCount = kdb->goalkeeperCount = 0;
	ZeroMemory(kdb->players, sizeof(KitEntry*) * 256);
	ZeroMemory(kdb->goalkeepers, sizeof(KitEntry*) * 256);

	// get list of player kits
	KitEntry* kits = buildKitList(dir, PLAYERS);

	// traverse the list and place the kits into the database
	KitEntry* p = kits;
	KitEntry* q = NULL;
	while (p != NULL)
	{
		q = p->next;
		KDB_DEBUG(klog, (klog, "p->kit->filename = %s\n", p->kit->fileName));

		int n = getTeamNumber(p->kit->fileName);
		if (n >= 0 && n <= 255) 
		{
			p->next = kdb->players[n];
			kdb->players[n] = p;
			kdb->playerCount += 1;

			KDB_DEBUG(klog, (klog, "[%03d] : %s\n", n, p->kit->fileName));
		}
		p = q;
	}

	// get list of goalkeeper kits
	kits = buildKitList(dir, GOALKEEPERS);

	// traverse the list and place the kits into the database
	p = kits;
	q = NULL;
	while (p != NULL)
	{
		q = p->next;
		KDB_DEBUG(klog, (klog, "p->kit->filename = %s\n", p->kit->fileName));

		int n = getTeamNumber(p->kit->fileName);
		if (n >= 0 && n <= 255) 
		{
			p->next = kdb->goalkeepers[n];
			kdb->goalkeepers[n] = p;
			kdb->goalkeeperCount += 1;

			KDB_DEBUG(klog, (klog, "[%03d] : %s\n", n, p->kit->fileName));
		}
		p = q;
	}

	// read the attributes from attrib.cfg file
	int currTeam = -1;
	Kit* currUni = NULL;
	Ball* currBall = NULL;

	// default is players 
	// (for compatibility with attrib.cfg files from older kitservers
	int group = GROUP_PLAYERS; 

	char buf[4096];
	ZeroMemory(buf, 4096);
	lstrcpy(buf, dir); lstrcat(buf, "KDB\\attrib.cfg");

	FILE* att = fopen(buf, "rt");
	if (att != NULL)
	{
		// go line by line
		while (!feof(att))
		{
			ZeroMemory(buf, 4096);
			fgets(buf, 4096, att);
			if (lstrlen(buf) == 0) break;

			// strip off comments
			char* comm = strstr(buf, "#");
			if (comm != NULL) comm[0] = '\0';

			// look for start of the section
			char* start = strstr(buf, "[");
			if (start != NULL) 
			{
				char* end = strstr(start+1,"]");
				if (end != NULL)
				{
					// new section
					char name[255];
					ZeroMemory(name, 255);
					lstrcpy(name, start+1);
					name[end-start-1] = '\0';

					KDB_DEBUG(klog, (klog, "section: {%s}\n", name));

					// check if we changed groups
					if (lstrcmpi(name, "Players")==0) 
					{ 
						group = GROUP_PLAYERS; 
						currTeam = -1; currUni = NULL;
						continue; 
					}
					else if (lstrcmpi(name, "Goalkeepers")==0) 
					{ 
						group = GROUP_GOALKEEPERS; 
						currTeam = -1; currUni = NULL;
						continue; 
					}
					else if (lstrcmpi(name, "Balls")==0) 
					{ 
						group = GROUP_BALLS; 
						currTeam = -1; currUni = NULL;
						continue; 
					}

					if (group == GROUP_PLAYERS)
					{
						// this has to be a kit file
						start[7] = '\0';
						if (sscanf(start+4,"%d",&currTeam)==1)
						{
							KDB_DEBUG(klog, (klog, "looking up uniform for team: {%d}\n", currTeam));
							// lookup name in KDB
							KitEntry* p = kdb->players[currTeam];
							while (p != NULL)
							{
								if (lstrcmp(p->kit->fileName, name)==0)
								{
									currUni = p->kit;
									break;
								}
								p = p->next;
							}
							if (p == NULL) {
								currTeam = -1; // didn't find such uniform in KDB
								currUni = NULL;
							}
						}
					}

					else if (group == GROUP_GOALKEEPERS)
					{
						// this has to be a kit file
						start[7] = '\0';
						if (sscanf(start+4,"%d",&currTeam)==1)
						{
							KDB_DEBUG(klog, (klog, "looking up uniform for team: {%d}\n", currTeam));
							// lookup name in KDB
							KitEntry* p = kdb->goalkeepers[currTeam];
							while (p != NULL)
							{
								if (lstrcmp(p->kit->fileName, name)==0)
								{
									currUni = p->kit;
									break;
								}
								p = p->next;
							}
							if (p == NULL) {
								currTeam = -1; // didn't find such uniform in KDB
								currUni = NULL;
							}
						}
					}

					else if (group == GROUP_BALLS)
					{
						// this has to be a ball file
						KDB_DEBUG(klog, (klog, "New ball key: {%s}\n", name));
						currBall = (Ball*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Ball));
						if (currBall != NULL)
						{
							lstrcpy(currBall->texFileName, name);

							// insert into list of balls
							BallEntry* be = (BallEntry*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BallEntry));
							if (be != NULL)
							{
								be->ball = currBall;
								be->next = kdb->balls;
								kdb->balls = be;
							}
						}
					}
				} // end if (end ...
			}
			
			// otherwise try to read attributes
			else 
			{
				if (currTeam != -1 && (group == GROUP_PLAYERS || group == GROUP_GOALKEEPERS))
				{
					char key[80]; ZeroMemory(key, 80);
					char value[80]; ZeroMemory(value, 80);

					if (sscanf(buf,"%s = %s",key,value)==2)
					{
						KDB_DEBUG(klog, (klog, "key: {%s} has value: {%s}\n", key, value));

						BYTE color[6];
						if (lstrcmp(key, "shirt.backNumber")==0)
						{
							MakeKonamiColor(value, color);
							memcpy(currUni->shirtBackNumber, color, 6);
							currUni->attDefined |= SHIRT_BACK_NUMBER;
						}
						else if (lstrcmp(key, "shirt.backName")==0)
						{
							MakeKonamiColor(value, color);
							memcpy(currUni->shirtBackName, color, 6);
							currUni->attDefined |= SHIRT_BACK_NAME;
						}
						else if (lstrcmp(key, "shirt.frontNumber")==0)
						{
							MakeKonamiColor(value, color);
							memcpy(currUni->shirtFrontNumber, color, 6);
							currUni->attDefined |= SHIRT_FRONT_NUMBER;
						}
						else if (lstrcmp(key, "shorts.number")==0)
						{
							MakeKonamiColor(value, color);
							memcpy(currUni->shortsNumber, color, 6);
							currUni->attDefined |= SHORTS_NUMBER;
						}
						else if (lstrcmp(key, "collar")==0)
						{
							currUni->collar = (lstrcmp(value,"yes")==0) ? 0 : 2;
							currUni->attDefined |= COLLAR;
						}
					}
				}
				else 
				{
					if (group == GROUP_BALLS && currBall != NULL)
					{
						char key[255]; ZeroMemory(key, 255);

						sscanf(buf, "%s", key);
						if (lstrcmp(key, "ball.name")==0)
						{
							char* startQuote = strstr(buf, "\"");
							if (startQuote == NULL) continue;
							char* endQuote = strstr(startQuote + 1, "\"");
							if (endQuote == NULL) continue;

							memcpy(currBall->name, 
									startQuote + 1, endQuote - startQuote - 1);

							KDB_DEBUG(klog, (klog, "key: {%s} has value: {%s}\n", key, currBall->name));
						}
						else if (lstrcmp(key, "ball.model")==0)
						{
							char* startQuote = strstr(buf, "\"");
							if (startQuote == NULL) continue;
							char* endQuote = strstr(startQuote + 1, "\"");
							if (endQuote == NULL) continue;

							memcpy(currBall->mdlFileName, 
									startQuote + 1, endQuote - startQuote - 1);

							KDB_DEBUG(klog, (klog, "key: {%s} has value: {%s}\n", key, currBall->mdlFileName));
						}
					}
				}
			} // end else

		}
		fclose(att);
	}
	KDB_DEBUG(klog, (klog, "attributes read.\n"));

	// cycle the uniform lists, adding a "dummy" kits
	// and a "dummy" ball as well
	HANDLE heap = GetProcessHeap();
	for (int i=0; i<256; i++)
	{
		// PLAYERS
		KitEntry* p = kdb->players[i];
		if (p != NULL)
		{
			KitEntry* dummy = (KitEntry*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(KitEntry));
			dummy->kit = (Kit*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(Kit));
			dummy->kit->fileName[0] = 'x';
			dummy->kit->attDefined = 0;
			dummy->next = NULL;

			// append dummy kit at the end
			while (p->next != NULL) p = p->next;
			p->next = dummy;
			dummy->next = kdb->players[i];
		}

		// GOALKEEPERS
		p = kdb->goalkeepers[i];
		if (p != NULL)
		{
			KitEntry* dummy = (KitEntry*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(KitEntry));
			dummy->kit = (Kit*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(Kit));
			dummy->kit->fileName[0] = 'x';
			dummy->kit->attDefined = 0;
			dummy->next = NULL;

			// append dummy kit at the end
			while (p->next != NULL) p = p->next;
			p->next = dummy;
			dummy->next = kdb->goalkeepers[i];
		}
	}
	KDB_DEBUG(klog, (klog, "PL and GK cycled.\n"));

	// insert the dummy ball at the front
	if (kdb->balls != NULL)
	{
		BallEntry* dummy = (BallEntry*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(BallEntry));
		dummy->ball = (Ball*)HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(Ball));
		dummy->ball->texFileName[0] = 'x';
		dummy->next = kdb->balls;
		kdb->balls = dummy;
	}

	// now reverse the list
	BallEntry* reversed = NULL;
	BallEntry* bp = kdb->balls;
	while (bp != NULL)
	{
		BallEntry* bq = bp->next;
		bp->next = reversed;
		reversed = bp;
		bp = bq;
	}
	kdb->balls = reversed;
	KDB_DEBUG(klog, (klog, "balls reversed.\n"));

	// now cycle it
	bp = kdb->balls;
	if (bp != NULL)
	{
		while (bp->next != NULL) bp = bp->next;
		bp->next = kdb->balls;
	}
	KDB_DEBUG(klog, (klog, "balls cycled.\n"));

	KDB_DEBUG(klog, (klog, "KDB loaded.\n"));
	KDB_DEBUG_CLOSE(klog);
	return kdb;
}