C++

Добавление кнопки плагина к окну сообщения QIP

В этом примере узнаем, как можно создать кнопку плагина в окне сообщения программы QIP, а также добавить ей событие. Для этого будет использоваться плагин заготовка, необходимые действия описаны в виде алгоритма действий:
Подробнее »Добавление кнопки плагина к окну сообщения QIP

Создание плагина заготовки для QIP

Работа плагина для QIP
Для продолжения дальнейших экспериментов с написанием плагина для программы QIP, понадобиться плагин заготовка, который представляет собой каркас, на который в последующем будет наращиваться функционал создаваемого плагина. За основу был взять исходник поставляемый вместе с портированным SDK для C++, в котором был немного изменен код, удален функционал и добавлен показ сообщения при нажатии кнопки «Настроить» в настройках модулей.

Скачать плагин

Создание плагина для QIP используя Microsoft Visual C++

Создание плагина для QIP используя Microsoft Visual C++QIP – это многофункциональная программа, которая со временем станет нечто большим, нежели мульти протокольным средством мгновенного обмена сообщениями. Для расширения представленных возможностей программы, существует SDK для написания плагинов, при помощи которого будем добавлять новый функционал к программе QIP.
В данной заметке попробуем создать первый простой плагин, из поставки SDK, при этом ни написав, ни одной строки кода. В первую очередь это заметка дает начальные навыки создания плагина и необходимую информацию для этого. На момент написания заметки использовался QIP Infium Release 3.0 Build 9044 и QIP Infium VC++ Plugin SDK Версия 1.9.0. Плагин создавался в Microsoft Visual C++ 2010. Описание создание плагина будет приведено в виде алгоритма действия.
Подробнее »Создание плагина для QIP используя Microsoft Visual C++

Просмотр сетевых сеансов

В операционных система Windows имеется интересный инструмент «Общие папки», являющийся средством для просмотра общих ресурсов локального компьютера, открытых сетевых сеансов и используемых файлов, для того чтобы запустить данное приложение, нужно набрать в командной строке fsmgmt.mscПодробнее »Просмотр сетевых сеансов

Программирование WinInet C++. Часть 2

Целью создания системы явилась потребность в удаленном управлении и администрировании домашним компьютером, получении и обмене информации с ним, при помощи веб браузера используемого как в компьютере, так и в сотовом телефоне.Подробнее »Программирование WinInet C++. Часть 2

Программирование WinInet C++

WinInet сокращение от Windows Internet, это ничто иной как расширение к Windows API, созданное компанией Microsoft, который предоставляет простой в использовании интерфейса для трех прикладных протоколов Интернета.
В данном примере рассматривается способ получения строки с web сайта используя протокол HTTP, данную реализацию можно использовать для того чтобы приложение могло проверять наличие обновлений или скачивать заранее подготовленный файл, в общем можно найти огромное количество примеров для применения данной технологии.Подробнее »Программирование WinInet C++

Прокси туннелирование. Часть 2

Прокси серверы представляют из себя компьютеры с установленным специализированным программным обеспечением и являются, по сути, обработчиками разнообразных запросов со стороны клиента и передачи их дальше по сети. Они играют большую роль в функционировании компьютерных сетей, как локальных, так и глобальной сети Интернет.Подробнее »Прокси туннелирование. Часть 2

Прокси туннелирование C++

Прокси серверы – это компьютеры с установленным специализированным программным обеспечением, служащие для обработки разнообразных запросов со стороны клиента. Основными типами прокси серверов служат: шлюзы, анонимные прокси и файрволы. В данном примере показано как через HTTP прокси получить тестовую html страницу.Подробнее »Прокси туннелирование C++

Программно монтируем диски в директорию

В этой статье рассматривается, как программно монтировать жесткие диски в директории. По умолчанию Windows монтирует несъемные носители автоматически, то есть если вы подключаете новый жесткий диск к компьютеру и после загрузки операционной системы, и установки необходимых драйверов, вы можете увидеть его в проводнике.

В операционных системах UNIX существует возможность монтирования жестких дисков в директории, так называемые точки монтирования. Начиная с Windows NT 4.0 в поставку операционной системы входит утилита mountvol.exe, которая через интерфейс командной строки позволяет создавать, удалять и выводит список точек подключения дисков. Результат работы которой вы видите на рисунке:

Программно монтируем диски в директорию

После не продолжительной работы с данной утилитой, мне захотелось реализовать предоставленные возможности самому, программно. Первым шагом, нужно было, выяснить какие API функции использует mountvol.exe, для этого использовалась программа Dependency Walker входящая в состав поставки среды разработки, ниже на рисунке предоставлено основное окно программы с загруженной в нее утилиты mountvol.exe:
Программно монтируем диски в директорию
Из результата работы Dependency Walker мы видим какие API функции использует mountvol.exe. Для создания программы-примера использовалась среда разработки MS Visual C++ 6.0, тип приложения «Win 32 Console Application».Для начала рассмотрим функций, которые будут использоваться в приложении, и так по порядку:

HANDLE FindFirstVolume(LPTSTR lpszVolumeName,DWORD cchBufferLength);

Данная функция используется для начала сканирования компьютера на наличие томов, возвращаемое значение хендел который используется для последующего поиска, в переменную lpszVolumeName возвращается указатель на буфер, содержащий уникальный индефикатор (GUID) первого найденного тома.

Для дальнейшего поиска используется функция:

BOOL FindNextVolume(HANDLE hFindVolume, LPTSTR lpszVolumeName, DWORD cchBufferLength);

Первым параметром, которой является хендел, полученный при помощи вызова функции FindFirstVolume, в переменную lpszVolumeName возвращаются последующие найденные индефикаторы(GUID) томов.

Для завершения поиска необходимо осуществить вызов функции:

BOOL FindVolumeClose(HANDLE hFindVolume);

Единственным параметром функции, которой является хендел поиска.

Для определения типа тома использовалась функция:

UINT GetDriveType( LPCTSTR lpRootPathName);

Параметром которой является индефикатор тома, возвращаемое значение:

DRIVE_UNKNOWN Не известный тип
DRIVE_NO_ROOT_DIR Не точек подключения
DRIVE_REMOVABLE Съёмный диск
DRIVE_FIXED Фиксированный диск
DRIVE_REMOTE Удалённый или network диск
DRIVE_CDROM CD-ROM диск
DRIVE_RAMDISK RAM диск

Для определения файловой системы и метки тома использовалась функция:

BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,
  LPTSTR lpVolumeNameBuffer,
  DWORD nVolumeNameSize,
  LPDWORD lpVolumeSerialNumber,
  LPDWORD lpMaximumComponentLength,
  LPDWORD lpFileSystemFlags,
  LPTSTR lpFileSystemNameBuffer,
  DWORD nFileSystemNameSize);

Первый параметр которой является уникальный индефикатор тома, в параметра lpVolumeNameBuffer возвращается метка тома, в параметр lpFileSystemNameBuffer возвращается указатель на буфер содержащий имя файловой системы.

Мною также был найден еще один способ получения уникальных индефикаторов томов, для этого использовалась связка функций GetLogicalDrives и GetVolumeNameForVolumeMountPoint, подробней о их параметрах:

DWORD GetLogicalDrives(void);

Функция возвращает битовую маску, которая содержит все доступные тома в системе.

BOOL GetVolumeNameForVolumeMountPoint(
  LPCTSTR lpszVolumeMountPoint,
  LPTSTR lpszVolumeName,
  DWORD cchBufferLength);

Функция возвращает уникальный индефикатор тома по его точке монтирования.
На рисунке представлен результат работы этих двух способов:
Программно монтируем диски в директорию
Для удаления точки монтирования использовалась функция:

BOOL DeleteVolumeMountPoint(LPCTSTR lpszVolumeMountPoint);

Параметром которой является точка монтирования.

И самая главная функция по монтированию томов:

BOOL SetVolumeMountPoint(
  LPCTSTR lpszVolumeMountPoint,
  LPCTSTR lpszVolumeName);

Первый параметр которой является точка последующего монтирования, в нашем случае это директория, например “C:\\mnt\\”, второй параметр это уникальный индефикатор тома.

<strong>Предупреждение:</strong>
Точка куда будет монтироваться том, в нашем случае директория должна быть пустой!!!
На содержимое монтируемого тома это условие не распространяется.

А теперь пробуем все вместе, далее приведен исходный текст программы, которая сначала выводит двумя способами уникальные индефикаторы томов, так же файловую систему, тип тома и метку, дальше она производит демонтирование заданного диска и последующее его монтирование в точку C:\\mnt\\ после паузы возвращает первоначальную точку.

#include <iostream.h>
#include <windows.h>
#include <conio.h>
 
HANDLE (WINAPI * FindFirstVolume)(LPTSTR,DWORD);
BOOL   (WINAPI * FindNextVolume)(HANDLE,LPTSTR,DWORD);
BOOL   (WINAPI * FindVolumeClose)(HANDLE);
BOOL   (WINAPI * GetVolumeNameForVolumeMountPoint)(LPCTSTR,LPTSTR,DWORD);
BOOL   (WINAPI * DeleteVolumeMountPoint)(LPCTSTR);
BOOL   (WINAPI * SetVolumeMountPoint)(LPCTSTR,LPCTSTR);
 
void ErrorView();
 
int main()
{
        HANDLE hMount;
 
        char szPath[MAX_PATH],
                 szRecvBuff[MAX_PATH+1],
                 szFileSystem[MAX_PATH+1];
 
        HMODULE hmod;
        if((hmod = LoadLibrary("Kernel32.dll")))
        {
                if(!(FindFirstVolume  = (HANDLE(WINAPI *)
                        (LPTSTR,DWORD))GetProcAddress(hmod,"FindFirstVolumeA")))
                {cout<<"Error GetProcAddress...1"<<endl;return -1;}
                if(!(FindNextVolume   = (BOOL(WINAPI *)
                        (HANDLE,LPTSTR,DWORD))GetProcAddress(hmod,"FindNextVolumeA")))
                {cout<<"Error GetProcAddress...2"<<endl;return -1;}
                if(!(FindVolumeClose  = (BOOL(WINAPI *)
                        (HANDLE))GetProcAddress(hmod,"FindVolumeClose")))
                {cout<<"Error GetProcAddress...3"<<endl;return -1;}
                if(!(GetVolumeNameForVolumeMountPoint  = (BOOL(WINAPI *)
                        (LPCTSTR,LPTSTR,DWORD))GetProcAddress(hmod,
                        "GetVolumeNameForVolumeMountPointA")))
                {cout<<"Error GetProcAddress...4"<<endl;return -1;}
                if(!(DeleteVolumeMountPoint  = (BOOL(WINAPI *)
                        (LPCTSTR))GetProcAddress(hmod,"DeleteVolumeMountPointA")))
                {cout<<"Error GetProcAddress...5"<<endl;return -1;}
                if(!(SetVolumeMountPoint  = (BOOL(WINAPI *)
                        (LPCTSTR,LPCTSTR))GetProcAddress(hmod,"SetVolumeMountPointA")))
                {cout<<"Error GetProcAddress...6"<<endl;return -1;}
 
                hMount = FindFirstVolume(szPath,sizeof(szPath));
 
                UINT uin;
 
                if(hMount!=INVALID_HANDLE_VALUE)
                {
                        do
                        {
                                uin = GetDriveType(szPath);
                                if(uin==DRIVE_CDROM)      {cout<<"CDROM: ";}
                                if(uin==DRIVE_UNKNOWN)    {cout<<"UNKNOWN: ";}
                                if(uin==DRIVE_NO_ROOT_DIR){cout<<"NO_ROOT_DIR: ";}
                                if(uin==DRIVE_REMOVABLE)  {cout<<"REMOV: ";}
                                if(uin==DRIVE_FIXED)      {cout<<"FIXED: ";}
                                if(uin==DRIVE_REMOTE)     {cout<<"REMOTE: ";}
                                if(uin==DRIVE_RAMDISK)    {cout<<"RAMDISK: ";}
 
                                GetVolumeInformation(szPath,
                                                                szRecvBuff,
                                                                sizeof(szRecvBuff),
                                                                NULL,NULL,NULL,
                                                                szFileSystem,
                                                                sizeof(szFileSystem));
 
                                cout<<"("<<szRecvBuff
                                      <<"|"<<szFileSystem
                                      <<") "<<szPath<<endl<<endl;  
        
                                ZeroMemory(szRecvBuff,sizeof(szRecvBuff));
                                ZeroMemory(szFileSystem,sizeof(szFileSystem));
 
                        }while(FindNextVolume(hMount,szPath,sizeof(szPath))!=0);
                        
                        FindVolumeClose(hMount);
 
                }else{cout<<"Error FindFirstVolume"<<endl;}
 
                FreeLibrary(hmod);
                
        }else{cout<<"Error LoadLibrary"<<endl;}
                
        ZeroMemory(szRecvBuff,sizeof(szRecvBuff));
        char szDrive[4];DWORD dwID = GetLogicalDrives();
 
        for(int i = 0;i < 26;i++)
        {
           if(((dwID>>i)&0x00000001)==1)
           {
                 szDrive[0] =  char(65+i);
                 szDrive[1] = ':';
                 szDrive[2] = '\\';
                 szDrive[3] = 0;
                 GetVolumeNameForVolumeMountPoint(szDrive,
                                                                        szRecvBuff,
                                                                        sizeof(szRecvBuff));
                 cout <<szDrive<<" "<<szRecvBuff<<endl;
 
           }
        }
 
/************************************/
        if(DeleteVolumeMountPoint("G:\\"))
        {cout<<"DeleteVolumeMountPoint status:OK"<<endl;}
        else
        {cout<<"DeleteVolumeMountPoint status:ERROR"<<endl;ErrorView();}
        if(SetVolumeMountPoint("C:\\mnt\\",
                "\\\\?\\Volume{e7aaf23a-8560-11db-97d5-806d6172696f}\\"))
        {cout<<"SetVolumeMountPoint status:OK"<<endl;}
        else
        {cout<<"SetVolumeMountPoint status:ERROR"<<endl;ErrorView();}
/////////////////
        cout<<"(PAUSE)Press any key..."<<endl;
        while(!getch());
/////////////////
        if(DeleteVolumeMountPoint("C:\\mnt\\"))
        {cout<<"DeleteVolumeMountPoint status:OK"<<endl;}
        else
        {cout<<"DeleteVolumeMountPoint status:ERROR"<<endl;ErrorView();}
        if(SetVolumeMountPoint("G:\\",
                "\\\\?\\Volume{e7aaf23a-8560-11db-97d5-806d6172696f}\\"))
        {cout<<"SetVolumeMountPoint status:OK"<<endl;}
        else
        {cout<<"SetVolumeMountPoint status:ERROR"<<endl;ErrorView();}
/************************************/
 
        cout<<"Press any key to exit..."<<endl;
        while(!getch());
        return 0;
 
}
 
void ErrorView()
{
        LPVOID lpMsgBuf = NULL;
        FormatMessage
        (FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf, 0, NULL);
        CharToOem((LPTSTR)lpMsgBuf,(LPTSTR)lpMsgBuf);
        cout<<(LPCTSTR)lpMsgBuf<<endl;
        LocalFree(lpMsgBuf);
}

А теперь подробней, по шагам:

HANDLE (WINAPI * FindFirstVolume) (LPTSTR,DWORD);
BOOL   (WINAPI * FindNextVolume) (HANDLE,LPTSTR,DWORD);
BOOL   (WINAPI * FindVolumeClose)(HANDLE);
BOOL   (WINAPI * GetVolumeNameForVolumeMountPoint) (LPCTSTR,LPTSTR,DWORD);
BOOL   (WINAPI * DeleteVolumeMountPoint) (LPCTSTR);
BOOL   (WINAPI * SetVolumeMountPoint) (LPCTSTR,LPCTSTR);

Создаются указатели на прототипы функций для последующей загрузки в них адресов функций.

hmod = LoadLibrary("Kernel32.dll"));

Загружаем необходимую библиотеку.

if(!(FindFirstVolume  = (HANDLE(WINAPI *)
(LPTSTR,DWORD))GetProcAddress(hmod,"FindFirstVolumeA")))
{cout<<"Error GetProcAddress...1"<<endl;return -1;}
if(!(FindNextVolume   = (BOOL(WINAPI *)
(HANDLE,LPTSTR,DWORD))GetProcAddress(hmod,"FindNextVolumeA")))
{cout<<"Error GetProcAddress...2"<<endl;return -1;}
if(!(FindVolumeClose  = (BOOL(WINAPI *)
(HANDLE))GetProcAddress(hmod,"FindVolumeClose")))
{cout<<"Error GetProcAddress...3"<<endl;return -1;}
if(!(GetVolumeNameForVolumeMountPoint  = (BOOL(WINAPI *)
(LPCTSTR,LPTSTR,DWORD))GetProcAddress(hmod,
"GetVolumeNameForVolumeMountPointA")))
{cout<<"Error GetProcAddress...4"<<endl;return -1;}
if(!(DeleteVolumeMountPoint  = (BOOL(WINAPI *)
(LPCTSTR))GetProcAddress(hmod,"DeleteVolumeMountPointA")))
{cout<<"Error GetProcAddress...5"<<endl;return -1;}
if(!(SetVolumeMountPoint  = (BOOL(WINAPI *)
(LPCTSTR,LPCTSTR))GetProcAddress(hmod,"SetVolumeMountPointA")))
{cout<<"Error GetProcAddress...6"<<endl;return -1;}

Далее получаем адреса необходимых нам функций.

hMount = FindFirstVolume(szPath,sizeof(szPath));
UINT uin;
if(hMount!=INVALID_HANDLE_VALUE)
{
        do
        {
                uin = GetDriveType(szPath);
                if(uin==DRIVE_CDROM)      {cout<<"CDROM: ";}
                if(uin==DRIVE_UNKNOWN)    {cout<<"UNKNOWN: ";}
                if(uin==DRIVE_NO_ROOT_DIR){cout<<"NO_ROOT_DIR: ";}
                if(uin==DRIVE_REMOVABLE)  {cout<<"REMOV: ";}
                if(uin==DRIVE_FIXED)      {cout<<"FIXED: ";}
                if(uin==DRIVE_REMOTE)     {cout<<"REMOTE: ";}
                if(uin==DRIVE_RAMDISK)    {cout<<"RAMDISK: ";}
                GetVolumeInformation(szPath, szRecvBuff,
                                                 sizeof(szRecvBuff), NULL,NULL,NULL,
                                                 szFileSystem,sizeof(szFileSystem));
                cout<<"("<<szrecvbuff
                       <<"|"<<szFileSystem
                       <<") "<<szPath<<endl<<endl;  
        
                ZeroMemory(szRecvBuff,sizeof(szRecvBuff));
                ZeroMemory(szFileSystem,sizeof(szFileSystem));
 
        }while(FindNextVolume(hMount,szPath,sizeof(szPath))!=0);
}

Производится поиск томов и вывод информации о них.

ZeroMemory(szRecvBuff,sizeof(szRecvBuff));
char szDrive[4];DWORD dwID = GetLogicalDrives();
for(int i = 0;i < 26;i++)
{
         if(((dwID>>i)&0x00000001)==1)
          {
                 szDrive[0] =  char(65+i);
                 szDrive[1] = ':';
                 szDrive[2] = '\\';
                 szDrive[3] = 0;
                 GetVolumeNameForVolumeMountPoint(szDrive,
                                                      szRecvBuff,
                                                     sizeof(szRecvBuff));
                 cout <<szDrive<<" "<<szRecvBuff<<endl;
 
           }
}

Здесь идет вывод информации вторым способом.

if(DeleteVolumeMountPoint("G:\\"))
{cout<<"DeleteVolumeMountPoint status:OK"<<endl;}
else
{cout<<"DeleteVolumeMountPoint status:ERROR"<<endl;ErrorView();}

Удаление точки монтирования, после выполнения данного участка кода, утилита mountvol покажет вам следующее:
Программно монтируем диски в директорию
Далее устанавливаем новую точку монтирования:

if(SetVolumeMountPoint("C:\\mnt\\",
"\\\\?\\Volume{e7aaf23a-8560-11db-97d5-806d6172696f}\\"))
{cout<<"SetVolumeMountPoint status:OK"<<endl;}
else
{cout<<"SetVolumeMountPoint status:ERROR"<<endl;ErrorView();}

и смотрим результат работы mountvol а также заходим в точку монтирования C:\mnt\ и видим там содержимое жесткого диска:
Программно монтируем диски в директорию
Ну а теперь возвращаем все как было, для этого следующий участок кода:

if(DeleteVolumeMountPoint("C:\\mnt\\"))
{cout<<"DeleteVolumeMountPoint status:OK"<<endl;}
else
{cout<<"DeleteVolumeMountPoint status:ERROR"<<endl;ErrorView();}
if(SetVolumeMountPoint("G:\\",
"\\\\?\\Volume{e7aaf23a-8560-11db-97d5-806d6172696f}\\"))
{cout<<"SetVolumeMountPoint status:OK"<<endl;}
else
{cout<<"SetVolumeMountPoint status:ERROR"<<endl;ErrorView();}

Результат работы программы вы можете видеть на рисунке, в последующем мне хотелось бы создать программу, которая будет для удобства иметь графический интерфейс….
Программно монтируем диски в директорию[/code]