DLL import failure in using WinDivert - c++-cli

I am going to design a program using WinDivert to manipulate the network traffic.
The language I use is C++ and the program is designed under Visual Studio 2008.
Firstly I create a project in visual C++ CLR (Windows Forms Application) so I can implement the UI simply.
For importing the WinDirvert Library, I have done the following setting in project properties:
Configuaration Properties: General
Common Language Runtime support: Common Language Runtime Support(/ctr)
Configuaration Properties: Linker
Additional Dependencies: link of WinDivert.lib
Module Definition File: link of windivert.def
Within the project I have created, I also added the windivert.h in the header files.
Also, windivert.h is included in the main entry point of my project (ProjectG.cpp):
#include "stdafx.h"
#include "Form1.h"
#pragma managed(push, off)
#include "windivert.h"
#pragma managed(pop)
using namespace ProjectG;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
HANDLE handle;
unsigned char packet[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
handle = WinDivertOpen("udp", WINDIVERT_LAYER_NETWORK, 0,
WINDIVERT_FLAG_DROP);
if (handle == INVALID_HANDLE_VALUE)
{
Application::Exit();
}
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
MessageBox::Show("Fail");
continue;
}
}
return 0;
}
Finally, I put the {WinDivert.dll, windivert.h, WinDivert.lib, WinDivert32.sys} under the project directory.
However, the following error is shown:
fatal error LNK1306: DLL entry point "int __clrcall main(cli::array<class
System::String ^ >^)" (?main##$$HYMHP$01AP$AAVString#System###Z) cannot be managed;
compile to native ProjectG.obj ProjectG
Additional: (a warning)
warning LNK4070: /OUT:WinDivert.dll directive in .EXP differs from output filename
'C:\Users\David\Desktop\css\ProjectG\Debug\ProjectG.exe'; ignoring directive
ProjectG.exp ProjectG
Question:
How can I resolve this situation?

a) your main source is .cpp, so you can delete [STAThreadAttribute] and change
int main(array<System::String ^> ^args) to int _tmain(int argc, _TCHAR* argv[])
b) exclude windivert.def from linker Module Definition File, this only when you are creating a DLL
c) the DLL/SYS files would need to be copied to the Debug and Release folders

Related

How to call upon a .dll file from C++ and extract the functions of it?

I would like to know the proper procedure for calling a .dll file with also having a .cpp and .h files for a certain application. I have a program which is the .cpp file with different .h header files and I also included the .dll file into the folder where the .cpp and .h files are located. I would like to know in the .cpp code how am I able to call upon this .dll file since inside of it there are different functions that will allow a DDC264 Evaluation Board to read data from memory through usb and extract the data. I am using a program called DevC++ and I am receiving a current Error which is [Id] returned 1 exit status and MakefileWin has changed.
Attached below is a snippit of the .cpp code:
I also would like to know how to fix both of these errors .enter image description hereenter image description here
// USB_IO_for_VB6.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "USB_IO_For_VB6.h"
#include "CyAPI.h"
#include <cstring>
#include <malloc.h>
#include "BASETSD.H"
#include <math.h>
#include <stdio.h>
// #include <string.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
//int USB_IO_FOR_VB6_EXPORTS int USB_IO_for_VB6_API =22;
I
USB_IO_FOR_VB6_API int nUSB_IO_for_VB6 = 22;
#define STRINGLEN 65536 //the larger this number is, the faster the data is shifted in.
#define MAX_CHANNELS_FAST 4096 // 2048= 1024A + 1024B
#define DBP 0 //debug print - 1 enables writing some information to a file in "C:\temp\"
// This function reads the device descriptors from the Cypress USB Chip(s).
// It returns arrays of values, one set of values per device detected.
// The user can then use the visual basic software to select which device to use.
int __stdcall ReadDeviceDescriptors(int *USBdevCount, int *bLengthPass, int *bDescriptorTypePass,
long *bcdUSBPass, int *bDeviceClassPass, int *bDeviceSubClassPass,
int *bDeviceProtocolPass, int *bMaxPacketSize0Pass, long *idVendorPass,
long *idProductPass, long *bcdDevicePass, int *iManufacturerPass,
int *iProductPass, int *iSerialNumberPass, int *bNumConfigurationsPass)
{
CCyUSBDevice *USBDevice;
USB_DEVICE_DESCRIPTOR descr;
USBDevice = new CCyUSBDevice(NULL); // Create an instance of CCyUSBDevice
USBdevCount[0] = USBDevice->DeviceCount();
for (int i=0; i < USBDevice->DeviceCount(); i++)
{
if (USBDevice->Open(i))
{
USBDevice->GetDeviceDescriptor(&descr);
bLengthPass[i]=descr.bLength;
bDescriptorTypePass[i]=descr.bDescriptorType;
bcdUSBPass[i]=descr.bcdUSB;
bDeviceClassPass[i]=descr.bDeviceClass;
bDeviceSubClassPass[i]=descr.bDeviceSubClass;
bDeviceProtocolPass[i]=descr.bDeviceProtocol;
bMaxPacketSize0Pass[i]=descr.bMaxPacketSize0;
idVendorPass[i]=descr.idVendor;
idProductPass[i]=descr.idProduct;
bcdDevicePass[i]=descr.bcdDevice;
iManufacturerPass[i]=descr.iManufacturer;
iProductPass[i]=descr.iProduct;
iSerialNumberPass[i]=descr.iSerialNumber;
bNumConfigurationsPass[i]=descr.bNumConfigurations;
USBDevice->Close();
}
}
return( USBdevCount[0] );
}
I am not sure about how to go about calling a .dll file in C++, I am fairly new to Object Oriented programming.
Regarding the MakefileWin error I tried changing the TDM-GCC release version from 32 to 64 bits and the error continues.
I also tried deleting the dllmain.cpp which is another cpp file that is not needed and moving another original.cpp file from the folder that is shown in one of the images.
I only have a single .cpp file running on my DevC++ compiler which I thought would not cause the Error [Id] returned 1 to exit status to pop up.

Boost asio crashes

I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?
I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.

How to enumerate folder contents in Oct 2018

Trying to translate to cppwinrt the StorageFolder method GetFilesAsync I'm unable to get past compiler link errors. Here is a very simple routine to test the concept:
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Foundation.Collections.h"
IAsyncAction TestClass::LoadFiles()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(hstring(L"Assets"));
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
The problem seems to lie in the return type for GetFilesAsync. I've tried various types for that, e.g. IVectorView, but nothing seems to work. Does anyone know of a code example showing how this enumeration might be accomplished in C++/winrt?
[UPDATE] Returning to this project with SDK 10.0.17666 and VS 15.9.0 Preview 3 I find that the solution adopted earlier from these answers no longer works. This time I will be sure to include the full error to see if anyone has ideas. For simplicity I'll use just the simple code provided by IInspectable, altered only to make it a class member in my ResourceManager class:
#include "winrt/Windows.ApplicationModel.h"
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Storage.Search.h"
#include "winrt/Windows.UI.Core.h"
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;
IAsyncAction ResourceManager::LoadActivities()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Activities");
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
The call to GetFilesAsync now produces the following link error:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: struct winrt::Windows::Foundation::IAsyncOperation > __thiscall winrt::impl::consume_Windows_Storage_Search_IStorageFolderQueryOperations::GetFilesAsync(enum winrt::Windows::Storage::Search::CommonFileQuery const &)const " (?GetFilesAsync#?$consume_Windows_Storage_Search_IStorageFolderQueryOperations#UStorageFolder#Storage#Windows#winrt###impl#winrt##QBE?AU?$IAsyncOperation#U?$IVectorView#UStorageFile#Storage#Windows#winrt###Collections#Foundation#Windows#winrt###Foundation#Windows#3#ABW4CommonFileQuery#Search#Storage#63##Z) referenced in function "public: struct winrt::Windows::Foundation::IAsyncAction __thiscall AppEngine::ResourceManager::LoadActivities$_ResumeCoro$2(void)" (?LoadActivities$_ResumeCoro$2#ResourceManager#AppEngine##QAE?AUIAsyncAction#Foundation#Windows#winrt##XZ)
(followed by the path to the object file)
I have to admit I find that error message hard to decipher. Perhaps someone else here will have an idea? Must be something that changed in recent system updates.
For what it's worth, the following standalone code builds just fine. So you're probably either missing a #include or a link library, but it's impossible to tell when you don't share important information like what actual error(s) you're seeing.
#pragma comment(lib, "WindowsApp")
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Search.h>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Search;
IAsyncAction LoadFiles()
{
StorageFolder appFolder = Windows::ApplicationModel::Package::Current().InstalledLocation();
StorageFolder assetsFolder = co_await appFolder.GetFolderAsync(L"Assets");
auto files = co_await assetsFolder.GetFilesAsync(CommonFileQuery::DefaultQuery);
}
int main()
{
LoadFiles().get();
}

Add Forms from another project in Borland C++

I'm currently working on a project using Borland C++, I have two Forms so far but each one in an independent Project, I wish to join these two project into one project so I can switch between the Forms.
I want to have only one executable file (for security purposes), I tried reading some pdfs about borland c++, also tried googling it, but no luck.
if there's a way to do so, I wish you could guide me or give me some hints.
Note: I'm using Borland C++ Builder 6, under Windows 8.1.
I am used to BDS2006 so for newer IDE/Compilers it can be different
1.form copy
has .h,.cpp,*.dfm files
copy them to target project directory
2.open target project in IDE
3.add forms to project
find add to project in IDE main menu (I think it is in Project tag)
then select *.dfm files of your new forms click add or OK ...
4.Open target project source code (*.cpp)
should look like this:
//$$---- EXE CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
//*** here you have line for each form type and its name in forms menu
USEFORM("win_view.cpp", win_view);
USEFORM("win_main.cpp", win_main);
USEFORM("win_editor\win_editor_setup.cpp", win_EditorSetup);
USEFORM("win_editor\win_editor.cpp", win_editor);
USEFORM("win_editor\win_editor_find.cpp", win_EditorFind);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
//*** here create form for each static form you want
//*** dynamic windows (created in runtime are not here !!!
Application->CreateForm(__classid(Twin_main), &win_main);
//*** here load cross references to forms if needed
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
5.dynamic forms
add #include of *.h for all dynamic/used inside form files to main form cpp file
this makes them accessible from main form
now you can crete / destroy windows
should look like this:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "win_main.h"
//*** add the dynamic/used forms *.h files
#include "win_view.h"
#include "win_editor\win_editor.h"
//---------------------------------------------------------------------------
//*** add pointer to dynamic forms
Twin_view *win_view=NULL;
//---------------------------------------------------------------------------
void __fastcall Twin_main::some_event(...)
{
win_view=new Twin_view(win_main);
if (win_view)
{
win_view->OnResize(win_view);
win_view->_can_close=false;
}
}
//---------------------------------------------------------------------------
void __fastcall Twin_main::FormDestroy(TObject *Sender)
{
//*** destroy form before exiting also can call ->Close() and wait few [ms] before
if (win_view) { delete win_view; win_view=NULL; }
}
//-------------------------------------------------------------------
you can also move the form pointers to owner form class to make it more objective c++ like
and allow to make multiple originaly main forms in future (in another project later)
6.static used forms
just include *.cpp file instead of *.h
the pointer to these forms are directly in *.cpp files (at the start)
[notes]
if your forms have some global variables
then you can not use more then 1 form of that type
also the global variable names have to be different between used forms
do not change namespace for them it will make VCL crazy

How to make a loadable dll to use tcl code functionality by any program

I have created a GUI using tcl. I want to make some of the core functionalities of the tcl code available to be used by any program which supports dll. For that i have taken a very simple tcl code example, which adds two integer numbers and i have written a c wrapper function to use this functionality. This is working for me. Now how can i create a dll for these two c and tcl files, so that any program can use this addition functionality by simply loading the dll.
Here is my simple tcl code :
/* Filename : simple_addition.tcl */
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is my c wrapper function which uses the above tcl addition functionality :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
This c wrapper is working fine for me and gives correct results.
Now I want to create a dll file, so that if i include that dll to any program that supports dll, it should be able to use this addition functionality of the above tcl code. Can anybody please tell me the way i can do it. Please help me. I am new to this dll concept.
In order to create the .dll you'll have to use something like Visual Studio and C or C++ to create the .dll (there are lots of other tools out there that can create .dll files but VS is easy to get hold of and to use.) So in VS create a new project, this needs to be a C++ WIN32 project. Select the DLL application type and the Export Symbols additional option.
VS will create a basic .dll that you can then amend to do what you want. I short I'd look at putting the creating/destruction of the intrepter into the dllmain:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
Tcl_DeleteInterp(interp);
break;
}
}
return TRUE;
}
and then create functions exported by the .dll that make use of the interpreter. If you aren't familiar with the concept of shared libaries then I'd suggest spending a little time reading up on them, try here and here for some background reading.