Exemple #1
0
/**
 * Allow install using regsvr32
 */
HRESULT WINAPI
DllRegisterServer(void)
{
	TCHAR fn[MAX_PATH], full_fn[MAX_PATH];
	LPTSTR name;
	WORD len_out;
	DWORD cnt;
	char *desc = NULL;
	BOOL b_res;

	if (!GetModuleFileName(hinstFreeTDS, fn, TDS_VECTOR_SIZE(fn)))
		return SELFREG_E_CLASS;
	if (!GetFullPathName(fn, TDS_VECTOR_SIZE(full_fn), full_fn, &name) || !name || full_fn == name)
		return SELFREG_E_CLASS;

	if (asprintf(&desc, "FreeTDS%c"
		"APILevel=2%c"
		"ConnectFunctions=YYN%c"
		"DriverODBCVer=03.00%c"
		"FileUsage=0%c"
		"SQLLevel=2%c"
		"Setup=%s%c"
		"Driver=%s%c",
		0, 0, 0, 0, 0, 0,
		name, 0, name, 0
		) < 0)
		return SELFREG_E_CLASS;
	name[-1] = 0;

	b_res = SQLInstallDriverEx(desc, full_fn, fn, TDS_VECTOR_SIZE(fn), &len_out, ODBC_INSTALL_COMPLETE, &cnt);
	free(desc);
	if (!b_res)
		return SELFREG_E_CLASS;
	return S_OK;
}
Exemple #2
0
int
tds_parse_boolean(const char *value, int default_value)
{
	int p;

	for (p = 0; p < TDS_VECTOR_SIZE(boolean_values); ++p) {
		if (!strcasecmp(value, boolean_values[p].value))
			return boolean_values[p].to_return;
	}
	return default_value;
}
Exemple #3
0
int
tds_config_boolean(const char *value)
{
	int p;

	for (p = 0; p < TDS_VECTOR_SIZE(boolean_values); ++p) {
		if (!strcasecmp(value, boolean_values[p].value))
			return boolean_values[p].to_return;
	}
	tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED boolean value: '%s'. Treating as 'no'.\n", value);
	return 0;
}
Exemple #4
0
int
tds_config_boolean(const char *option, const char *value, TDSLOGIN *login)
{
    int p;

    for (p = 0; p < TDS_VECTOR_SIZE(boolean_values); ++p) {
        if (!strcasecmp(value, boolean_values[p].value))
            return boolean_values[p].to_return;
    }
    tdsdump_log(TDS_DBG_ERROR, "UNRECOGNIZED option value '%s' for boolean setting '%s'!\n",
                value, option);
    login->valid_configuration = 0;
    return 0;
}
Exemple #5
0
/**
 * Set state of TDS connection, with logging and checking.
 * \param tds	  state information for the socket and the TDS protocol
 * \param state	  the new state of the connection, cf. TDS_STATE.
 * \return 	  the new state, which might not be \a state.
 */
TDS_STATE
tds_set_state(TDSSOCKET * tds, TDS_STATE state)
{
	const TDS_STATE prior_state = tds->state;
	static const char state_names[][10] = {
		"IDLE",
	        "QUERYING",
	        "PENDING",
	        "READING",
	        "DEAD"
	};
	assert(state < TDS_VECTOR_SIZE(state_names));
	assert(tds->state < TDS_VECTOR_SIZE(state_names));
	
	if (state == tds->state)
		return state;
	
	switch(state) {
		/* transition to READING are valid only from PENDING */
	case TDS_PENDING:
		if (tds->state != TDS_READING && tds->state != TDS_QUERYING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			return tds->state;
		}
		tds->state = state;
		break;
	case TDS_READING:
		if (tds->state != TDS_PENDING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			return tds->state;
		}
		tds->state = state;
		break;
	case TDS_IDLE:
		if (tds->state == TDS_DEAD && TDS_IS_SOCKET_INVALID(tds_get_s(tds))) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			return tds->state;
		}
	case TDS_DEAD:
		tds->state = state;
		break;
	case TDS_QUERYING:
		CHECK_TDS_EXTRA(tds);

		if (tds->state == TDS_DEAD) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSEWRIT, 0);
			break;
		} else if (tds->state != TDS_IDLE) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSERPND, 0);
			break;
		}

		/* TODO check this code, copied from tds_submit_prepare */
		tds_free_all_results(tds);
		tds->rows_affected = TDS_NO_COUNT;
		tds_release_cursor(tds, tds->cur_cursor);
		tds->cur_cursor = NULL;
		tds->internal_sp_called = 0;

		tds->state = state;
		break;
	default:
		assert(0);
		break;
	}
	
	tdsdump_log(TDS_DBG_ERROR, "Changed query state from %s to %s\n", state_names[prior_state], state_names[state]);
	CHECK_TDS_EXTRA(tds);
	
	return tds->state; 
}
char *
tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s)
{
	const unsigned char *number;

	unsigned int packet[sizeof(numeric->array) / 2];
	unsigned int *pnum, *packet_start;
	unsigned int *const packet_end = packet + TDS_VECTOR_SIZE(packet);

	unsigned int packet10k[(MAXPRECISION + 3) / 4];
	unsigned int *p;

	int num_bytes;
	unsigned int remainder, n, i, m;

	/* a bit of debug */
#if ENABLE_EXTRA_CHECKS
	memset(packet, 0x55, sizeof(packet));
	memset(packet10k, 0x55, sizeof(packet10k));
#endif

	/* set sign */
	if (numeric->array[0] == 1)
		*s++ = '-';

	/* put number in a 16bit array */
	number = numeric->array;
	num_bytes = tds_numeric_bytes_per_prec[numeric->precision];

	n = num_bytes - 1;
	pnum = packet_end;
	for (; n > 1; n -= 2)
		*--pnum = number[n - 1] * 256 + number[n];
	if (n == 1)
		*--pnum = number[n];
	while (!*pnum) {
		++pnum;
		if (pnum == packet_end) {
			*s++ = '0';
			if (numeric->scale) {
				*s++ = '.';
				i = numeric->scale;
				do {
					*s++ = '0';
				} while (--i);
			}
			*s++ = 0;
			return s;
		}
	}
	packet_start = pnum;

	/* transform 2^16 base number in 10^4 base number */
	for (p = packet10k + TDS_VECTOR_SIZE(packet10k); packet_start != packet_end;) {
		pnum = packet_start;
		n = *pnum;
		remainder = n % 10000u;
		if (!(*pnum++ = (n / 10000u)))
			packet_start = pnum;
		for (; pnum != packet_end; ++pnum) {
			n = remainder * (256u * 256u) + *pnum;
			remainder = n % 10000u;
			*pnum = n / 10000u;
		}
		*--p = remainder;
	}

	/* transform to 10 base number and output */
	i = 4 * ((packet10k + TDS_VECTOR_SIZE(packet10k)) - p);	/* current digit */
	/* skip leading zeroes */
	n = 1000;
	remainder = *p;
	while (remainder < n)
		n /= 10, --i;
	if (i <= numeric->scale) {
		*s++ = '0';
		*s++ = '.';
		m = i;
		while (m < numeric->scale)
			*s++ = '0', ++m;
	}
	for (;;) {
		*s++ = (remainder / n) + '0';
		--i;
		remainder %= n;
		n /= 10;
		if (!n) {
			n = 1000;
			if (++p == packet10k + TDS_VECTOR_SIZE(packet10k))
				break;
			remainder = *p;
		}
		if (i == numeric->scale)
			*s++ = '.';
	}
	*s++ = 0;

	return s;
}
Exemple #7
0
	 * precision can't be 0 but using a value > 0 assure no
	 * core if for some bug it's 0...
	 */
	1, 
	2,  2,  3,  3,  4,  4,  4,  5,  5,
	6,  6,  6,  7,  7,  8,  8,  9,  9,  9,
	10, 10, 11, 11, 11, 12, 12, 13, 13, 14,
	14, 14, 15, 15, 16, 16, 16, 17, 17, 18,
	18, 19, 19, 19, 20, 20, 21, 21, 21, 22,
	22, 23, 23, 24, 24, 24, 25, 25, 26, 26,
	26, 27, 27, 28, 28, 28, 29, 29, 30, 30,
	31, 31, 31, 32, 32, 33, 33, 33
};

TDS_COMPILE_CHECK(maxprecision,
	MAXPRECISION < TDS_VECTOR_SIZE(tds_numeric_bytes_per_prec) );

/*
 * money is a special case of numeric really...that why its here
 */
char *
tds_money_to_string(const TDS_MONEY * money, char *s)
{
	int frac;
	TDS_INT8 mymoney;
	TDS_UINT8 n;
	char *p;

	/* sometimes money it's only 4-byte aligned so always compute 64-bit */
	mymoney = (((TDS_INT8) money->tdsoldmoney.mnyhigh) << 32) | money->tdsoldmoney.mnylow;
Exemple #8
0
/**
 * Set state of TDS connection, with logging and checking.
 * \param tds	  state information for the socket and the TDS protocol
 * \param state	  the new state of the connection, cf. TDS_STATE.
 * \return 	  the new state, which might not be \a state.
 */
TDS_STATE
tds_set_state(TDSSOCKET * tds, TDS_STATE state)
{
	TDS_STATE prior_state;
	static const char state_names[][8] = {
		"IDLE",
	        "WRITING",
	        "SENDING",
	        "PENDING",
	        "READING",
	        "DEAD"
	};
	assert(state < TDS_VECTOR_SIZE(state_names));
	assert(tds->state < TDS_VECTOR_SIZE(state_names));

	prior_state = tds->state;
	if (state == prior_state)
		return state;

	switch(state) {
	case TDS_PENDING:
		if (prior_state == TDS_READING || prior_state == TDS_WRITING) {
			tds->state = TDS_PENDING;
			tds_mutex_unlock(&tds->wire_mtx);
			break;
		}
		tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
						state_names[prior_state], state_names[state]);
		break;
	case TDS_READING:
		/* transition to READING are valid only from PENDING */
		if (tds_mutex_trylock(&tds->wire_mtx))
			return tds->state;
		if (tds->state != TDS_PENDING) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			break;
		}
		tds->state = state;
		break;
	case TDS_SENDING:
		if (prior_state != TDS_READING && prior_state != TDS_WRITING) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			break;
		}
		if (tds->state == TDS_READING) {
			/* TODO check this code, copied from tds_submit_prepare */
			tds_free_all_results(tds);
			tds->rows_affected = TDS_NO_COUNT;
			tds_release_cursor(&tds->cur_cursor);
			tds_release_cur_dyn(tds);
			tds->current_op = TDS_OP_NONE;
		}

		tds_mutex_unlock(&tds->wire_mtx);
		tds->state = state;
		break;
	case TDS_IDLE:
		if (prior_state == TDS_DEAD && TDS_IS_SOCKET_INVALID(tds_get_s(tds))) {
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n",
				state_names[prior_state], state_names[state]);
			break;
		}
	case TDS_DEAD:
		if (prior_state == TDS_READING || prior_state == TDS_WRITING)
			tds_mutex_unlock(&tds->wire_mtx);
		tds->state = state;
		break;
	case TDS_WRITING:
		CHECK_TDS_EXTRA(tds);

		if (tds_mutex_trylock(&tds->wire_mtx))
			return tds->state;

		if (tds->state == TDS_DEAD) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSEWRIT, 0);
			break;
		} else if (tds->state != TDS_IDLE && tds->state != TDS_SENDING) {
			tds_mutex_unlock(&tds->wire_mtx);
			tdsdump_log(TDS_DBG_ERROR, "logic error: cannot change query state from %s to %s\n", 
							state_names[prior_state], state_names[state]);
			tdserror(tds_get_ctx(tds), tds, TDSERPND, 0);
			break;
		}

		if (tds->state == TDS_IDLE) {
			/* TODO check this code, copied from tds_submit_prepare */
			tds_free_all_results(tds);
			tds->rows_affected = TDS_NO_COUNT;
			tds_release_cursor(&tds->cur_cursor);
			tds_release_cur_dyn(tds);
			tds->current_op = TDS_OP_NONE;
		}

		tds->state = state;
		break;
	default:
		assert(0);
		break;
	}

	state = tds->state;

	tdsdump_log(TDS_DBG_ERROR, "Changed query state from %s to %s\n", state_names[prior_state], state_names[state]);
	CHECK_TDS_EXTRA(tds);

	return state;
}