What is the correct ConnectionString to pass SQLConnect? - c

I've found a good example on the MSDN site. SQLConnect
I want to connect to an SQL server, to my database, but unfortunately, SQLConnect always returns -1, and the application freezes.
I have edited the code above:
direxec::direxec()
{
_mbscpy_s( chr_ds_name, MAX_DATA, ( const unsigned char * )"Server=mySQLServer;Database=myDatabaseName;" );
_mbscpy_s( uid, MAX_DATA, ( const unsigned char * )"testuser" );
_mbscpy_s( pwd, MAX_DATA, ( const unsigned char * )"testpassword" );
printf("\n%s",chr_ds_name);
}
void direxec::sqlconn()
{
SQLAllocEnv( &henv );
SQLAllocConnect( henv, &hdbc );
rc = SQLConnect( hdbc, chr_ds_name, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS );
// Deallocate handles, display error message, and exit.
if ( !MYSQLSUCCESS( rc ) )
{
printf( "\nFailed %d",rc );
SQLFreeConnect( henv );
SQLFreeEnv( henv );
SQLFreeConnect( hdbc );
if ( hstmt ) error_out();
exit( -1 );
}
printf("\nConnected");
rc = SQLAllocStmt( hdbc, &hstmt );
}
Using SQLDriverConnect i can connect to my database, but i want to use SQLConnect if it is possible.
Does anyone have any idea what am i doing wrong?
Thanks!

SqlConnect doesn't accept a connection string, it only accepts a Data Source Name (DSN). DSN's are configured in the ODBC Administration Tool in Administrative Tools. If you want to use a connection string then you need to use SqlDriverConnect

Related

How to get data from POST/GET method in a C program?

I want to write a simple program that takes data from forms via POST OR GET. A simple form lets say for adding two numbers.
I saw that libcurl is capable of talking with http protocol but I did not see any example related to this question.
All i saw is how to send data to webpage but not how to get it.
Thank you for your time.
Quick-n-dirty, very untested example based on another project of mine - no warranties express or implied. This assumes that the binary has properly been deployed on the Web server (for example, under the cgi-bin directory on an Apache server) and that the input form has been set up to call it properly:
<form action="http://my-url.com/cgi-bin/adder" method="get"> <!-- or method="post" -->
<label for="v1">V1:</label><input type="text" name="v1"><br>
<label for="v2">V2:</label><input type="text" name="v2"><br>
<input type="submit" name="submitbutton" value="Add">
</form>
Then your C code will look something like
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char **argv )
{
char *interface = getenv( "GATEWAY_INTERFACE" );
/**
* If interface is NULL, then we were not invoked through CGI.
* For this example we just fail silently.
*/
if ( !interface )
exit( EXIT_FAILURE );
char *method = getenv( "REQUEST_METHOD" );
/**
* If method is NULL, then we were not invoked through CGI;
* for this example we'll just fail silently
*/
if ( !method )
exit( EXIT_FAILURE );
if ( strcmp( method, "GET" ) == 0 )
{
/**
* We were invoked from a Web client with the HTTP GET method -
* input parameters will be in the QUERY_STRING environment
* variable as "param=value&param=value"
*/
char *query_string = getenv( "QUERY_STRING" );
do_stuff_with( query_string );
}
else if ( strcmp( method, "POST" ) == 0 )
{
/**
* We were invoked from a Web client with the HTTP POST method -
* input parameters will be received via standard input
*/
char query_string[SOME_SIZE];
if ( fgets( query_string, sizeof query_string, stdin ) )
{
do_stuff_with( query_string );
}
else
// handle error
}
else
{
/**
* Input method is not GET or POST, log an error and fail
*/
fputs( "Don't know how to handle this request\n", stderr );
exit( EXIT_FAILURE );
}
}
Any response back to the Web client will be written through standard output:
printf( "Content-type: text/html\r\n\r\n" );
printf( "<!DOCTYPE HTML><html><head><title>Adder result</title></head>" );
printf( "<body><p>Result of add is %d</p></body></html>", add_result );

Cannot find output of Win32 TraceLogging

I tried to replicate the short sample program for TraceLogging that Microsoft provides (see below, with minor changes). I completed the "development" (rather copy) in Visual Studio 2019. All is fine, compiles without issues, runs without issues, but nowhere on my PC I can find an updated *.etl or *.log file, nor do I find an entry somewhere in the Event Viewer.
I carefully read the Microsoft documentation and I searched the Internet for many hours, but no useful findings.
I know that I'm stupid from time to time and I must miss something obvious, but what is it? Any hints, please? Many thanks!
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
HRESULT hrRegister;
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping." );
return 1;
}
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
// TraceLoggingChannel ( WINEVENT_CHANNEL_CLASSIC_TRACE ),
// TraceLoggingLevel ( WINEVENT_LEVEL_CRITICAL ),
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
return 0;
}
First of all, running this C++ code will not generate the .log or .etl file you want, it just sends the TraceLogging event, you need to capture it in other ways to generate the etl file.
According to the MSDN,You have two steps to capture TraceLogging events:
Capture trace data with WPR
Capture TraceLogging events on Windows Phone
First create a .WPRP file, I used the same C++ code and WPRP file from MSDN as follow.
test.cpp
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>
// Define the GUID to use in TraceLoggingProviderRegister
// {3970F9cf-2c0c-4f11-b1cc-e3a1e9958833}
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
(0x3970f9cf, 0x2c0c, 0x4f11, 0xb1, 0xcc, 0xe3, 0xa1, 0xe9, 0x95, 0x88, 0x33));
void main()
{
char sampleValue[] = "Sample value";
// Register the provider
TraceLoggingRegister(g_hMyComponentProvider);
// Log an event
TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
"HelloWorldTestEvent", // Event Name that should uniquely identify your event.
TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
}
Sample WPRP file
<?xml version="1.0" encoding="utf-8"?>
<!-- TODO:
1. Find and replace "SimpleTraceLoggingProvider" with the name of your provider.
2. See TODO below to update GUID for your event provider
-->
<WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
<Profiles>
<EventCollector Id="EventCollector_SimpleTraceLoggingProvider" Name="SimpleTraceLoggingProvider">
<BufferSize Value="64" />
<Buffers Value="4" />
</EventCollector>
<!-- TODO:
1. Update Name attribute in EventProvider xml element with your provider GUID, eg: Name="3970F9cf-2c0c-4f11-b1cc-e3a1e9958833". Or
if you specify an EventSource C# provider or call TraceLoggingRegister(...) without a GUID, use star (*) before your provider
name, eg: Name="*MyEventSourceProvider" which will enable your provider appropriately.
2. This sample lists one EventProvider xml element and references it in a Profile with EventProviderId xml element.
For your component wprp, enable the required number of providers and fix the Profile xml element appropriately
-->
<EventProvider Id="EventProvider_SimpleTraceLoggingProvider" Name="*SimpleTraceLoggingProvider" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" LoggingMode="File" DetailLevel="Verbose">
<Collectors>
<EventCollectorId Value="EventCollector_SimpleTraceLoggingProvider">
<EventProviders>
<!-- TODO:
1. Fix your EventProviderId with Value same as the Id attribute on EventProvider xml element above
-->
<EventProviderId Value="EventProvider_SimpleTraceLoggingProvider" />
</EventProviders>
</EventCollectorId>
</Collectors>
</Profile>
<Profile Id="SimpleTraceLoggingProvider.Light.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="File" DetailLevel="Light" />
<Profile Id="SimpleTraceLoggingProvider.Verbose.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
<Profile Id="SimpleTraceLoggingProvider.Light.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
</Profiles>
</WindowsPerformanceRecorder>
Then start the capture using WPR from an elevated (run as Administrator) Command Prompt window.
wpr.exe -start C:\Users\songz\Desktop\test.wprp
Next you may run the application that contains your events and stop the trace capture.
wpr.exe -stop C:\Users\songz\Desktop\test.etl description
This can generate the etl file you need normally.
After completing the above operations, you should capture TraceLogging events. According to the github, you can use the following commands:
xperf -start MySession -f C:\Users\songz\Desktop\test.etl -on 3970F9cf-2c0c-4f11-b1cc-e3a1e9958833
xperf -stop MySession
Note:You should use like xperf -start MySession -f MyFile.etl -on Id
Finally you can view the corresponding information through WPA.
Zhu Song, thank you very much for your input! Your comments brought me to the right track.
Well, I did not follow strictly your text, but I found new stuff to read.
I want the controller to be part of my application as well. So, what I did is roughly the following:
Prepare EVENT_TRACE_PROPERTIES structure
TraceLogRegister
StartTrace
EnableTraceEx2 (enable)
TraceLoggingWrite
TraceLoggingUnregister
EnableTraceEx2 (disable)
ControlTrace (stop)
This resulted in an xxx.etl file that I could view with tracerpt or WPA.
Thanks again! I'm all fine now.
This is the code in detail:
#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <evntrace.h>
#include <stdio.h>
#include <strsafe.h>
#define LOGFILE_NAME TEXT(".\\Test-Test.etl")
#define LOGSESSION_NAME TEXT("Test-Test-Session")
// Define the GUID to use in TraceLoggingRegister
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER ( // defines g_hProvider
g_hProvider, // Name of the provider variable
"Test-Test", // Human-readable name of the provider
(0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) ); // Provider GUID
static const GUID ProviderGUID = { 0x5b5852d4, 0xdc24, 0x4a0f, {0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68} };
int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
TRACEHANDLE hTrace = 0;
EVENT_TRACE_PROPERTIES *petProperties;
HRESULT hrRegister;
ULONG bufferSize, ret_val;
bufferSize = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGFILE_NAME ) + sizeof ( LOGSESSION_NAME ) + 512; // The additional bytes are necessary because the path of thr LOGFILE_NAME is expanded
petProperties = (EVENT_TRACE_PROPERTIES *) malloc ( bufferSize );
if ( petProperties == NULL ) {
printf ( "Unable to allocate %d bytes for properties structure.\n", bufferSize );
return 1;
}
ZeroMemory ( petProperties, bufferSize );
petProperties->Wnode.BufferSize = bufferSize;
petProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
petProperties->Wnode.ClientContext = 1;
petProperties->Wnode.Guid = ProviderGUID;
petProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC;
petProperties->MaximumFileSize = 100; // was 1
petProperties->BufferSize = 512;
petProperties->MinimumBuffers = 8;
petProperties->MaximumBuffers = 64;
petProperties->LoggerNameOffset = sizeof ( EVENT_TRACE_PROPERTIES );
petProperties->LogFileNameOffset = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGSESSION_NAME );
StringCbCopy ( (LPWSTR) ((char *) petProperties + petProperties->LogFileNameOffset), sizeof ( LOGFILE_NAME ), LOGFILE_NAME );
hrRegister = TraceLoggingRegister ( g_hProvider );
if ( !SUCCEEDED ( hrRegister ) ) {
printf ( "TraceLoggingRegister failed. Stopping.\n" );
return 1;
}
ret_val = StartTrace ( &hTrace, LOGSESSION_NAME, petProperties );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "StartTrace failed with %i\n", ret_val );
if ( ret_val != ERROR_ALREADY_EXISTS )
return 1;
}
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(enable) failed with %i\n", ret_val );
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 1;
}
if ( TraceLoggingProviderEnabled ( g_hProvider, 0, 0 ) )
printf ( "TraceLoggingProvider enabled\n" );
else
printf ( "TraceLoggingProvider NOT enabled\n" );
TraceLoggingWrite (
g_hProvider,
"MyEvent1",
TraceLoggingString ( argv[0], "arg0" ), // field name is "arg0"
TraceLoggingInt32 ( argc ) ); // field name is implicitly "argc"
TraceLoggingUnregister ( g_hProvider );
ret_val = EnableTraceEx2 ( hTrace, &ProviderGUID, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "EnableTraceEx2(disable) failed with %i\n", ret_val );
}
ret_val = ControlTrace ( hTrace, LOGSESSION_NAME, petProperties, EVENT_TRACE_CONTROL_STOP );
if ( ret_val != ERROR_SUCCESS ) {
printf ( "ControlTrace(stop) failed with %i\n", ret_val );
}
return 0;
}
ETW is an event routing system. TraceLoggingWrite means "send the event to ETW". But if nobody is interested in your event then ETW will just ignore it.
To collect the data from TraceLoggingWrite, there needs to be an ETW session that is listening for events from you. There are many ways to start and control ETW sessions, including the StartTrace API, the AutoLogger registry key, the WPR tool, and the TRACELOG tool.
I usually prefer the TRACELOG tool. It is included with the Windows SDK, so it is installed if I have installed Visual Studio, and it will be on my path if I open a "Developer command prompt". On my computer, TRACELOG is in C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86\tracelog.exe.
To capture events from the provider you show in your source code, I would run:
TRACELOG -start MySessionName -f MySession.etl -guid #5B5852D4-DC24-4A0F-87B6-9115AE9D2768
After my code has run, I would stop the trace with:
TRACELOG -stop MySessionName
I could then use various tools to decode the trace. I usually use the TRACEFMT tool.
TRACEFMT MySession.etl

mbedtls: error on mbedtls_ctr_drbg_seed

I'm using mbedtls to run SSL server.
The function mbedtls_ctr_drbg_seed returned -34.
My code is below:
const char *pers = "ssl_server2";
mbedtls_havege_state hs;
mbedtls_ssl_session ssn;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
// One HTTPS Request Handling
memset( &ssn, 0, sizeof( mbedtls_ssl_session ) );
/*
* 4. Setup stuff
*/
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_entropy_init( &entropy );
printf( " . Setting up the RNG and SSL data...." );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, sizeof( pers ) ) ) != 0 )
{
printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
goto ExitFunction;
}
else
printf( " mbedtls_ctr_drbg_seed returned 0x%x ok\n", ret );
As #Gilles rightfully said, the error you are receiving is probably -0x34, which is MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED. This error is returned when the function mbedtls_entropy_func() fails. Please check the the entropy source you are using is strong enough, meaning you have at least one entropy source which is strong, when added with mbedtls_entropy_add_source(). You should also verify that the entropy source you are using can collect enough entropy, and exceeds the threshold set to the source.
There are other locations where mbedtls_entropy_func() might fail, therefore I suggest you check these locations as well.

How to link between MongoDB C Driver to my own programs

I'm a novice user for MongoDB using C driver, and I can't find any detail tutorial that teach how to create my first MongoDB program in C.
I've created my first program according to http://api.mongodb.org/c/current/tutorial.html
#include <stdio.h>
#include "mongo.h"
int main() {
mongo conn[1];
int status = mongo_connect( conn, "127.0.0.1", 27017 );
if( status != MONGO_OK ) {
switch ( conn->err ) {
case MONGO_CONN_SUCCESS: printf( "connection succeeded\n" ); break;
case MONGO_CONN_NO_SOCKET: printf( "no socket\n" ); return 1;
case MONGO_CONN_FAIL: printf( "connection failed\n" ); return 1;
case MONGO_CONN_NOT_MASTER: printf( "not master\n" ); return 1;
}
}
mongo_destroy( conn );
return 0;
}
However, it shows up an error that it can not find where "mongo.h" is.
Does anyone know how to compile this file so I can link it to the MongoDB C driver?
You should go to C Language Driver docs and download the latest stable code base (v0.4).
This contains mongo.h. Install it where-ever you want on your computer, and build the library. You then need to specify the -I to the location of your downloaded headers, and -L for your compiled library.

How to set request-specific data to SNMP agent using net-snmp?

I want the SNMP agent to response differently depending on the source requester, but cannot find a way to magic convey some data to make it distinguishable by the SNMP agent.
What I have tried setting is the netsnmp_session structure and netsnmp_pdu structure. because they're two parameters of snmp_send. The data field I tried to facilitate is myvoid and callback_magic.
But unfortunately on the SNMP agent, the data received are all 0, which is not what I have set on the SNMP client.
Sorry to answer myselv's question.
Finally I found the following trick to circumvent the issue:
insert a well known SNMP object(such as ifNumber) immediately after the target SNMP object to identify the specific SNMP query.
The handler function in agent should check the variable next to current variable to see whether
it's exactly the well known SNMP object ifNumber. If yes then the query comes from you, which using
NET-SNMP API to form the variable list of this query.
client code:
oid dest_OID[ MAX_OID_LEN ] = {0};
size_t dest_OID_len = COUNT_OF(dest_OID);
get_node(g_snmp_name_ifNumber, dest_OID, &dest_OID_len );
snmp_add_null_var(pdu, dest_OID, dest_OID_len);
On agent side:
int get_status(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
switch (reqinfo->mode) {
case MODE_GET:
{
bool is_sent_by_manager = false;
if( requests->requestvb->next_variable )
{
struct variable_list * v = requests->requestvb->next_variable;
oid dest_OID[ MAX_OID_LEN ] = {0};
size_t dest_OID_len = COUNT_OF(dest_OID);
get_node(g_snmp_name_ifNumber, dest_OID, &dest_OID_len );
const int nbytes = v->name_length * sizeof(v->name[0]);
if( dest_OID_len >= v->name_length
&& memcmp(dest_OID, v->name, nbytes) == 0 ) {
is_sent_by_manager = true;
}
}
if( is_sent_by_manager ) {
...
}
else {
...
}

Resources