I am working on a simple driver, currently I am at the very beginning with a simple callback installed with PsSetCreateThreadNotifyRoutine. In the callback function I call DbgPrint to print out the pid and process name:
DbgPrint("%.4x %s", ProcessId, GetProcessNameFromPid(ProcessId)); // dbgview shows nothing
If I remove the %s specificer it suddenly works:
DbgPrint("%.4x", ProcessId); // works
I am using dbgview to view debug messages, on Windows 7 x64. I have in the registry Print Debug Filter set to 0xF
Also I verified with windbg that returned pointer by GetProcessNameFromPid() is indeed points to the process name.
LPSTR GetProcessNameFromPid(HANDLE Pid)
{
PEPROCESS Process;
if (PsLookupProcessByProcessId(Pid, &Process) != STATUS_SUCCESS)
return "????";
return (LPSTR)PsGetProcessImageFileName(Process);
}
Related
I have an imbedded Tcl interpreter and want to redirect its stderr and stdout to a console widget in the application.
Using a chan push command for stderr seems to work (not much testing yet), like explained here:
TCL: Redirect output of proc to a file
I could have a file with the required tcl namespace definition, etc, and do a Tcl_Eval to source that script after creating an interp with Tcl_CreateInterp.
Can I do the same thing using Tcl C library calls instead of running the Tcl commands via a Tcl_Eval?
To implement a channel transformation in C, you first have to define a Tcl_ChannelType structure. Such a structure specifies a name for the transformation and pointers to functions for the different operations that may be done on a channel. Next, you implement the functions that perform those operations. The most important ones are inputProc and outputProc. You also have to implement a watchProc. The pointers for other operations can be set to NULL, if you don't need them.
For your example it may look something like:
static const Tcl_ChannelType colorChannelType = {
"color",
TCL_CHANNEL_VERSION_5,
NULL,
ColorTransformInput,
ColorTransformOutput,
NULL, /* seekProc */
NULL, /* setOptionProc */
NULL, /* getOptionProc */
ColorTransformWatch,
NULL, /* getHandleProc */
NULL, /* close2Proc */
NULL, /* blockModeProc */
NULL, /* flushProc */
NULL, /* handlerProc */
NULL, /* wideSeekProc */
NULL,
NULL
};
Then, when you want to push the transformation onto a channel:
chan = Tcl_StackChannel(interp, &colorChannelType, clientData,
Tcl_GetChannelMode(channel), channel);
For a complete example from the Tcl sources, see tclZlib.c
Not really an answer to my question, but maybe it will help someone to see what works by using a Tcl_Eval to show the tcl code that does the redirection.
proc redir_stdout {whichChan args} {
switch -- [lindex $args 0] {
initialize {
return {initialize write finalize}
}
write {
::HT_puts $whichChan [lindex $args 2]
}
finalize {
}
}
}
chan push stderr [list redir_stdout 1]
chan push stdout [list redir_stdout 2]
Both the chan push commands use the same proc, but pass an different identifier (1 or 2) to indicate whether stdout or stderr was the originator of the output.
HT_puts is an extension provided by the C code:
Tcl_CreateObjCommand(interp,"HT_puts",putsCmd,(ClientData) NULL,NULL);
int TclInterp::putsCmd(ClientData ,Tcl_Interp *,int objcnt,Tcl_Obj * CONST *objv)
{
if (objcnt != 3)
return TCL_ERROR;
int length;
int whichChan;
Tcl_GetIntFromObj(interp,objv[1],&whichChan);
//qDebug() << "Channel is $whichChan";
QString out =Tcl_GetStringFromObj(objv[2],&length);
QColor textColor;
if (whichChan==1)
textColor = QColor(Qt::red);
else
textColor = QColor(Qt::white);
console->putData(out.toUtf8(),textColor);
//qDebug() << out;
return TCL_OK;
}
Text forwarded from stderr gets colored red and text from stdout gets colored white.
And, as I mentioned above, each subsequent command that gets executed via Tcl_Eval needs to have the Tcl_Eval return value processed something like this:
if (rtn != TCL_OK)
{
QString output = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
console->putData(output.toUtf8(),QColor(Qt::red));
//qDebug("Failed Tcl_Eval: %d \n%s\n", rtn,
}
To get what's normally printed to stderr by tclsh on a TCL_ERROR into the console (instead of the app's stderr).
I was planning to do the equivalent in C to eliminate the need to run Tcl code in the interpreter for the redirect. But, really there's no need for that.
The Tcl_Eval that does the redirection is done right after doing the Tcl_CreateInterp. Any subsequent Tcl_Evals using that interp will have stdout and stderr redirected to my application's console.
Besides, I'm having trouble understanding how to use Tcl_StackChannel and can't find an example I can follow.
Honestly, can't say that I completely understand the Tcl implementation. I made some assumptions on what gets passed to the proc used in the "chan push" command based on the referenced thread.
It looks like the proc is called with the list specified in the chan push command AND an args list. The first element of the args list is a name like "write" or "initialize". The third element looks like the string to be printed.
Still trying to find a definition of what's passed without having to dig into something like namespace ensemble.
So, it's likely that this Tcl code isn't the best implementation but it's working so far (with limited testing).
I'm trying to write a program to shift the key of a midi file. Basically, I just need to shift every note event by a given amount and live the rest unchanged. I found it easy to use MIKMIDI to read, parse, modify and write back the stream.
Unfortunately, I have a problem that I'm unable to solve. I've a loop in which I select the note events and add/subtract the desired shift value, but when I append the event in the output track I get a message from the MIKMIDI library:
"Warning: attempted to insert a NULL event".
The code I wrote is the following:
for event in inputTrack.events {
if event.eventType == .midiNoteMessage {
var tmpData = event.data
if (event.data[0] != 9) { // skip percussion channel
tmpData[1] = event.data[1] - shift
}
let outEvent = MIKMIDIEvent(timeStamp: event.timeStamp, midiEventType: .midiNoteMessage, data: tmpData)!
outputSeq.tracks[i].events.append(outEvent)
}
else {
outSeq.tracks[i].events.append(event)
}
}
BTW, the code works perfectly (the midi file is plays as expected), it is just that it takes minutes to execute in debugging mode due to the infinite sequence of warning messages printed in the debug screen.
Thanks!
This question already has an answer here:
How, in Perl 5, can I get the pid of the process who sent me a signal?
(1 answer)
Closed 6 years ago.
local $SIG{INT} = \&handle_sigint;
sub handle_sigint {
print "received sigint\n";
}
in handle_sigint i would like to print who (pid/process name) sent the signal.
Is there a way to capture that info in perl?
i can do this in C and this is ported to python as a module
I am looking for equivalent in perl
static void csignal_handler(int signum, siginfo_t *siginfo, void *context) {
char *interrupt_msg[150];
if (siginfo->si_pid != 0) {
struct passwd *pwd = getpwuid(siginfo->si_uid);
if (pwd != 0) {
sprintf(interrupt_msg, "Received signal '%d' from process '%d' (%s) of user '%s'\n",
signum, siginfo->si_pid, get_process_name_by_pid(siginfo->si_pid), pwd->pw_name);
} else {
sprintf(interrupt_msg, "Received signal '%d' from process '%d' (%s) of user '%d'\n",
signum, siginfo->si_pid, get_process_name_by_pid(siginfo->si_pid), siginfo->si_uid);
}
printf("%s", interrupt_msg);
}
if (raise_interrupt) {
PyGILState_STATE gstate = PyGILState_Ensure();
PyErr_SetString(PyExc_KeyboardInterrupt, interrupt_msg );
PyGILState_Release(gstate);
} else {
interrupted = 1;
}
}
You can combine SA_SIGINFO and signalfd to find out the pid of process which sent the signal.
See: How can I tell in Linux which process sent my process a signal
All that our process gets from the kernel is the signal, which I believe is just an integer. Also, a signal may come from all kinds of events, not just another process. The list given by, for example, man 7 signal reveals all kinds of possible sources.
All that is not in the signal.
Update to the question edit
The added C code doesn't exactly use the signal itself, but queries a whole lot more. A similar approach in Perl is discussed in this post, unearthed by Syck in a comment.
As for digging that information up from siginfo_t, the POSIX::SigAction is meant to expose those fields, but it apparently doesn't. It may be that you are best off writing your own extension, or try with Inline::C as suggested by sobrique
I am running a Perl script to control two other scripts. The user of the main program can call the two secondary scripts with the following line.
do 'Task_A.pl';
The script then runs Task_A.pl but I would like to find a way of then exiting Task_A.pl and return to the main program. If possible I would like to return to the function where I last called the secondary script. I am not sure as to what this is called but I appreciate any input for a possible solution.
This is the whole main program, not much to it at the moment.
my $selecion;
#Looping variables.
my $program_loop = 1;
while ($program_loop == 1)
{
print "Please choose one of the programs listed in the menu.\n";
#Program menu where the user chooses from the presented options.
print "[1] - Script A.\n";
print "[2] - Script B.\n";
print "[3] - Exit program.\n";
my $user_input = <>;
if ($user_input == 1) # <-- Scrip_A.pl
{
do 'Task_A.pl';
}
elsif ($user_input == 2) # <-- Scrip_B.pl
{
do 'Task_B.pl';
}
elsif ($user_input == 3) # <-- Exit Program
{
#The user can choose to exit from the menu.
print "The program will now exit.\n";
exit;
}
}
do does not start another process. If that's what you want, use "system()".
If you want do, then it's probably best to just put everything into a function in the file to be evaluated and call the function at the end of the file.
Use "return" to leave the function and return to next instruction after do.
I'm trying to write a very simple program to replace an existing executable. It should munge its arguments slightly and exec the original program with the new arguments. It's supposed to be invoked automatically and silently by a third-party library.
It runs fine, but it pops up a console window to show the output of the invoked program. I need that console window to not be there. I do not care about the program's output.
My original attempt was set up as a console application, so I thought I could fix this by writing a new Windows GUI app that did the same thing. But it still pops up the console. I assume that the original command is marked as a console application, and so Windows automatically gives it a console window to run in. I also tried replacing my original call to _exec() with a call to system(), just in case. No help.
Does anyone know how I can make this console window go away?
Here's my code:
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
char* lpCmdLine,
int nCmdShow)
{
char *argString, *executable;
// argString and executable are retrieved here
std::vector< std::string > newArgs;
// newArgs gets set up with the intended arguments here
char const ** newArgsP = new char const*[newArgs.size() + 1];
for (unsigned int i = 0; i < newArgs.size(); ++i)
{
newArgsP[i] = newArgs[i].c_str();
}
newArgsP[newArgs.size()] = NULL;
int rv = _execv(executable, newArgsP);
if (rv)
{
return -1;
}
}
Use the CreateProcess function instead of execve. For the dwCreationFlags paramter pass the CREATE_NO_WINDOW flag. You will also need to pass the command line as a string as well.
e.g.
STARTUPINFO startInfo = {0};
PROCESS_INFORMATION procInfo;
TCHAR cmdline[] = _T("\"path\\to\\app.exe\" \"arg1\" \"arg2\"");
startInfo.cb = sizeof(startInfo);
if(CreateProcess(_T("path\\to\\app.exe"), cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startInfo, &procInfo))
{
CloseHandle(procInfo.hProcess);
CloseHandle(procInfo.hThread);
}
Aha, I think I found the answer on MSDN, at least if I'm prepared to use .NET. (I don't think I'm really supposed to, but I'll ignore that for now.)
System::String^ command = gcnew System::String(executable);
System::Diagnostics::Process^ myProcess = gcnew Process;
myProcess->StartInfor->FileName = command;
myProcess->StartInfo->UseShellExecute = false; //1
myProcess->StartInfo->CreateNowindow = true; //2
myProcess->Start();
It's those two lines marked //1 and //2 that are important. Both need to be present.
I really don't understand what's going on here, but it seems to work.
You need to create a non-console application (i.e. a Windows GUI app). If all this app does is some processing of files or whatever, you won't need to have a WinMain, register any windows or have a message loop - just write your code as for a console app. Of course, you won't be able to use printf et al. And when you come to execute it, use the exec() family of functions, not system().