• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • kernel
kkernel_win.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (C) 2004 Jarosław Staniek <staniek@kde.org>
4 Copyright (C) 2007 Christian Ehrlicher <ch.ehrlicher@gmx.de>
5 Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
6 Copyright (C) 2008-2009 Ralf Habacker <ralf.habacker@freenet.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License version 2 as published by the Free Software Foundation.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "kkernel_win.h"
24
25#include <config.h>
26#include <QtCore/QBool>
27#include <QtCore/QTextCodec>
28
29#ifdef Q_OS_WIN
30
31#include "kglobal.h"
32#include <klocale.h>
33
34#include <QtCore/QDir>
35#include <QtCore/QString>
36#include <QtCore/QLibrary>
37
38#include <windows.h>
39#include <shellapi.h>
40#include <process.h>
41
42// console related includes
43#include <stdio.h>
44#include <fcntl.h>
45#include <io.h>
46#include <iostream>
47#include <fstream>
48#ifndef _USE_OLD_IOSTREAMS
49using namespace std;
50#endif
51
52#if defined(__MINGW32__)
53# define WIN32_CAST_CHAR (const WCHAR*)
54#else
55# define WIN32_CAST_CHAR (LPCWSTR)
56#endif
57
58#ifndef _WIN32_WCE
59static HINSTANCE kdecoreDllInstance = NULL;
60#else
61static HANDLE kdecoreDllInstance = NULL;
62#endif
63#ifdef KDELIBS_STATIC_LIBS
64static bool kde4prefixInitialized = false;
65#endif
66static wchar_t kde4prefixUtf16[MAX_PATH + 2] = L"";
67
68static QString *kde4Prefix = NULL;
69
70void initKde4prefixUtf16()
71{
72 //the path is C:\some\path\kde4\bin\kdecore.dll
73#ifndef _WIN32_WCE
74 GetModuleFileNameW(kdecoreDllInstance, kde4prefixUtf16, MAX_PATH + 1);
75#else
76 GetModuleFileNameW((HMODULE)kdecoreDllInstance, kde4prefixUtf16, MAX_PATH + 1);
77#endif
78 int bs1 = 0, bs2 = 0;
79
80 //we convert \ to / and remove \bin\kdecore.dll from the string
81 int pos;
82 for (pos = 0; pos < MAX_PATH + 1 && kde4prefixUtf16[pos] != 0; ++pos) {
83 if (kde4prefixUtf16[pos] == '\\') {
84 bs1 = bs2;
85 bs2 = pos;
86 kde4prefixUtf16[pos] = '/';
87 }
88 }
89 Q_ASSERT(bs1);
90 Q_ASSERT(pos < MAX_PATH + 1);
91 kde4prefixUtf16[bs1] = '/';
92 kde4prefixUtf16[bs1+1] = 0;
93}
94
95// can't use QCoreApplication::applicationDirPath() because sometimes we
96// don't have an instantiated QCoreApplication
97QString getKde4Prefix()
98{
99#ifdef _WIN32_WCE
100 if (kde4prefixInitialized)
101 return QString::fromUtf16((ushort*) kde4prefixUtf16);
102
103 QDir kde4prefixDir(QString::fromUtf16((ushort*) STATIC_INSTALL_PATH));
104 if (kde4prefixDir.exists()){
105 wcscpy(kde4prefixUtf16, STATIC_INSTALL_PATH);
106 kde4prefixUtf16[wcslen(kde4prefixUtf16)] = 0;
107 kde4prefixInitialized = true;
108 return QString::fromUtf16((ushort*) kde4prefixUtf16);
109 } else {
110 bool ok;
111 QString retval = getWin32RegistryValue(HKEY_LOCAL_MACHINE, "Software\\kde", "KDEDIRS", &ok);
112 if (!ok){
113 return QString();
114 } else {
115 retval = QDir::fromNativeSeparators(retval);
116 wcscpy(kde4prefixUtf16, retval.utf16());
117 kde4prefixUtf16[wcslen(kde4prefixUtf16)] = 0;
118 kde4prefixInitialized = true;
119 return retval;
120 }
121 }
122#else
123 // we can get called after DLL_PROCESS_DETACH!
124 return kde4Prefix ? *kde4Prefix : QString::fromUtf16((ushort*) kde4prefixUtf16);
125#endif
126}
127
128#ifndef KDELIBS_STATIC_LIBS
133extern "C"
134#ifndef _WIN32_WCE
135BOOL WINAPI DllMain ( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved)
136#else
137BOOL WINAPI DllMain ( HANDLE hinstDLL,DWORD fdwReason,LPVOID lpReserved)
138#endif
139{
140 switch ( fdwReason ) {
141 case DLL_PROCESS_ATTACH:
142 kdecoreDllInstance = hinstDLL;
143 initKde4prefixUtf16();
144 kde4Prefix = new QString( QString::fromUtf16((ushort*) kde4prefixUtf16) );
145 break;
146 case DLL_PROCESS_DETACH:
147 /* msdn:
148 When handling DLL_PROCESS_DETACH, a DLL should free resources such
149 as heap memory only if the DLL is being unloaded dynamically (the
150 lpReserved parameter is NULL). If the process is terminating (the
151 lpvReserved parameter is non-NULL), all threads in the process except
152 the current thread either have exited already or have been explicitly
153 terminated by a call to the ExitProcess function, which might leave
154 some process resources such as heaps in an inconsistent state. In this
155 case, it is not safe for the DLL to clean up the resources. Instead,
156 the DLL should allow the operating system to reclaim the memory.
157 */
158 if( lpReserved == NULL )
159 delete kde4Prefix;
160 kde4Prefix = 0;
161 break;
162 default:
163 break;
164 }
165 return true;
166}
167
168#endif
169
180QString getWin32RegistryValue ( HKEY key, const QString& subKey, const QString& item, bool *ok )
181{
182#define FAILURE \
183 { if (ok) \
184 *ok = false; \
185 return QString(); }
186
187 if ( subKey.isEmpty() )
188 FAILURE;
189 HKEY hKey;
190 TCHAR *lszValue;
191 DWORD dwType=REG_SZ;
192 DWORD dwSize;
193
194 if ( ERROR_SUCCESS!=RegOpenKeyExW ( key, WIN32_CAST_CHAR subKey.utf16(), 0, KEY_READ, &hKey ) )
195 FAILURE;
196
197 if ( ERROR_SUCCESS!=RegQueryValueExW ( hKey, WIN32_CAST_CHAR item.utf16(), NULL, NULL, NULL, &dwSize ) )
198 FAILURE;
199
200 lszValue = new TCHAR[dwSize];
201
202 if ( ERROR_SUCCESS!=RegQueryValueExW ( hKey, WIN32_CAST_CHAR item.utf16(), NULL, &dwType, ( LPBYTE ) lszValue, &dwSize ) ) {
203 delete [] lszValue;
204 FAILURE;
205 }
206 RegCloseKey ( hKey );
207
208 QString res = QString::fromUtf16 ( ( const ushort* ) lszValue );
209 delete [] lszValue;
210
211 if (ok)
212 *ok = true;
213
214 return res;
215}
216
217
218bool showWin32FilePropertyDialog ( const QString& fileName )
219{
220 QString path_ = QDir::convertSeparators ( QFileInfo ( fileName ).absoluteFilePath() );
221
222#ifndef _WIN32_WCE
223 SHELLEXECUTEINFOW execInfo;
224#else
225 SHELLEXECUTEINFO execInfo;
226#endif
227 memset ( &execInfo,0,sizeof ( execInfo ) );
228 execInfo.cbSize = sizeof ( execInfo );
229#ifndef _WIN32_WCE
230 execInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
231#else
232 execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
233#endif
234 const QString verb ( QLatin1String ( "properties" ) );
235 execInfo.lpVerb = WIN32_CAST_CHAR verb.utf16();
236 execInfo.lpFile = WIN32_CAST_CHAR path_.utf16();
237#ifndef _WIN32_WCE
238 return ShellExecuteExW ( &execInfo );
239#else
240 return ShellExecuteEx ( &execInfo );
241 //There is no native file property dialog in wince
242 // return false;
243#endif
244}
245
246// note: QLocale().name().left(2).toLatin1() returns the same
247
248QByteArray getWin32LocaleName()
249{
250 bool ok;
251 QString localeNumber = getWin32RegistryValue ( HKEY_CURRENT_USER,
252 QLatin1String("Control Panel\\International"),
253 QLatin1String("Locale"), &ok );
254 if ( !ok )
255 return QByteArray();
256 QString localeName = getWin32RegistryValue ( HKEY_LOCAL_MACHINE,
257 QLatin1String("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout\\DosKeybCodes"),
258 localeNumber, &ok );
259 if ( !ok )
260 return QByteArray();
261 return localeName.toLatin1();
262}
263
267QString getWin32ShellFoldersPath ( const QString& folder )
268{
269 return getWin32RegistryValue ( HKEY_CURRENT_USER,
270 QLatin1String("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
271 folder );
272}
273
277static void kMessageOutputDebugString(QtMsgType type, const char *msg)
278{
279 int BUFSIZE=4096;
280 char *buf = new char[BUFSIZE];
281 switch (type) {
282 case QtDebugMsg:
283 strlcpy(buf,"Debug:",BUFSIZE);
284 strlcat(buf,msg,BUFSIZE);
285 break;
286 case QtWarningMsg:
287 strlcpy(buf,"Warning:",BUFSIZE);
288 strlcat(buf,msg,BUFSIZE);
289 break;
290 case QtCriticalMsg:
291 strlcpy(buf,"Critical:",BUFSIZE);
292 strlcat(buf,msg,BUFSIZE);
293 break;
294 case QtFatalMsg:
295 strlcpy(buf,"Fatal:",BUFSIZE);
296 strlcat(buf,msg,BUFSIZE);
297 //abort();
298 break;
299 }
300 strlcat(buf,"\n",BUFSIZE);
301 OutputDebugStringW( (WCHAR*)QString::fromLatin1(buf).utf16());
302 delete[] buf;
303}
304
308static void kMessageOutputFileIO(QtMsgType type, const char *msg)
309{
310 switch (type) {
311 case QtDebugMsg:
312 fprintf(stderr, "Debug: %s\n", msg);
313 break;
314 case QtWarningMsg:
315 fprintf(stderr, "Warning: %s\n", msg);
316 break;
317 case QtCriticalMsg:
318 fprintf(stderr, "Critical: %s\n", msg);
319 break;
320 case QtFatalMsg:
321 fprintf(stderr, "Fatal: %s\n", msg);
322 //abort();
323 }
324}
325
330typedef BOOL (WINAPI*attachConsolePtr)(DWORD dwProcessId);
331static attachConsolePtr attachConsole = 0;
332static bool attachConsoleResolved = false;
333static bool attachToConsole()
334{
335 bool out = true;
336 if(!attachConsoleResolved) {
337 attachConsoleResolved = true;
338 attachConsole = (attachConsolePtr)QLibrary::resolve(QLatin1String("kernel32"), "AttachConsole");
339 }
340 out = attachConsole ? attachConsole(~0U) != 0 : false;
341 if(GetLastError() == ERROR_ACCESS_DENIED)
342 {
343 //we are already atatched to a console
344 out = true;
345 }
346 return out;
347}
348
353static void redirectToConsole()
354{
355//FIXME: for wince we cannot set stdio buffers
356#ifndef _WIN32_WCE
357 int hCrt;
358 FILE *hf;
359 int i;
360
361 hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE),_O_TEXT);
362 if(hCrt != -1) {
363 hf = _fdopen( hCrt, "r" );
364 *stdin = *hf;
365 i = setvbuf( stdin, NULL, _IONBF, 0 );
366 }
367
368 hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
369 if(hCrt != -1) {
370 hf = _fdopen( hCrt, "w" );
371 *stdout = *hf;
372 i = setvbuf( stdout, NULL, _IONBF, 0 );
373 }
374
375 hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
376 if(hCrt != -1) {
377 hf = _fdopen( hCrt, "w" );
378 *stderr = *hf;
379 i = setvbuf( stderr, NULL, _IONBF, 0 );
380 }
381 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
382 // point to console as well
383 ios::sync_with_stdio();
384#endif
385}
386
387#include <streambuf>
388
392class debug_streambuf: public std::streambuf
393{
394 public:
395 debug_streambuf(const char *prefix)
396 {
397 strcpy(buf,prefix);
398 index = rindex = strlen(buf);
399 }
400
401 protected:
402 virtual int overflow(int c = EOF)
403 {
404 if (c != EOF)
405 {
406 char cc = traits_type::to_char_type(c);
407 // @TODO: buffer size checking
408 buf[index++] = cc;
409 if (cc == '\n')
410 {
411 buf[index] = '\0';
412 OutputDebugStringW((WCHAR*)QString::fromLatin1(buf).utf16());
413 index = rindex;
414 }
415 }
416 return traits_type::not_eof(c);
417 }
418 private:
419 char buf[4096];
420 int index, rindex;
421};
422
427static int subSystem()
428{
429#ifdef _WIN32_WCE
430 // there is only one subsystem on Windows CE
431 return IMAGE_SUBSYSTEM_WINDOWS_CE_GUI;
432#else
433 static int subSystem = -1;
434 if (subSystem > -1)
435 return subSystem;
436
437 // get base address of memory mapped executable
438 PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
439 PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS) ((char *)dosHeader + dosHeader->e_lfanew);
440 if (ntHeader->Signature != 0x00004550)
441 {
442 subSystem = IMAGE_SUBSYSTEM_UNKNOWN;
443 return subSystem;
444 }
445 subSystem = ntHeader->OptionalHeader.Subsystem;
446 return subSystem;
447#endif
448}
449
478static class kMessageOutputInstaller {
479 public:
480 kMessageOutputInstaller() : stdoutBuffer("stdout:"), stderrBuffer("stderr:"), oldStdoutBuffer(0), oldStderrBuffer(0)
481 {
482 if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
483 if (attachToConsole()) {
484 // setup kde and qt level
485 qInstallMsgHandler(kMessageOutputFileIO);
486 // redirect ios and file io to console
487 redirectToConsole();
488 }
489 else {
490 // setup kde and qt level
491 qInstallMsgHandler(kMessageOutputDebugString);
492 // redirect ios to debug message port
493 oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
494 oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
495 }
496 }
497 else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
498 // setup kde and qt level
499 qInstallMsgHandler(kMessageOutputDebugString);
500 // try to get a console
501 if (attachToConsole()) {
502 redirectToConsole();
503 }
504 else {
505 // redirect ios to debug message port
506 oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
507 oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
508 // TODO: redirect FILE * level to console, no idea how to do yet
509 }
510 } else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CE_GUI) {
511 // do not try to get a console on WinCE systems
512 qInstallMsgHandler(kMessageOutputDebugString);
513 oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
514 oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
515 }
516 else
517 qWarning("unknown subsystem %d detected, could not setup qt message handler",subSystem());
518 }
519 ~kMessageOutputInstaller()
520 {
521 if (oldStdoutBuffer)
522 std::cout.rdbuf(oldStdoutBuffer);
523 if (oldStderrBuffer)
524 std::cerr.rdbuf(oldStderrBuffer);
525 }
526
527 private:
528 debug_streambuf stdoutBuffer;
529 debug_streambuf stderrBuffer;
530 std::streambuf* oldStdoutBuffer;
531 std::streambuf* oldStderrBuffer;
532
533} kMessageOutputInstallerInstance;
534
535
536bool isExecutable(const QString &file)
537{
538 return ( file.endsWith( QLatin1String( ".exe" ) ) ||
539 file.endsWith( QLatin1String( ".com" ) ) ||
540 file.endsWith( QLatin1String( ".bat" ) ) ||
541 file.endsWith( QLatin1String( ".sln" ) ) ||
542 file.endsWith( QLatin1String( ".lnk" ) ) );
543
544}
545
546#endif // Q_OS_WIN
QString
kglobal.h
getWin32RegistryValue
QString getWin32RegistryValue(HKEY key, const QString &subKey, const QString &item, bool *ok)
Definition: kkernel_win.cpp:180
subSystem
static int subSystem()
retrieve type of win32 subsystem from the executable header
Definition: kkernel_win.cpp:427
redirectToConsole
static void redirectToConsole()
redirect stdout, stderr and cout, wcout, cin, wcin, wcerr, cerr, wclog and clog to console
Definition: kkernel_win.cpp:353
DllMain
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
The dll entry point - get the instance handle for GetModuleFleNameW Maybe also some special initializ...
Definition: kkernel_win.cpp:135
getWin32LocaleName
QByteArray getWin32LocaleName()
Definition: kkernel_win.cpp:248
kde4prefixUtf16
static wchar_t kde4prefixUtf16[MAX_PATH+2]
Definition: kkernel_win.cpp:66
initKde4prefixUtf16
void initKde4prefixUtf16()
Definition: kkernel_win.cpp:70
getKde4Prefix
QString getKde4Prefix()
Definition: kkernel_win.cpp:97
getWin32ShellFoldersPath
QString getWin32ShellFoldersPath(const QString &folder)
Windows-specific functions needed in kdecore.
Definition: kkernel_win.cpp:267
FAILURE
#define FAILURE
WIN32_CAST_CHAR
#define WIN32_CAST_CHAR
Definition: kkernel_win.cpp:55
attachConsole
static attachConsolePtr attachConsole
Definition: kkernel_win.cpp:331
isExecutable
bool isExecutable(const QString &file)
Definition: kkernel_win.cpp:536
showWin32FilePropertyDialog
bool showWin32FilePropertyDialog(const QString &fileName)
Shows native MS Windows file property dialog for a file fileName.
Definition: kkernel_win.cpp:218
kMessageOutputDebugString
static void kMessageOutputDebugString(QtMsgType type, const char *msg)
kde and qt debug message printer using windows debug message port
Definition: kkernel_win.cpp:277
attachConsolePtr
BOOL(WINAPI * attachConsolePtr)(DWORD dwProcessId)
try to attach to the parents console
Definition: kkernel_win.cpp:330
attachConsoleResolved
static bool attachConsoleResolved
Definition: kkernel_win.cpp:332
kde4Prefix
static QString * kde4Prefix
Definition: kkernel_win.cpp:68
kMessageOutputFileIO
static void kMessageOutputFileIO(QtMsgType type, const char *msg)
kde and qt debug message printer using FILE pointer based output
Definition: kkernel_win.cpp:308
kdecoreDllInstance
static HINSTANCE kdecoreDllInstance
Definition: kkernel_win.cpp:59
attachToConsole
static bool attachToConsole()
Definition: kkernel_win.cpp:333
kMessageOutputInstallerInstance
static class kMessageOutputInstaller kMessageOutputInstallerInstance
kkernel_win.h
klocale.h
prefix
QString prefix()
Definition: kstandarddirs_win.cpp:28
BOOL
typedef BOOL(WINAPI *PtrTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal