00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "kkernel_win.h"
00024
00025 #include <config.h>
00026 #include <QtCore/QBool>
00027 #include <QtCore/QTextCodec>
00028
00029 #ifdef Q_OS_WIN
00030
00031 #include "kglobal.h"
00032 #include <klocale.h>
00033
00034 #include <QtCore/QDir>
00035 #include <QtCore/QString>
00036
00037 #include <windows.h>
00038 #include <shellapi.h>
00039 #include <process.h>
00040
00041 #if defined(__MINGW32__)
00042 # define WIN32_CAST_CHAR (const WCHAR*)
00043 #else
00044 # define WIN32_CAST_CHAR (LPCWSTR)
00045 #endif
00046
00047 static HINSTANCE kdecoreDllInstance = NULL;
00048 static wchar_t kde4prefixUtf16[MAX_PATH + 2];
00049 static QString *kde4Prefix = NULL;
00050
00051 void initKde4prefixUtf16()
00052 {
00053
00054 GetModuleFileNameW(kdecoreDllInstance, kde4prefixUtf16, MAX_PATH + 1);
00055 int bs1 = 0, bs2 = 0;
00056
00057
00058 int pos;
00059 for (pos = 0; pos < MAX_PATH + 1 && kde4prefixUtf16[pos] != 0; ++pos) {
00060 if (kde4prefixUtf16[pos] == '\\') {
00061 bs1 = bs2;
00062 bs2 = pos;
00063 kde4prefixUtf16[pos] = '/';
00064 }
00065 }
00066 Q_ASSERT(bs1);
00067 Q_ASSERT(pos < MAX_PATH + 1);
00068 kde4prefixUtf16[bs1] = '/';
00069 kde4prefixUtf16[bs1+1] = 0;
00070 }
00071
00072
00073
00074 QString getKde4Prefix()
00075 {
00076
00077 return kde4Prefix ? *kde4Prefix : QString::fromUtf16((ushort*) kde4prefixUtf16);
00078 }
00079
00084 extern "C"
00085 BOOL WINAPI DllMain ( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved)
00086 {
00087 switch ( fdwReason ) {
00088 case DLL_PROCESS_ATTACH:
00089 kdecoreDllInstance = hinstDLL;
00090 initKde4prefixUtf16();
00091 kde4Prefix = new QString( QString::fromUtf16((ushort*) kde4prefixUtf16) );
00092 break;
00093 case DLL_PROCESS_DETACH:
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 if( lpReserved == NULL )
00106 delete kde4Prefix;
00107 kde4Prefix = 0;
00108 break;
00109 default:
00110 break;
00111 }
00112 return true;
00113 }
00114
00125 QString getWin32RegistryValue ( HKEY key, const QString& subKey, const QString& item, bool *ok = 0 )
00126 {
00127 #define FAILURE \
00128 { if (ok) \
00129 *ok = false; \
00130 return QString(); }
00131
00132 if ( subKey.isEmpty() )
00133 FAILURE;
00134 HKEY hKey;
00135 TCHAR *lszValue;
00136 DWORD dwType=REG_SZ;
00137 DWORD dwSize;
00138
00139 if ( ERROR_SUCCESS!=RegOpenKeyExW ( key, WIN32_CAST_CHAR subKey.utf16(), 0, KEY_READ, &hKey ) )
00140 FAILURE;
00141
00142 if ( ERROR_SUCCESS!=RegQueryValueExW ( hKey, WIN32_CAST_CHAR item.utf16(), NULL, NULL, NULL, &dwSize ) )
00143 FAILURE;
00144
00145 lszValue = new TCHAR[dwSize];
00146
00147 if ( ERROR_SUCCESS!=RegQueryValueExW ( hKey, WIN32_CAST_CHAR item.utf16(), NULL, &dwType, ( LPBYTE ) lszValue, &dwSize ) ) {
00148 delete [] lszValue;
00149 FAILURE;
00150 }
00151 RegCloseKey ( hKey );
00152
00153 QString res = QString::fromUtf16 ( ( const ushort* ) lszValue );
00154 delete [] lszValue;
00155 return res;
00156 }
00157
00158
00159 bool showWin32FilePropertyDialog ( const QString& fileName )
00160 {
00161 QString path_ = QDir::convertSeparators ( QFileInfo ( fileName ).absoluteFilePath() );
00162
00163 SHELLEXECUTEINFOW execInfo;
00164 memset ( &execInfo,0,sizeof ( execInfo ) );
00165 execInfo.cbSize = sizeof ( execInfo );
00166 execInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
00167 const QString verb ( QLatin1String ( "properties" ) );
00168 execInfo.lpVerb = WIN32_CAST_CHAR verb.utf16();
00169 execInfo.lpFile = WIN32_CAST_CHAR path_.utf16();
00170 return ShellExecuteExW ( &execInfo );
00171 }
00172
00173
00174
00175 QByteArray getWin32LocaleName()
00176 {
00177 bool ok;
00178 QString localeNumber = getWin32RegistryValue ( HKEY_CURRENT_USER,
00179 QLatin1String("Control Panel\\International"),
00180 "Locale", &ok );
00181 if ( !ok )
00182 return QByteArray();
00183 QString localeName = getWin32RegistryValue ( HKEY_LOCAL_MACHINE,
00184 QLatin1String("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout\\DosKeybCodes"),
00185 localeNumber, &ok );
00186 if ( !ok )
00187 return QByteArray();
00188 return localeName.toLatin1();
00189 }
00190
00194 QString getWin32ShellFoldersPath ( const QString& folder )
00195 {
00196 return getWin32RegistryValue ( HKEY_CURRENT_USER,
00197 QLatin1String("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
00198 folder );
00199 }
00200
00204 static void kMessageGuiOutput(QtMsgType type, const char *msg)
00205 {
00206 int BUFSIZE=4096;
00207 char *buf = new char[BUFSIZE];
00208 switch (type) {
00209 case QtDebugMsg:
00210 strlcpy(buf,"Debug:",BUFSIZE);
00211 strlcat(buf,msg,BUFSIZE);
00212 break;
00213 case QtWarningMsg:
00214 strlcpy(buf,"Warning:",BUFSIZE);
00215 strlcat(buf,msg,BUFSIZE);
00216 break;
00217 case QtCriticalMsg:
00218 strlcpy(buf,"Critical:",BUFSIZE);
00219 strlcat(buf,msg,BUFSIZE);
00220 break;
00221 case QtFatalMsg:
00222 strlcpy(buf,"Fatal:",BUFSIZE);
00223 strlcat(buf,msg,BUFSIZE);
00224
00225 break;
00226 }
00227 strlcat(buf,"\n",BUFSIZE);
00228 OutputDebugStringA(buf);
00229 delete[] buf;
00230 }
00231
00235 static void kMessageConsoleOutput(QtMsgType type, const char *msg)
00236 {
00237 kMessageGuiOutput(type,msg);
00238 switch (type) {
00239 case QtDebugMsg:
00240 fprintf(stderr, "Debug: %s\n", msg);
00241 break;
00242 case QtWarningMsg:
00243 fprintf(stderr, "Warning: %s\n", msg);
00244 break;
00245 case QtCriticalMsg:
00246 fprintf(stderr, "Critical: %s\n", msg);
00247 break;
00248 case QtFatalMsg:
00249 fprintf(stderr, "Fatal: %s\n", msg);
00250
00251 }
00252 }
00253
00258 static int subSystem()
00259 {
00260 static int subSystem = -1;
00261 if (subSystem > -1)
00262 return subSystem;
00263
00264 PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)0x00400000;
00265 PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS) ((char *)dosHeader + dosHeader->e_lfanew);
00266 if (ntHeader->Signature != 0x00004550)
00267 {
00268 subSystem = IMAGE_SUBSYSTEM_UNKNOWN;
00269 return subSystem;
00270 }
00271 subSystem = ntHeader->OptionalHeader.Subsystem;
00272 return subSystem;
00273 }
00274
00287 static class kMessageOutputInstaller {
00288 public:
00289 kMessageOutputInstaller()
00290 {
00291 if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
00292 qInstallMsgHandler(kMessageConsoleOutput);
00293 }
00294 else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
00295 qInstallMsgHandler(kMessageGuiOutput);
00296 }
00297 else
00298 qWarning("unknown subsystem %d detected, could not setup qt message handler",subSystem());
00299 }
00300 } kMessageOutputInstallerInstance;
00301
00302
00303 bool isExecutable(const QString &file)
00304 {
00305 return ( file.endsWith( QLatin1String( ".exe" ) ) ||
00306 file.endsWith( QLatin1String( ".com" ) ) ||
00307 file.endsWith( QLatin1String( ".bat" ) ) ||
00308 file.endsWith( QLatin1String( ".sln" ) ) ||
00309 file.endsWith( QLatin1String( ".lnk" ) ) );
00310
00311 }
00312
00313 #endif // Q_OS_WIN