win32.cpp

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file win32.cpp
00013 ** \version $Id: win32.cpp 2362 2008-02-29 04:30:11Z edmanm $ 
00014 ** \brief Win32-specific functions
00015 */
00016 
00017 #include "win32.h"
00018 #include <tlhelp32.h>
00019 #include <shlobj.h>
00020 #include <QDir>
00021 #include <QLibrary>
00022 #include <QtDebug>
00023 
00024 #if defined(UNICODE)
00025 /* Force the ascii verisons of these functions, so we can run on Win98. We
00026  * don't pass any Unicode strings to these functions anyway. */
00027 #undef PROCESSENTRY32
00028 #undef LPPROCESSENTRY32
00029 #undef Process32First
00030 #undef Process32Next
00031 #endif
00032 
00033 /* Load the tool help functions dynamically, since they don't exist on
00034  * Windows NT 4.0 */
00035 typedef HANDLE (WINAPI *CreateToolhelp32Snapshot_fn)(DWORD, DWORD);
00036 typedef BOOL (WINAPI *Process32First_fn)(HANDLE, LPPROCESSENTRY32);
00037 typedef BOOL (WINAPI *Process32Next_fn)(HANDLE, LPPROCESSENTRY32);
00038 
00039 
00040 /** Finds the location of the "special" Windows folder using the given CSIDL
00041  * value. If the folder cannot be found, the given default path is used. */
00042 QString
00043 win32_get_folder_location(int folder, QString defaultPath)
00044 {
00045   TCHAR path[MAX_PATH+1];
00046   LPITEMIDLIST idl;
00047   IMalloc *m;
00048   HRESULT result;
00049 
00050   /* Find the location of %PROGRAMFILES% */
00051   if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &idl))) {
00052     /* Get the path from the IDL */
00053     result = SHGetPathFromIDList(idl, path);
00054     SHGetMalloc(&m);
00055     if (m) {
00056       m->Release();
00057     }
00058     if (SUCCEEDED(result)) {
00059       QT_WA(return QString::fromUtf16((const ushort *)path);,
00060             return QString::fromLocal8Bit((char *)path);)
00061     }
00062   }
00063   return defaultPath;
00064 }
00065 
00066 /** Gets the location of the user's %PROGRAMFILES% folder. */
00067 QString
00068 win32_program_files_folder()
00069 {
00070   return win32_get_folder_location(
00071      CSIDL_PROGRAM_FILES, QDir::rootPath() + "\\Program Files");
00072 }
00073 
00074 /** Gets the location of the user's %APPDATA% folder. */
00075 QString
00076 win32_app_data_folder()
00077 {
00078   return win32_get_folder_location(
00079       CSIDL_APPDATA, QDir::homePath() + "\\Application Data");
00080 }
00081 
00082 /** Returns the value in keyName at keyLocation. 
00083  *  Returns an empty QString if the keyName doesn't exist */
00084 QString
00085 win32_registry_get_key_value(QString keyLocation, QString keyName)
00086 {
00087   HKEY key;
00088   char data[255] = {0};
00089   DWORD size = sizeof(data);
00090 
00091   /* Open the key for reading (opens new key if it doesn't exist) */
00092   if (RegOpenKeyExA(HKEY_CURRENT_USER,
00093                     qPrintable(keyLocation), 
00094                     0L, KEY_READ, &key) == ERROR_SUCCESS) {
00095     
00096     /* Key exists, so read the value into data */
00097     RegQueryValueExA(key, qPrintable(keyName), 
00098                     NULL, NULL, (LPBYTE)data, &size);
00099   }
00100 
00101   /* Close anything that was opened */
00102   RegCloseKey(key);
00103 
00104   return QString(data);
00105 }
00106 
00107 /** Creates and/or sets the key to the specified value */
00108 void
00109 win32_registry_set_key_value(QString keyLocation, QString keyName, QString keyValue)
00110 {
00111   HKEY key;
00112   
00113   /* Open the key for writing (opens new key if it doesn't exist */
00114   if (RegOpenKeyExA(HKEY_CURRENT_USER,
00115                    qPrintable(keyLocation),
00116                    0, KEY_WRITE, &key) != ERROR_SUCCESS) {
00117 
00118     /* Key didn't exist, so write the newly opened key */
00119     RegCreateKeyExA(HKEY_CURRENT_USER,
00120                    qPrintable(keyLocation),
00121                    0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
00122                    &key, NULL);
00123   }
00124 
00125   /* Save the value in the key */
00126   RegSetValueExA(key, qPrintable(keyName), 0, REG_SZ, 
00127                 (BYTE *)qPrintable(keyValue),
00128                 (DWORD)keyValue.length() + 1); // include null terminator
00129 
00130   /* Close the key */
00131   RegCloseKey(key);
00132 }
00133 
00134 /** Removes the key from the registry if it exists */
00135 void
00136 win32_registry_remove_key(QString keyLocation, QString keyName)
00137 {
00138   HKEY key;
00139   
00140   /* Open the key for writing (opens new key if it doesn't exist */
00141   if (RegOpenKeyExA(HKEY_CURRENT_USER,
00142                    qPrintable(keyLocation),
00143                    0, KEY_SET_VALUE, &key) == ERROR_SUCCESS) {
00144   
00145     /* Key exists so delete it */
00146     RegDeleteValueA(key, qPrintable(keyName));
00147   }
00148 
00149   /* Close anything that was opened */
00150   RegCloseKey(key);
00151 }
00152 
00153 /** Returns a list of all currently active processes, including their pid
00154  * and exe filename. */
00155 QHash<qint64, QString>
00156 win32_process_list()
00157 {
00158   QHash<qint64, QString> procList;
00159   CreateToolhelp32Snapshot_fn pCreateToolhelp32Snapshot;
00160   Process32First_fn pProcess32First;
00161   Process32Next_fn pProcess32Next;
00162   HANDLE hSnapshot;
00163   PROCESSENTRY32 proc;
00164   QString exeFile;
00165   qint64 pid;
00166 
00167   /* Load the tool help functions */
00168   pCreateToolhelp32Snapshot =
00169     (CreateToolhelp32Snapshot_fn)QLibrary::resolve("kernel32", "CreateToolhelp32Snapshot");
00170   pProcess32First = (Process32First_fn)QLibrary::resolve("kernel32", "Process32First");
00171   pProcess32Next = (Process32Next_fn)QLibrary::resolve("kernel32", "Process32Next");
00172  
00173   if (!pCreateToolhelp32Snapshot || !pProcess32First || !pProcess32Next) {
00174     qWarning("Unable to load tool help functions. Running process information "
00175              "will be unavailable.");
00176     return QHash<qint64, QString>();
00177   }
00178 
00179   /* Create a snapshot of all active processes */
00180   hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
00181   if (hSnapshot != INVALID_HANDLE_VALUE) {
00182     proc.dwSize = sizeof(PROCESSENTRY32);
00183     
00184     /* Iterate through all the processes in the snapshot */
00185     if (pProcess32First(hSnapshot, &proc)) {
00186       do {
00187         /* Extract the PID and exe filename from the process record */
00188         pid = (qint64)proc.th32ProcessID;
00189         exeFile = QString::fromAscii((const char *)proc.szExeFile);
00190         
00191         /* Add this process to our list */
00192         procList.insert(pid, exeFile);
00193       } while (pProcess32Next(hSnapshot, &proc));
00194     }
00195     CloseHandle(hSnapshot);
00196   }
00197   return procList;
00198 }
00199 

Generated on Wed Nov 26 21:02:39 2008 for Vidalia by  doxygen 1.5.6