40 #include <QtCore/QProcess>
41 #include <QtCore/QFileInfo>
44 #include <QtDBus/QtDBus>
48 #include <kapplication.h>
49 #include <kdeversion.h>
54 #define KDED_EXENAME "kded4"
80 int sidLength = GetLengthSid(from);
81 PSID to = (PSID) malloc(sidLength);
82 CopySid(sidLength, to, from);
107 if (!ConvertSidToStringSid(sid, &s))
126 return OpenProcess( SYNCHRONIZE|PROCESS_QUERY_INFORMATION |
127 PROCESS_VM_READ | PROCESS_TERMINATE,
138 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
141 hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
142 if( hModuleSnap == INVALID_HANDLE_VALUE )
145 me32.dwSize =
sizeof( MODULEENTRY32 );
147 if( !Module32First( hModuleSnap, &me32 ) ) {
148 CloseHandle( hModuleSnap );
152 CloseHandle( hModuleSnap );
164 HANDLE hToken = NULL;
167 OpenProcessToken(hProcess, TOKEN_READ, &hToken);
171 PTOKEN_USER userStruct;
174 GetTokenInformation(hToken, TokenUser, NULL, 0, &size);
175 if( ERROR_INSUFFICIENT_BUFFER == GetLastError() )
177 userStruct =
reinterpret_cast<PTOKEN_USER
>(
new BYTE[size] );
178 GetTokenInformation(hToken, TokenUser, userStruct, size, &size);
180 sid =
copySid(userStruct->User.Sid);
182 delete [] userStruct;
201 class ProcessListEntry {
203 ProcessListEntry( HANDLE _handle,
QString _path,
int _pid, PSID _owner=0 )
206 path = p.absolutePath();
229 out <<
"(ProcessListEntry"
233 <<
"handle" << c.handle
252 ProcessList(PSID userSid=0);
261 ProcessListEntry *find(
const QString &name);
268 bool terminateProcess(
const QString &name);
282 ProcessList::ProcessList(PSID userSid)
288 ProcessList::~ProcessList()
290 foreach(
const ProcessListEntry *ple,m_processes)
294 void ProcessList::init()
299 h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
300 if (h == INVALID_HANDLE_VALUE) {
303 pe32.dwSize =
sizeof(PROCESSENTRY32);
304 if (!Process32First( h, &pe32 ))
315 if (!sid || m_userId && !EqualSid(m_userId,sid))
323 m_processes <<
new ProcessListEntry( hProcess, name, pe32.th32ProcessID, sid);
324 }
while(Process32Next( h, &pe32 ));
328 CloseToolhelp32Snapshot(h);
332 ProcessListEntry *ProcessList::find(
const QString &name)
334 ProcessListEntry *ple;
335 foreach(ple,m_processes) {
337 qDebug() <<
"negative pid!";
341 if (ple->name != name && ple->name != name +
".exe") {
347 qDebug() <<
"path of the process" << name <<
"seems to be outside of the installPath:" << ple->path <<
KStandardDirs::installPath(
"kdedir");
355 bool ProcessList::terminateProcess(
const QString &name)
357 qDebug() <<
"going to terminate process" << name;
358 ProcessListEntry *p = find(name);
360 qDebug() <<
"could not find ProcessListEntry for process name" << name;
364 bool ret = TerminateProcess(p->handle,0);
366 int i = m_processes.indexOf(p);
367 if(i != -1) m_processes.removeAt(i);
381 startedProcesses << proc;
382 _PROCESS_INFORMATION* _pid = proc->
pid();
383 int pid = _pid ? _pid->dwProcessId : 0;
385 fprintf(stderr,
"%s",proc->readAllStandardError().constData());
386 fprintf(stderr,
"%s",proc->readAllStandardOutput().constData());
390 fprintf(stderr,
"kdeinit4: Launched %s, pid = %ld\n", qPrintable(cmd),(
long) pid);
394 fprintf(stderr,
"kdeinit4: could not launch %s, exiting\n",qPrintable(cmd));
411 fprintf(stderr,
"not registered %s in dbus after %d secs\n",qPrintable(name),_timeout);
415 fprintf(stderr,
"%s is registered in dbus\n",qPrintable(name));
423 foreach(
const ProcessListEntry *ple, processList.list())
425 if (!ple->path.isEmpty() && ple->path.toLower().startsWith(installPrefix.
toLower()))
426 fprintf(stderr,
"path: %s name: %s pid: %u\n", ple->path.toLatin1().data(), ple->name.toLatin1().data(), ple->pid);
434 foreach(
const ProcessListEntry *ple, processList.list())
436 if (!ple->path.isEmpty() && ple->path.toLower().startsWith(installPrefix.
toLower()))
439 fprintf(stderr,
"terminating path: %s name: %s pid: %u\n", ple->path.toLatin1().data(), ple->name.toLatin1().data(), ple->pid);
440 processList.terminateProcess(ple->name);
450 foreach(
const QString &service, services) {
462 foreach(
const QString &service, services) {
471 fprintf(stderr,
"invalid interface of service %s\n", service.
toLatin1().
data());
486 bool launch_dbus =
true;
487 bool launch_klauncher =
true;
488 bool launch_kded =
true;
490 bool listProcesses =
false;
491 bool killProcesses =
false;
492 bool listAppsInDBus =
false;
493 bool quitAppsOverDBus =
false;
494 bool shutdown =
false;
497 char **safe_argv = (
char **) malloc(
sizeof(
char *) * argc);
498 for(
int i = 0; i < argc; i++)
500 safe_argv[i] = strcpy((
char*)malloc(strlen(argv[i])+1), argv[i]);
501 if (strcmp(safe_argv[i],
"--no-dbus") == 0)
503 if (strcmp(safe_argv[i],
"--no-klauncher") == 0)
504 launch_klauncher =
false;
505 if (strcmp(safe_argv[i],
"--no-kded") == 0)
507 if (strcmp(safe_argv[i],
"--suicide") == 0)
510 if (strcmp(safe_argv[i],
"--exit") == 0)
513 if (strcmp(safe_argv[i],
"--verbose") == 0)
515 if (strcmp(safe_argv[i],
"--version") == 0)
517 printf(
"Qt: %s\n",qVersion());
521 if (strcmp(safe_argv[i],
"--help") == 0)
523 printf(
"Usage: kdeinit4 [options]\n");
525 printf(
" --exit Terminate when kded has run\n");
527 printf(
" --help this help page\n");
528 printf(
" --list list kde processes\n");
529 printf(
" --list-dbus-apps list all applications registered in dbus\n");
530 printf(
" --quit-over-dbus quit all application registered in dbus\n");
531 printf(
" --no-dbus do not start dbus-daemon\n");
532 printf(
" --no-klauncher do not start klauncher\n");
533 printf(
" --no-kded do not start kded\n");
534 printf(
" --shutdown safe shutdown of all running kde processes\n");
535 printf(
" first over dbus, then using hard kill\n");
536 #ifdef ENABLE_SUICIDE
537 printf(
" --suicide terminate when no KDE applications are left running\n");
539 printf(
" --terminate hard kill of *all* running kde processes\n");
540 printf(
" --verbose print verbose messages\n");
541 printf(
" --version Show version information\n");
544 if (strcmp(safe_argv[i],
"--list") == 0)
545 listProcesses =
true;
546 if (strcmp(safe_argv[i],
"--shutdown") == 0)
548 if (strcmp(safe_argv[i],
"--terminate") == 0 || strcmp(safe_argv[i],
"--kill") == 0)
549 killProcesses =
true;
550 if (strcmp(safe_argv[i],
"--list-dbus-apps") == 0)
551 listAppsInDBus =
true;
552 if (strcmp(safe_argv[i],
"--quit-over-dbus") == 0)
553 quitAppsOverDBus =
true;
558 fprintf(stderr,
"current user sid: %s\n",qPrintable(
toString(currentSid)));
559 ProcessList processList(currentSid);
566 else if (killProcesses) {
570 else if (listAppsInDBus) {
574 else if (quitAppsOverDBus) {
589 if (launch_dbus && processList.find(
"dbus-daemond"))
593 pid =
launch(
"dbus-launchd.exe");
595 pid =
launch(
"dbus-launchd.bat");
596 launch_dbus = (pid == 0);
599 if (launch_dbus && !processList.find(
"dbus-daemon"))
602 pid =
launch(
"dbus-launch.exe");
604 pid =
launch(
"dbus-launch.bat");
609 if (launch_klauncher && !processList.find(
"klauncher"))
611 pid =
launch(
"klauncher");
624 for(
int i = 1; i < argc; i++)
626 if (safe_argv[i][0] ==
'+')
628 pid =
launch(safe_argv[i]+1);
630 else if (safe_argv[i][0] ==
'-')
636 pid =
launch( safe_argv[i]);
641 for(
int i = 0; i < argc; i++)
648 #ifdef ENABLE_SUICIDE
653 foreach(proc,startedProcesses) {
654 if (proc->
state() != QProcess::NotRunning)
QString fromWCharArray(const wchar_t *string, int size)
static PSID getProcessOwner(HANDLE hProcess)
return sid of specific process
QDBusConnectionInterface * interface() const
static QString getProcessName(DWORD pid)
return absolute path of process
void listAllRunningKDEProcesses(ProcessList &processList)
QString toString(PSID sid)
copy sid
QDBusConnection sessionBus()
#define KDE_VERSION_STRING
static PSID getCurrentProcessOwner()
return sid of current process owner
QDBusMessage call(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8)
QDebug operator<<(QDebug out, const ProcessListEntry &c)
QString fromUtf16(const ushort *unicode, int size)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QList< QProcess * > startedProcesses
holds process list for suicide mode
int launch(const QString &cmd)
void terminateAllRunningKDEProcesses(ProcessList &processList)
void quitApplicationsOverDBus()
static QString installPath(const char *type)
bool waitForStarted(int msecs)
bool checkIfRegisteredInDBus(const QString &name, int _timeout=10)
check dbus registration
static HANDLE getProcessHandle(int processID)
return process handle
void listAllNamedAppsInDBus()
int main(int argc, char **argv, char **envp)
QByteArray toLatin1() const
void freeSid(PSID sid)
copy sid
QDBusError lastError() const
static KComponentData * s_instance
void start(const QString &program, const QStringList &arguments, QFlags< QIODevice::OpenModeFlag > mode)
QProcess::ProcessState state() const
PSID copySid(PSID from)
copy sid