====== Biblioteki DLL ====== ===== Zadanie 1 ===== - Utwórz bibliotekę DLL eksportującą przynajmniej jedną funkcję i jedną zmienną: * utwórz pusty projekt biblioteki DLL w Visual Studio * wyeksportuj z utworzonej biblioteki funkcję o nazwie ''Komunikat'', która wyświetla okno MessageBox z zadanym w argumencie komunikatem, \\ void Komunikat(TCHAR *tekst); * wyeksportuj z biblioteki zmienną całkowitą o wartości początkowej 42 * do eksportowania wykorzystaj modyfikator: \\ __declspec(dllexport) \\ Kompilator C%%++%% "magluje" nazwy funkcji. Aby temu zapobiec można zadeklarować funkcje oraz zmienne eskortowane z biblioteki za pomocą exterm "C" {...} * korzystając z narzędzia [[https://msdn.microsoft.com/en-us/library/c1h23y6c.aspx|DumpBin.exe]] zobacz listę eksportowanych (oraz importowanych) funkcji oraz zmiennych z utworzonego pliku ''.dll'' oraz ''.lib''. \\ DumpBin.exe /EXPORTS plik.dll DumpBin.exe /IMPORTS plik.dll \\ Narzędzie ''DumpBin'' dostarczane jest w ramach ''Common Tools for Visual C++'' i jeżeli jest zainstalowane to można go używać w linii komend ''Developer Command Prompt'' z Menu Start * dodatkowo: wyeksportuj klasę o nazwie ''MojaKlasa'' zawierającą metodę publiczną ''Komunikat'' działającą identycznie jak powyższa funkcja. - Utwórz w ramach tego samego rozwiązania nowy projekt i zlinkuj bibliotekę statycznie (niejawnie). Przetestuj działanie dostępnych w bibliotece funkcji, zmiennych i klas. \\ * dodaj do projektu odpowiednio przygotowany plik nagłówkowy biblioteki i wskaż linkierowi lokalizację plików lib i dll. * do importowania funkcji i zmiennych z biblioteki wykorzystaj modyfikator: \\ __declspec(dllimport). Spróbuj tak przygotować plik nagłówkowy aby mógł być współdzielony zarówno przy budowaniu biblioteki DLL jak i przy budowaniu projektu aplikacji wykorzystującej tą bibliotekę. * korzystając z DumpBin.exe zobacz listę eksportowanych (oraz importowanych) funkcji i zmiennych z utworzonego pliku ''.exe'' * dodaj do biblioteki DLL funkcję [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs.85%29.aspx|DllMain]]. Wyświetl komunikaty (MessageBox) informujące o tym jaki był powód uruchomienia tej funkcji (np. ''DLL_PROCESS_ATTACH'') * utwórz dodatkowy wątek tak aby wywołać w bibliotece DLL funkcję DllMain z ''DLL_THREAD_ATTACH'' - Utwórz w ramach tego samego rozwiązania nowy projekt i zlinkuj bibliotekę dynamicznie (jawnie) w czasie działania programu. Przetestuj działanie dostępnych w bibliotece funkcji, zmiennych i klas. * korzystając z DumpBin.exe zobacz listę eksportowanych (oraz importowanych) funkcji z utworzonego pliku ''.exe'' * wyświetl pełną ścieżkę i nazwę wczytanej biblioteki, * przydatne funkcje: * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx|LoadLibrary]] wczytuje moduł do pamięci wirtualnej procesu * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx|GetProcAddress]] uzyskuje adres importowanej funkcji * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152%28v=vs.85%29.aspx|FreeLibrary]] zwalnia zasoby biblioteki DLL * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197%28v=vs.85%29.aspx|GetModuleFileName]] * [[https://msdn.microsoft.com/en-us/library/windows/desktop/hh310513%28v=vs.85%29.aspx|AddDllDirectory]] - Umieść w bibliotece DLL następujące zasoby: dowolny napis, dowolne menu * wczytaj z biblioteki zapisane zasoby. Wczytany tekst wyświetl a menu załaduj jako menu kontekstowe (aktywowane prawym klawiszem myszy w oknie) * przydatne funkcje: * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms647486%28v=vs.85%29.aspx|LoadString]] * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms647990%28v=vs.85%29.aspx|LoadMenu]] * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms648002%28v=vs.85%29.aspx|TrackPopupMenu]] * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms647984%28v=vs.85%29.aspx|GetSubMenu]] * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms648390%28v=vs.85%29.aspx|GetCursorPos]] ===== Zadanie 2 ===== Utwórz program zakładający hak przechwytujący globalnie próbę zamknięcia dowolnego okna za pomocą skrótu klawiszowego ''Alt+F4''. W tym celu wykonaj następujące kroki: - Utwórz bibliotekę DLL eksportującą funkcje zakładające i zdejmujące hak typy [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx#wh_keyboardhook|WH_KEYBORD]] - Zaimplementuj procedurę haka [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx|KeyboardProc]] wychwytującą wciśnięcie klawisza F4 (VK_F4) i jednoczesne wciśnięcie lewego klawisza Alt (29 bit argumentu ''lParam'') - Utwórz program, który ładuje dynamicznie bibliotekę DLL i uruchamia funcję zakładającą hak globalny. Zadbaj o to, aby przy zamykaniu aplikacji hak został zdjęty. **Przydatne funkcje:** * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx|SetWindowsHookEx]] - instaluje hak \\ HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId); * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx|UnhookWindowsHookEx]] - usuwa hak BOOLUnhookWindowsHookEx(HHOOK hhk); * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644984%28v=vs.85%29.aspx|KeyboardProc callback function]] \\ LRESULT KeyboardProc(int code, WPARAM wParam, LPARAM lParam); * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx|CallNextHookEx]] - przesyła informacje do kolejnego haka w kolejce \\ LRESULT CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);