StartService with argument - c

I am trying to convert a win32 application in to service. I use CreateService() to create it application as a service(using below code).
SC_HANDLE schService = CreateService
(
schSCManager, /* SCManager database */
pName, /* name of service */
pName, /* service name to display */
SERVICE_ALL_ACCESS, /* desired access */
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS , /*service type*/
SERVICE_AUTO_START, /* start type */
SERVICE_ERROR_NORMAL, /* error control type */
pPath, /* service's binary */
NULL, /* no load ordering group */
NULL, /* no tag identifier */
NULL, /* no dependencies */
NULL, /* LocalSystem account */
NULL
); /* no password */
I am able to start the service, if there is no argument in the actual application. If i try to start the service with argument, then its creating problem.
LPCTSTR apszSvcArgv[32] = {"start","passwd"};
int nSvcArgc = 2;
if(StartService(schService, nSvcArgc,apszSvcArgv))
{
return TRUE;
}
I tried to dump the incoming argument in the main program and its always showing the no of argument as 1.
Am i doing anything wrong?. Is it possible to pass argument like this to a win32 console application.
Please correct me if i am wrong.. Thanks in advance

you need to define the args vector as const char (or wchar), then pass the vector to StartService.
here is an example for a unicode program in VS
const wchar_t *args[] = { L"arg1", L"arg2", L"arg3", L"arg4" };
StartService(schService, 4, args);

Related

'cannot convert from...' error during callback assignations (migrated code from C)

I'm migrating some lines coded on C to C++/CLI (UI Windows Form based on .NET). One of my problems comes when I try to do this kind of assignation:
myCallbacks.cbf_data_write = this->dataWriteFunc;
In this case, dataWriteFunc is defined as:
PNIO_IOXS dataWriteFunc(PNIO_UINT32, PNIO_DEV_ADDR *, PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
And myCallbacks is declared as
PNIOD_CBF_FUNCTIONS myCallbacks;
with
typedef struct {
PNIO_UINT32 size; /* size of struct = sizeof(PNIO_CBF_FUNCTIONS) */
PNIO_CBF_DATA_WRITE cbf_data_write; /* mandatory */
PNIO_CBF_DATA_READ cbf_data_read; /* mandatory */
PNIOD_CBF_ASYNC_REC_READ cbf_async_rec_read; /* mandatory */
PNIOD_CBF_ASYNC_REC_WRITE cbf_async_rec_write; /* mandatory */
PNIOD_CBF_SYNC_ALARM_DONE cbf_sync_alarm_done; /* mandatory */
PNIOD_CBF_ASYNC_CONNECT_IND cbf_async_connect_ind; /* mandatory */
PNIOD_CBF_ASYNC_OWNERSHIP_IND cbf_async_ownership_ind; /* mandatory */
PNIOD_CBF_ASYNC_INDATA_IND cbf_async_indata_ind; /* mandatory */
PNIOD_CBF_SYNC_DISCONNECT_IND cbf_sync_disconnect_ind; /* mandatory */
PNIOD_CBF_SYNC_DATA_STATUS_IND cbf_sync_data_status_ind; /* mandatory */
PNIOD_CBF_ASYNC_PRM_END_IND cbf_async_prm_end_ind; /* mandatory */
PNIOD_CBF_SYNC_STOPPED cbf_sync_device_stopped; /* mandatory */
PNIOD_CBF_ASYNC_IRT_INIT_INPUTS cbf_async_irt_init_inputs; /* mandatory for IRT top */
PNIOD_CBF_SYNC_CP_STOP_REQ cbf_sync_cp_stop_req; /* optional */
PNIOD_CBF_SYNC_START_LED_FLASH cbf_sync_start_led_flash; /* optional */
PNIOD_CBF_SYNC_STOP_LED_FLASH cbf_sync_stop_led_flash; /* optional */
PNIOD_CBF_RESERVED
} ATTR_PACKED PNIOD_CBF_FUNCTIONS;
Also:
typedef PNIO_IOXS (*PNIO_CBF_DATA_WRITE) /* write data to IO stack (local ==> remote) */
(PNIO_UINT32 DevHndl, /* Handle for Multidevice */
PNIO_DEV_ADDR * pAddr, /* geographical address */
PNIO_UINT32 BufLen, /* length of the submodule input data */
PNIO_UINT8 * pBuffer, /* Ptr to data buffer to write to */
PNIO_IOXS Iocs); /* remote (io controller) consumer status */
So, what exactly I'm doing wrong? VS2012 gives me next error:
Error 4 error C2440: '=' : cannot convert from 'PNIO_IOXS (__thiscall CP1626::* )(PNIO_UINT32,PNIO_DEV_ADDR *,PNIO_UINT32,PNIO_UINT8 *,PNIO_IOXS)' to 'PNIO_CBF_DATA_WRITE' c:\users\hp\documents\visual studio 2012\projects\ui_cp1626\ui_cp1626\Profinet_IDevice.h 513 1 UI_CP1626
What's the correct form to associate callbacks in this case?
Thank you in advance.
You're trying to convert thiscall function (non-static class member function) to ordinary function. The problem is non-static class members take extra implicit argument, the pointer to class object aka this, so dataWriteFunc's implicit signature is:
PNIO_IOXS dataWriteFunc(CP1626 *this, PNIO_UINT32, PNIO_DEV_ADDR *,
PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
, note the 1st argument, it's implicit presence is what gives function "__thiscall" attribute. If you declare this function as
static PNIO_IOXS dataWriteFunc(PNIO_UINT32, PNIO_DEV_ADDR *,
PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
then the error will go away. Note that inside static methods this is not available.

How can I write, read and append parameter-value pairs of HTTP request to a file at Apache's server side?

I am a newbie, and I'm writing an Apache module to handle http request. I want to store all of the http requests' parameters and their values to a txt file. And, here is my code, but it didn't succeeded.
Whenever, I tried to put some parameters in the URL, the page crashed. In the error.log of apache, it shows "Segmentation Fault (core dumped)". I am aware that there is API of APR_FILE_() here instead of using standard C library. But I am so dump to understand all of pointers of those functions and the API does not have any sample usage of the apr_file_() functions, thus being stuck with file I/O. So I would be really thankful if someone could help me with the problem.
For your ready reference: I paste my code here to:
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
/* The sample content handler */
static int learning_handler(request_rec *r)
{
/* First off, we need to check if this is a call for the "example-handler" handler.
* If it is, we accept it and do our things, if not, we simply return DECLINED,
* and the server will try somewhere else.
*/
//if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);
/* Set the appropriate content type */
ap_set_content_type(r, "text/html");
/* Print out the IP address of the client connecting to us: */
ap_rprintf(r, "<h2>Hello, %s!</h2>", r->useragent_ip);
/* If we were reached through a GET or a POST request, be happy, else sad. */
if ( !strcmp(r->method, "POST") || !strcmp(r->method, "GET") ) {
ap_rputs("You used a GET or a POST method, that makes us happy!<br/>", r);
}
else {
ap_rputs("You did not use POST or GET, that makes us sad :(<br/>", r);
}
/* Lastly, if there was a query string, let's save it file */
if (r->args) {
ap_rprintf(r, "Your query string was: %s", r->args);
FILE * fp;
fp = fopen ("params_file.txt", "w+");
fprintf(fp, "%s",r->args);
fclose(fp);
}
return DECLINED;
}
static void learning_register_hooks(apr_pool_t *p)
{
ap_hook_handler(learning_handler, NULL, NULL, APR_HOOK_REALLY_FIRST);
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA learning_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* table of config file commands */
learning_register_hooks /* register hooks */
};

Change Struct module pointer

Good day all, I'd like some help to change a small section in this C program which I have licensed back in the early 90's. Some of you may be familiar with it, it's called MajorBBS and as you probably have guess it is bbs software.
In the header file majorbbs.h we have
extern
struct module { /* module interface block */
char descrp[MNMSIZ]; /* description for main menu */
int (*lonrou)(); /* user logon supplemental routine */
int (*sttrou)(); /* input routine if selected */
void (*stsrou)(); /* status-input routine if selected */
int (*injrou)(); /* "injoth" routine for this module */
int (*lofrou)(); /* user logoff supplemental routine */
void (*huprou)(); /* hangup (lost carrier) routine */
void (*mcurou)(); /* midnight cleanup routine */
void (*dlarou)(); /* delete-account routine */
void (*finrou)(); /* finish-up (sys shutdown) routine */
} **module;
Also in the majorbbs.h we have some code that defines the menu variables
extern
struct usrmnu { /* user's menuing-specific variables */
char curpag[PNMSIZ]; /* current menu page */
char parpag[PNMSIZ]; /* parent menu page */
char selchrs[MAXSEL]; /* select characters currently available */
char pages[MAXSEL][PNMSIZ]; /* pages or file names for select chars */
char optdsp[MAXSEL]; /* instructions on how to display options */
int keyreq[MAXSEL]; /* key required for each select character */
FILE *fp; /* pointer to file currently being viewed */
char mnuttl[TITLSZ]; /* menu page title */
} *mnuusr;
Then in the majorbbs.c file we have
struct module module00={ /* module interface block */
"Menuing System", /* description for main menu */
NULL, /* user logon supplemental routine */
mainu, /* input routine if selected */
musthn, /* status-input routine if selected */
NULL, /* "injoth" routine for this module */
NULL, /* user logoff supplemental routine */
loscar, /* hangup (lost carrier) routine */
midnit, /* midnight cleanup routine */
NULL, /* delete-account routine */
mjrfin /* finish-up (sys shutdown) routine */
};
What I'd like is to change the value of the descrp here which is defined as "Menuing System" to something more dynamic like the Menu the user is currently on.
From the code here I think it would be mnuusr->curpag which is where the pointer is pointing to I think.
So I'm thinking of a routine. I am by no means a programmer and I've been there many sites to look for examples of how to do such a thing. I've searched here for the last couple days (before posting this). I saw some things
that sparked a "Hey this might work" but I ended up with compiler errors (more on that in a bit)
What I did was make a routine like
char *
mydescrp
{
if (strcmp(module00.descrp,"Menuing System" ) == 0 ) {
mnuusr=mnuoff(usrnum);
return(mnuusr->mnuttl);
}
}
Then if I change the module00 call above to
struct module module00={
mydescrp, /* My change */
NULL,
mainu,
musthn,
NULL,
NULL,
loscar,
midnit,
NULL,
mjrfin
};
When I compile I get some error that says:
Initalization not fully bracketed
the list goes on from there. There are some further initialization later on in majorbbs.c and will gladly supply them if you need. I am sure one would be.
int
register_module( /* register a module for online use */
struct module *mod) /* pointer to a module block */
{
if (strlen(mod->descrp) > MNMSIZ-1) {
catastro("MODULE NAME \"%s\" TOO LONG!",mod->descrp);
}
if (mod->stsrou == NULL) {
mod->stsrou=dfsthn;
}
if (nmods == 0) {
module=(struct module **)alcmem(sizeof(struct module *));
mdstats=(struct mdstats *)alcmem(sizeof(struct mdstats));
}
else {
module=(struct module **)alcrsz(module,sizeof(struct module *)*nmods,
sizeof(struct module *)*(nmods+1));
mdstats=(struct mdstats *)alcrsz(mdstats,sizeof(struct mdstats)*nmods,
sizeof(struct mdstats)*(nmods+1));
}
module[nmods]=mod;
setbtv(mstbb);
if (qeqbtv(mod->descrp,0)) {
gcrbtv(&mdstats[nmods],0);
}
else {
setmem(&mdstats[nmods],sizeof(struct mdstats),0);
strcpy(mdstats[nmods].mdname,mod->descrp);
}
rstbtv();
return(nmods++);
}
From MENUING.C mnuoff routine
struct usrmnu *
mnuoff( /* get pointer to user's menu info */
int unum) /* user number to grab */
{
#ifdef PHARLAP
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
#ifdef ECLIPSE
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
return((struct usrmnu *)(muusrs+(unum*(long)sizeof(struct usrmnu))));
#endif
#endif
}
Is this the routine to change for some newly code? I am simply at a loss on how to go about this. If you need more code let me know.
I even went as far as asking for help from other majorbbs programmers on usenet but this software is 20 years + old so I don't think anyone uses it anymore let alone modify code anymore. I would think since it's still C someone might have an idea to help me out. I am trying to create a new revive with some small modifications. This being one of two.
Thanks for any help.
It looks like the descrp field in struct module is expecting a char[] (or a string), and you're giving it a char *() (function returning a string) instead.
Perhaps what you want to do is not call the mydescrp function in the declaration of module00, but manually perform the check in register_module:
int register_module(struct module *mod) {
if (strcmp(mod->descrp, "Menuing System") == 0) {
struct usrmnu *menu = mnuoff(usrnum);
// Copy as much of the title to the menu description as possible.
strncpy(mod->descrp, menu->mnuttl, MNMSIZ-1);
// Terminate the string in case the title was too long.
mod->descrp[MNMSIZ-1] = '\0';
}
// Rest of method.
}

redefinition of *_get_type(void) gtk+ requried method

As already said by the headline, I get a compile error I seem to be unable to fix:
error: redefinition of 'tinygecko_notebook_get_type'
note: previous definition of 'tinygecko_notebook_get_type' was here
Where error points to this line (the first of this codes snippet):
GType
tinygecko_notebook_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (TinygeckoNotebookClass), /* size of class struct */
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc)tinygecko_notebook_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (TinygeckoNotebook),
0, /* n_preallocs */
(GInstanceInitFunc)tinygecko_notebook_init /* instance_init */
};
type = g_type_register_static (GTK_TYPE_NOTEBOOK, "TinygeckoNotebook", &info, 0);
}
return type;
}
and the note line points to the type setup
G_DEFINE_TYPE (TinygeckoNotebook, tinygecko_notebook, GTK_TYPE_NOTEBOOK);
Both snippets are located within the .c file (the note line is above the error line).
Help appreciated.. I am confused. Why should that gtk+ macro redefine a function which I have to setup for own gobject based class initalizer and finalizer (if they exist) (in this case based on GtkNotebook).
G_DEFINE_TYPE is a shortcut to allow you to avoid writing the get_type function. So you don't want to use G_DEFINE_TYPE if you're implementing the get_type function by hand.
In this case I don't notice anything special in your handcoded implementation, looks like just the usual boilerplate, so you can probably just delete it and use G_DEFINE_TYPE.
There are also variants of G_DEFINE_TYPE such as G_DEFINE_TYPE_WITH_CODE, G_DEFINE_ABSTRACT_TYPE, G_DEFINE_TYPE_EXTENDED, etc. that let you deviate from pure boilerplate a bit and still avoid doing it all by hand.

Run C Code Block in Erlang

How to Run C Code Block from Erlang? ( Or Call a C function from erlang? )
This is for creating a driver
Firstly you'll need to create the C/C++ files to do it.
They will need to include
#include "erl_driver.h"
#include "ei.h"
Then you'll need to set up the driver mapping
/* mapping of the drivers functions */
static ErlDrvEntry driver_entry = {
NULL, /* init */
startup_function_name, /* startup */
shutdown_function_name, /* shutdown */
NULL, /* output */
NULL, /* ready_input */
NULL, /* ready_output */
driver_name, /* the name of the driver */
NULL, /* finish */
NULL, /* handle */
NULL, /* control */
NULL, /* timeout */
outputv_function_name, /* outputv */
NULL, /* ready_async */
NULL, /* flush */
NULL, /* call */
NULL, /* event */
ERL_DRV_EXTENDED_MARKER, /* ERL_DRV_EXTENDED_MARKER */
ERL_DRV_EXTENDED_MAJOR_VERSION, /* ERL_DRV_EXTENDED_MAJOR_VERSION */
ERL_DRV_EXTENDED_MAJOR_VERSION, /* ERL_DRV_EXTENDED_MINOR_VERSION */
ERL_DRV_FLAG_USE_PORT_LOCKING /* ERL_DRV_FLAGs */
};
DRIVER_INIT(driver_name){
return &driver_entry;
}
Note: if you are trying to run C++ code instead of C you'll need
extern "C" {
DRIVER_INIT(driver_name){
return &driver_entry;
}
}
And you will need to cast any literal string with (char *)
Then it's good to define a struct that'll contain the port information
typedef struct
{
ErlDrvPort port;
} port_data;
Lastly, you'll want to set up all the functions
static ErlDrvData startup_function_name(ErlDrvPort port, char *doc)
{
/* Plus any other start up methods you need */
port_data* d = (port_data*)driver_alloc(sizeof(port_data));
d->port = port;
return (ErlDrvData)d;
}
/* Plus any other shutdown methods you need */
static void shutdown_function_name(ErlDrvData handle)
{
driver_free((char*)handle);
}
static void outputv_function_name(ErlDrvData handle, ErlIOVec *ev)
{
port_data* d = (port_data*)handle;
char* inputstring = ev->binv[1]->orig_bytes;
ErlDrvTermData spec[] = {
ERL_DRV_ATOM, driver_mk_atom("ok"),
ERL_DRV_BUF2BINARY, inputstring, strlen(inputstring)
ERL_DRV_TUPLE, 2
};
driver_send_term(d->port,driver_caller(d->port),spec,sizeof(spec)/sizeof(spec[0]));
}
You'll want to compile this C/C++ code into a shared object and link it with the erl interface
g++ -fpic -rdynamic -shared file_name -lerl_interface -lei
Now from erlang you'll want to do a couple things:
You'll need to load the driver
erl_ddll:load_driver("./location/of/driver", driver_name).
Then you'll open a port to the driver
Port = open_port({spawn, driver_name}, [binary]).
And lastly you can sent data to the port
port_command(Port, <<"String to Echo Back"),
receive
{ok, String} -> io:format("Received ~p back from the driver")
end.
The newest approach would consider NIFs http://www.erlang.org/doc/man/erl_nif.html (be careful, it can crash VM). Regular way to do it involves linked in drivers (google up the link, because anti-spam holds it)

Resources