C++ SMTP that allows file attachments - c++

I am looking to create an SMTP that allows for file attachments, however, I am finding it difficult to locate a tutorial. I have found one close thing, which is https://stackoverflow.com/questions/58210/c-smtp-example , however, this fails to compile in VS2005/2010 because of the include files that are used.
I would like to roll my own and not adapt to some library such as Curl or Boost. Does anyone have any suggestions on how to do this, or some small sample code with good documentation that will compile in Visual Studio?

Building on my answer to a previous question, using the Microsoft ATL classes which are included in the paid versions of Visual Studio.
CSMTPConnection smtp;
if (!smtp.Connect(m_strEmailServer))
return false;
// start generating the email message; remember to call CoInitialize somewhere in the app before this
CMimeMessage msg;
msg.SetSubject(m_strSubject);
msg.SetSender(m_strSender);
// repeat the following as necessary
msg.AddRecipient(strSingleRecipient);
msg.AddText(m_strBody);
// add an attachment
msg.AttachFile(m_strAttachmentPath, m_strAttachmentName, _T("application/octet-stream"));
if (!smtp.SendMessage(msg))
return false;
return true;
The MIME type supplied in the AttachFile call will depend on the type of attachment.

There are a couple of ways to do attachments. You can use UUEncoded or MIME formatting. The UUEncoded is much simpler if you want to roll your own.

Related

C++ generate new EC_KEY using OpenSSL 1.1.1n

I'm very new to this OpenSSL stuff and trying to learn my way through it. I want to generate an ec key but its keep failing to generate. I'm currently using OpenSSL 1.1.1n and here's a snippet based on understaning of EC_Key through documentation and from other people's example online:
EC_KEY* key = EC_KEY_new_by_curve_name(NID_secp521r1);
if (!key)
{
ERROR
}
EC_GROUP* ecgroup = EC_GROUP_new_by_curve_name(NID_secp521r1);
if (ecgroup)
{
printf("ECGROUP IS NOT NULL!\n");
if (EC_KEY_set_group(key, ecgroup) != 1)
{
ERROR
}
}
if (EC_KEY_generate_key(key) != 1) //<-- fails at this function
{
ERROR
}
Maybe this piece of code is from an older version of OpenSSL but I don't see that function being mentioned in a change log. Any help would be really appreciated! Thanks in advance!
Edit:
Thanks for Jakob's answer I was able to get some more information about the failure by using ERR_get_error() function. The error I see now is
error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy
The manual states:
EC_KEY_generate_key() generates a new public and private key for the
supplied eckey object. eckey must have an EC_GROUP object associated
with it before calling this function. [...]
Did you associate an EC_GROUP with the key before calling the function? There is a function called EC_KEY_set_group() which can be used to add a group object. Such an object can be created with the EC_GROUP_new().
By the way is there a reason, why you are still using OpenSSL 1.1.1. I would recommend using the latest version of the library OpenSSL 3.0. Even if you only want to learn stuff, it is probably more useful, if you immediately learn the newer version.
Edit
I do not know, what is behind your ERROR macro, but it might be a good idea to learn the OpenSSL error handling system. There are functions like ERR_print_errors() that maybe could have given you a hint about what was going wrong.
Answering myself in case someone is having this same issue.
I was able to get around this problem by building OpenSSl with no-shared flag. I'm not sure how that is affecting the lib in getting an entropy but that's the parameter that made the EC_KEY_generate_key() work.
Here's my working configuration command:
perl Configure no-shared VC-WIN32

Can't find COM object from C++, although Guid it's registered

First of all happy new year to everyone, hope you're doing well!
I'm working on a C++ project in which I need to call a C# DLL I created following the first answer of this post. Once I have the DLL, I need to call it from Qt, so by using dumpcpp and the .tlb file generated by regasm, I managed to get the .cpp and .h files to use my classes. Just as a reference, the namespace of the classes is Wrapper, and the main class is Device with guid {DD4A4896-C105-4C60-839B-B18C99C8FE15}.
Once I have the generated files to use the DLL, if I try to create a Wrapper:: Device instance on Qt, I get the following error:
QAxBase::setControl: requested control {dd4a4896-c105-4c60-839b-b18c99c8fe15} could not be instantiated
QAxBase::qt_metacall: Object is not initialized, or initialization failed
It doesn't give any more information, so I tried to check if the guid was stored on the system registry (I used the regasm command explained on the previously quoted post, and It said that it was successful, but you never know). Opening Registry editor and searching for the Guid revealed that it's present at: Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{DD4A4896-C105-4C60-839B-B18C99C8FE15}, which, as far as I know, is the right route for these guids, and it points to the right DLL.
I though It may be due to some kind ActiveQt problem, and as the previously quoted post explained how to use that DLL from VS C++, I decided to give it a try, using this as an another reference. I've finished with this code, which is supposed to create an instance of my Device object
#include <iostream>
#include <atlstr.h>
#import "C:\Users\javie\Documents\Wrapper\Wrapper\bin\x86\Release\netstandard2.0\Wrapper.tlb" named_guids raw_interfaces_only
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
int main()
{
try
{
TESTHR(CoInitialize(0));
Wrapper::IDevicePtr devPtr = nullptr;
TESTHR(devPtr.CreateInstance("{DD4A4896-C105-4c60-839B-B18C99C8FE15}"));
}
catch (const _com_error& e)
{
CStringW out;
out.Format(L"Exception occurred. HR = %lx, error = %s", e.Error(), e.ErrorMessage());
MessageBoxW(NULL, out, L"Error", MB_OK);
}
CoUninitialize();// Uninitialize COM
std::cout << "Hello World!\n";
}
However, this doesn't work either, the createInstance method throws an exception of Class not registered and HR=80040154. Again, according to Registry editor, the class is registered, so I don't understand the error. I've also tried with devPtr.CreateInstance("Wrapper.Device"), devPtr.CreateInstance("Wrapper::Device") or `devPtr.CreateInstance("Wrapper::CLSID_Device") as the links I posted suggest, but in those cases I get another exception with HR=800401f3 and message Invalid class string.
It doesn't matter whether VS or Qt Creator are opened as administrator or not, I get the exact same error.
I have run out of ideas, and I really need to be able to use that DLL from Qt using the files generated by dumpcpp.
Does any one know what could be happening? It feels quite strange to me.
If your C++ application is 64-bit, that's the answer right there, because your C# component is 32-bit (or MSIL but registered to the 32-bit hive). In situations like these, a simple test using VBScript is always useful.
Write a simple VB Script (test.vbs)
Dim obj
Set obj = CreateObject("Wrapper.Device") ' or whatever your ProgID is
MsgBox TypeName(obj)
Now, run this macro 2 ways: with 32-bit and 64-bit versions of VBScript:
32-bit > c:\windows\SysWow64\cscript.exe test.vbs
64-bit > c:\windows\system32\cscript.exe test.vbs
This is assuming your C# component is dispatch compatible. If it's not, then it will still give you differing results that you can use to debug.
Assuming automation/IDispatch compatible, one will work and one won't if you have registered your component correctly.
Have you registered correctly? When I use regasm, I always use the the switches /tlb /codebase when registering the C# component for COM.
Ok, in case someone find the same error, I'll explain the solution I found.
The problem was that in my case, the C# class I developed depended on another 32 bits dll which was not registered on my PC. Once I registered the other dll, everything worked fine.
I don't know why VS kept telling me that the class was not registered when my class itselft was registered, it was one of its dependencies that wasn't registered.
Anyway, I discovered this thanks to Joseph's comments, so thanks a lot for your help.

Alternative of CreateVideoSource() in webrtc

Hi all I had seen one webrtc old source code which has this method called CreateVideoSource() for adding streams after an CreateAudioTrack() call.
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> video_source =
peer_connection_factory_->CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(
media_source->GetVideoCapturer()),
NULL);
What's happening is whenever I try to build it gives an error for the above CreateVideoSource() that it is undefined. And the reason behind that is the latest webrtc-checkout has deprecated this.
So my question is, I wanted to know the alternative which they have introduced after deprecating this method. So can anyone tell me what the alternate approach is.
Okay, Finally I was able to come up with an alternative(i.e the current implementation of libwebrtc) after looking into bundle examples and tests.
Line 71 is a good point to start

Writing namespace extensions with Windows 7 integration

I'm new to the topic shell extensions and I'm looking for resources about namespace extensions. I would like to write a namespace extension which supports SFTP with all options to browse like FTP in the explorer.
I read the examples 1, 2 of zengxi from codeproject, but they don't compile right and seems to be old. I think that there were also many changes like the folder selection in the address bar.
Can somebody provide me some resources in the right direction or some working examples?
UPDATE:
It is important that the source is free. This is a non-profit project.
At the moment I found a good source on the MSDN called Explorer Data Provider Sample. This is up to date and provides some aliases Explorer Data Provider and Shell Data Source. What is yet missing is drop & drag support and a glue for supporting protocol links.
For future usage it would be great to find a way to associate a file extension with that shell data source like zip files.
Here is the full example of creating a namespace to mapping real files on Flickr.
However, only source codes available. No tutorial.
Hope it helps....
http://www.viksoe.dk/code/flickrdrive.htm
For Drag&Drop, this series of articles are a great point to start. After I understood that the files must have the flag can copy, can move, etc. I had almost the solution. The magic was to add one line in GetAttributesOf:
*rgfInOut |= SFGAO_CANCOPY|SFGAO_CANMOVE;
Also I had to publish the IDataObject in GetUIObjectOf like this:
if(riid == IID_IDataObject) {
PWSTR pszName;
hr = _GetName(apidl[0], &pszName);
hr = SHCreateDataObject(m_pidl, cidl, apidl,
new CFileDataObject(pszName), riid, ppv);
} else if(riid == IID_IDropTarget) {
// TODO publish
return E_NOINTERFACE;
}
That's all.
By the way what is the best practice for allocating CFileDataObject here?
Take a look at the EZNamespaceExtensionsMFC library which makes it very easy to develop namespace extensions. Check out its FileBrowser and RegBrowser samples which you can use a starting point.
DISCLAIMER: I work for LogicNP Software, the developer of EZNamespaceExtensionsMFC

C++, OLE, Excel Automation: EAccessviolation at 00000800

I am writing an background service application that has to automatically read data from Excel 2003 files. But no matter what I try, the method OlePropertyGet() always results in an EAccessViolation error while trying to read from address "00000800".
The error always occurs at the last line of this code snippet, and seems independent of what parameter the method receives:
Variant excel, workbooks;
try
{
excel = GetActiveOleObject("Excel.Application");
}
catch(...)
{
excel = CreateOleObject("Excel.Application");
}
workbooks = excel.OlePropertyGet("Workbooks");
I've done some extensive google search on this, but found nothing that's even remotely helpful, only this forum thread where someone has the same issue, but doesn't give any information about the cause or solution (it's somewhat funny that at one point the author mentions he knows the cause, but doesn't say what it is!).
I'm open to any ideas as to what is causing this and how to solve this problem, but also alternative approaches to Excel OLE automation.
My guess is its a null pointer issue..
It looks like neither GetActiveOleObject() nor CreateOleObject() worked.
Try checkign the validity of 'excel' before calling OlePropertyGet.
And I guess you should make sure you have Excel installed.
You can use Visual Studio Tools for Office (see http://msdn.microsoft.com/en-us/library/d2tx7z6d.aspx).
Or you can use ATL support to instantiate the object model provided by office.
Your code may not be able to resolve "Excel.Application" successfully, leading to a null pointer. It uses a registry lookup with that string to identify Excel. It sounds like you're missing that registry entry.
I use such code to determine validity of created objects(in C++ Builder):
Varaint excel = GetActiveOleObject("Excel.Application");
TAutoDriver<IDispatch> dispatcher;
dispatcher.Bind(excel, false);
if (dispatcher.IsBound())
{
Variant workbooks = excel.OlePropertyGet("Workbooks");
}