• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.4 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
49 using 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
59 static HINSTANCE kdecoreDllInstance = NULL;
60 #else
61 static HANDLE kdecoreDllInstance = NULL;
62 #endif
63 #ifdef KDELIBS_STATIC_LIBS
64 static bool kde4prefixInitialized = false;
65 #endif
66 static wchar_t kde4prefixUtf16[MAX_PATH + 2] = L"";
67 
68 static QString *kde4Prefix = NULL;
69 
70 void 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
97 QString 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
129 
133 extern "C"
134 #ifndef _WIN32_WCE
135 BOOL WINAPI DllMain ( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved)
136 #else
137 BOOL 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 
180 QString 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 
218 bool 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 
248 QByteArray 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 
267 QString getWin32ShellFoldersPath ( const QString& folder )
268 {
269  return getWin32RegistryValue ( HKEY_CURRENT_USER,
270  QLatin1String("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
271  folder );
272 }
273 
277 static 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 
308 static 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 
330 typedef BOOL (WINAPI*attachConsolePtr)(DWORD dwProcessId);
331 static attachConsolePtr attachConsole = 0;
332 static bool attachConsoleResolved = false;
333 static bool attachToConsole()
334 {
335  if(!attachConsoleResolved) {
336  attachConsoleResolved = true;
337  attachConsole = (attachConsolePtr)QLibrary::resolve(QLatin1String("kernel32"), "AttachConsole");
338  }
339  return attachConsole ? attachConsole(~0U) != 0 : false;
340 }
341 
346 static void redirectToConsole()
347 {
348 //FIXME: for wince we cannot set stdio buffers
349 #ifndef _WIN32_WCE
350  int hCrt;
351  FILE *hf;
352  int i;
353 
354  hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE),_O_TEXT);
355  if(hCrt != -1) {
356  hf = _fdopen( hCrt, "r" );
357  *stdin = *hf;
358  i = setvbuf( stdin, NULL, _IONBF, 0 );
359  }
360 
361  hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
362  if(hCrt != -1) {
363  hf = _fdopen( hCrt, "w" );
364  *stdout = *hf;
365  i = setvbuf( stdout, NULL, _IONBF, 0 );
366  }
367 
368  hCrt = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
369  if(hCrt != -1) {
370  hf = _fdopen( hCrt, "w" );
371  *stderr = *hf;
372  i = setvbuf( stderr, NULL, _IONBF, 0 );
373  }
374  // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
375  // point to console as well
376  ios::sync_with_stdio();
377 #endif
378 }
379 
380 #include <streambuf>
381 
385 class debug_streambuf: public std::streambuf
386 {
387  public:
388  debug_streambuf(const char *prefix)
389  {
390  strcpy(buf,prefix);
391  index = rindex = strlen(buf);
392  }
393 
394  protected:
395  virtual int overflow(int c = EOF)
396  {
397  if (c != EOF)
398  {
399  char cc = traits_type::to_char_type(c);
400  // @TODO: buffer size checking
401  buf[index++] = cc;
402  if (cc == '\n')
403  {
404  buf[index] = '\0';
405  OutputDebugStringW((WCHAR*)QString::fromLatin1(buf).utf16());
406  index = rindex;
407  }
408  }
409  return traits_type::not_eof(c);
410  }
411  private:
412  char buf[4096];
413  int index, rindex;
414 };
415 
420 static int subSystem()
421 {
422 #ifdef _WIN32_WCE
423  // there is only one subsystem on Windows CE
424  return IMAGE_SUBSYSTEM_WINDOWS_CE_GUI;
425 #else
426  static int subSystem = -1;
427  if (subSystem > -1)
428  return subSystem;
429 
430  // get base address of memory mapped executable
431  PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
432  PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS) ((char *)dosHeader + dosHeader->e_lfanew);
433  if (ntHeader->Signature != 0x00004550)
434  {
435  subSystem = IMAGE_SUBSYSTEM_UNKNOWN;
436  return subSystem;
437  }
438  subSystem = ntHeader->OptionalHeader.Subsystem;
439  return subSystem;
440 #endif
441 }
442 
471 static class kMessageOutputInstaller {
472  public:
473  kMessageOutputInstaller() : stdoutBuffer("stdout:"), stderrBuffer("stderr:"), oldStdoutBuffer(0), oldStderrBuffer(0)
474  {
475  if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
476  if (attachToConsole()) {
477  // setup kde and qt level
478  qInstallMsgHandler(kMessageOutputFileIO);
479  // redirect ios and file io to console
480  redirectToConsole();
481  }
482  else {
483  // setup kde and qt level
484  qInstallMsgHandler(kMessageOutputDebugString);
485  // redirect ios to debug message port
486  oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
487  oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
488  }
489  }
490  else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
491  // setup kde and qt level
492  qInstallMsgHandler(kMessageOutputDebugString);
493  // try to get a console
494  if (attachToConsole()) {
495  redirectToConsole();
496  }
497  else {
498  // redirect ios to debug message port
499  oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
500  oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
501  // TODO: redirect FILE * level to console, no idea how to do yet
502  }
503  } else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CE_GUI) {
504  // do not try to get a console on WinCE systems
505  qInstallMsgHandler(kMessageOutputDebugString);
506  oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
507  oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
508  }
509  else
510  qWarning("unknown subsystem %d detected, could not setup qt message handler",subSystem());
511  }
512  ~kMessageOutputInstaller()
513  {
514  if (oldStdoutBuffer)
515  std::cout.rdbuf(oldStdoutBuffer);
516  if (oldStderrBuffer)
517  std::cerr.rdbuf(oldStderrBuffer);
518  }
519 
520  private:
521  debug_streambuf stdoutBuffer;
522  debug_streambuf stderrBuffer;
523  std::streambuf* oldStdoutBuffer;
524  std::streambuf* oldStderrBuffer;
525 
526 } kMessageOutputInstallerInstance;
527 
528 
529 bool isExecutable(const QString &file)
530 {
531  return ( file.endsWith( QLatin1String( ".exe" ) ) ||
532  file.endsWith( QLatin1String( ".com" ) ) ||
533  file.endsWith( QLatin1String( ".bat" ) ) ||
534  file.endsWith( QLatin1String( ".sln" ) ) ||
535  file.endsWith( QLatin1String( ".lnk" ) ) );
536 
537 }
538 
539 #endif // Q_OS_WIN
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jun 1 2013 12:05:02 by doxygen 1.8.1.1 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.10.4 API Reference

Skip menu "kdelibs-4.10.4 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