Trouble sending a MAPI message - c++

I am trying to send a message using Extended MAPI, but keep getting an E_ACCESSDENIED error. I am using a C# class which invokes a cpp dll. I am able to check mail and delete messages, but not send. Below is the C# I use to create the message:
using (MAPIMessage message = new MAPIMessage())
{
if (message.Create(this))
{
message.SetSender(send.SenderName, send.SenderAddress);
message.SetSubject(send.Subject);
message.SetBody(send.Message);
message.AddRecipient(send.RecipientAddress);
// High: Add attachments
#if DEBUG
ConfirmMessageCreation(send, message);
#endif
Logger.Log("Message created...\nSending message...", Verbose.LogEverything);
result = message.Send();
}
else
Logger.Log("There was a problem creating the email.", Verbose.LogImportant);
}
The actual cpp that sends the message follows:
BOOL MessageSend(CMAPIMessage* pMessage)
{
return pMessage->Send();
}
...
BOOL CMAPIMessage::Send()
{
HRESULT result = Message()->SubmitMessage(0);
if(Message() && result==S_OK)
{
Close();
return TRUE;
}
return FALSE;
}
Even though I am properly logged in and can check or delete messages, I get an E_ACCESSDENIED error when calling Send(). Any insight into this issue would be greatly appreciated.

The sender related properties need to be removed.

Related

Why I can't receive next messages without deleting previous in SQS queue using c++

I have the following example, where I'm trying to receive messages from SQS queue.
I can successfully get first batch of messages, but after that, the function ReceiveMessage() returns only an empty messages.
If I delete all received messages after every call of ReceiveMessage() I can see next messages.
So I want to know why?
Because as I understand after receiving messages, they are going to in-flight mod,
so when I call ReceiveMessage() again, I should get the next batch of messages without calling delete
Thank You
Aws::Vector<Aws::SQS::Model::Message> receive_message() const
{
Aws::SQS::Model::ReceiveMessageRequest rm_req;
rm_req.SetQueueUrl(queue_url_);
rm_req.SetMaxNumberOfMessages(10);
rm_req.SetWaitTimeSeconds(20);
const Aws::SQS::Model::ReceiveMessageOutcome rm_out = sqs_client_->ReceiveMessage(rm_req);
if (false == rm_out.IsSuccess())
{
throw;
}
Aws::Vector<Aws::SQS::Model::Message> messages = rm_out.GetResult().GetMessages();
return messages;
}
int main()
{
AmazonSQSReceiver sqs_receiver(Global::queue_name);
while (true)
{
Aws::Vector<Aws::SQS::Model::Message> messages = sqs_receiver.receive_message();
for (const auto &message : messages)
{
const Aws::String &message_body = message.GetBody();
std::cout<< message_body << std::endl;
}
}
return 0;
}

Protobuf object's GetTypeName() produces a corrupted string when testing

I am working on a communication framework using Protocol Buffers in C++ and Linux (Ubuntu). My problem is when testing a policy when the state of a node in the system changes: this policy wraps the message into an Any message, and sends it to the wire (I am using 0MQ for the push-pull architecture).
When I run a test the following happens:
I20220420 16:09:58.537735 133589 notification_policies.hpp:157] company.proto.core.RobotState.NodeStatusInfo
I20220420 16:09:58.538447 133589 notification_policies.hpp:157] company.proto.core.RobotState.NodeStatusInfo
I20220420 16:09:59.839386 133589 notification_policies.hpp:157] company.proto.core.RobotState.NodeStatusInfo
I20220420 16:09:59.840803 133589 notification_policies.hpp:157] p^u.V .proto.core.RobotState.NodeStatusInfo
[libprotobuf ERROR google/protobuf/wire_format_lite.cc:581] String field 'google.protobuf.Any.type_url' contains invalid UTF-8 data when serializing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes.
As you can see, the first 3 times I send a NodeStatusInfo message works without any problem, and then I got the error. I am printing the message.GetTypeName(), which after the third time it prints a corrupted string.
Does anyone know what is going on?
The NodeStatusInfo definition is the following:
message StateMessageWrapper {
uint64 stamp = 1;
google.protobuf.Any proto = 2;
}
enum Status {
option allow_alias = true;
UNKNOWN = 0;
....
}
message RobotState {
message NodeStatusInfo {
string name = 1;
Status status = 2;
optional Error error = 3;
};
...
map<string, NodeStatus> nodes_status = 5;
...
};
When I serialize the message, it works as follow:
template<MessageType>
struct PushMessagePolicy {
...
proto::core::StateMessageWrapper envelope_;
...
void
PushMessage(const MessageType& message) override
{
envelope_.Clear();
envelope_.mutable_proto()->PackFrom(message);
LOG(INFO) << message.GetTypeName();
envelope_.set_stamp(
std::chrono::system_clock::now().time_since_epoch().count());
envelope_.set_topic(topic_);
std::string message_str;
CHECK(envelope_.SerializeToString(&message_str)); // The proto error message is printed here.
zmq::message_t msg(message_str);
socket_.send(msg, zmq::send_flags::dontwait);
}
}
THanks in advance!

How to use grpc c++ ClientAsyncReader<Message> for server side streams

I am using a very simple proto where the Message contains only 1 string field. Like so:
service LongLivedConnection {
// Starts a grpc connection
rpc Connect(Connection) returns (stream Message) {}
}
message Connection{
string userId = 1;
}
message Message{
string serverMessage = 1;
}
The use case is that the client should connect to the server, and the server will use this grpc for push messages.
Now, for the client code, assuming that I am already in a worker thread, how do I properly set it up so that I can continuously receive messages that come from server at random times?
void StartConnection(const std::string& user) {
Connection request;
request.set_userId(user);
Message message;
ClientContext context;
stub_->Connect(&context, request, &reply);
// What should I do from now on?
// notify(serverMessage);
}
void notify(std::string message) {
// generate message events and pass to main event loop
}
I figured out how to used the api. Looks like it is pretty flexible, but still a little bit weird given that I typically just expect the async api to receive some kind of lambda callback.
The code below is blocking, you'll have to run this in a different thread so it doesn't block your application.
I believe you can have multiple thread accessing the CompletionQueue, but in my case I just had one single thread handling this grpc connection.
GrpcConnection.h file:
public:
void StartGrpcConnection();
private:
std::shared_ptr<grpc::Channel> m_channel;
std::unique_ptr<grpc::ClientReader<push_notifications::Message>> m_reader;
std::unique_ptr<push_notifications::PushNotificationService::Stub> m_stub;
GrpcConnection.cpp files:
...
void GrpcConnectionService::StartGrpcConnection()
{
m_channel = grpc::CreateChannel("localhost:50051",grpc::InsecureChannelCredentials());
LongLiveConnection::Connect request;
request.set_user_id(12345);
m_stub = LongLiveConnection::LongLiveConnectionService::NewStub(m_channel);
grpc::ClientContext context;
grpc::CompletionQueue cq;
std::unique_ptr<grpc::ClientAsyncReader<LongLiveConnection::Message>> reader =
m_stub->PrepareAsyncConnect(&context, request, &cq);
void* got_tag;
bool ok = false;
LongLiveConnection::Message reply;
reader->StartCall((void*)1);
cq.Next(&got_tag, &ok);
if (ok && got_tag == (void*)1)
{
// startCall() is successful if ok is true, and got_tag is void*1
// start the first read message with a different hardcoded tag
reader->Read(&reply, (void*)2);
while (true)
{
ok = false;
cq.Next(&got_tag, &ok);
if (got_tag == (void*)2)
{
// this is the message from server
std::string body = reply.server_message();
// do whatever you want with body, in my case i push it to my applications' event stream to be processed by other components
// lastly, initialize another read
reader->Read(&reply, (void*)2);
}
else if (got_tag == (void*)3)
{
// if you do something else, such as listening to GRPC channel state change, in your call, you can pass a different hardcoded tag, then, in here, you will be notified when the result is received from that call.
}
}
}
}

Setting Status icon for CFAPI does not work as expected

I try to set the status icon of the placeholder file created with CFAPI to error. (see below)
content of folder T:
I set the error state on the file, but it does not display the error. However the error is displayed on the containing folder.
I use following code to set the error on the file (the complete code is published on github):
void SetTransferStatus(_In_ PCWSTR fullPath, _In_ SYNC_TRANSFER_STATUS status)
{
// Tell the Shell so File Explorer can display the progress bar in its view
try
{
// First, get the Volatile property store for the file. That's where the properties are maintained.
winrt::com_ptr<IShellItem2> shellItem;
winrt::check_hresult(SHCreateItemFromParsingName(fullPath, nullptr, __uuidof(shellItem), shellItem.put_void()));
winrt::com_ptr<IPropertyStore> propStoreVolatile;
winrt::check_hresult(
shellItem->GetPropertyStore(
GETPROPERTYSTOREFLAGS::GPS_READWRITE | GETPROPERTYSTOREFLAGS::GPS_VOLATILEPROPERTIESONLY,
__uuidof(propStoreVolatile),
propStoreVolatile.put_void()));
// Set the sync transfer status accordingly
PROPVARIANT transferStatus;
winrt::check_hresult(
InitPropVariantFromUInt32(
status,
&transferStatus));
winrt::check_hresult(propStoreVolatile->SetValue(PKEY_SyncTransferStatus, transferStatus));
// Without this, all your hard work is wasted.
winrt::check_hresult(propStoreVolatile->Commit());
// Broadcast a notification that something about the file has changed, so that apps
// who subscribe (such as File Explorer) can update their UI to reflect the new progress
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, static_cast<LPCVOID>(fullPath), nullptr);
//wprintf(L"Succesfully Set Transfer Progress on \"%s\" to %llu/%llu\n", fullPath, completed, total);
}
catch (...)
{
// winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
// otherwise the exception will get rethrown and this method will crash out as it should
wprintf(L"Failed to Set Transfer Progress on \"%s\" with %08x\n", fullPath, static_cast<HRESULT>(winrt::to_hresult()));
}
}
In addition, if I delete the file and create a new file the state will still be on error.
Someone pointed me to an pull request in the windows cloud mirror sample that shows how to accomplish this.
This is the code:
void Utilities::UpdateErrorOnItem(PCWSTR path, bool setError)
{
try
{
winrt::com_ptr<IShellItem2> item;
winrt::check_hresult(SHCreateItemFromParsingName(path, nullptr, IID_PPV_ARGS(item.put())));
winrt::com_ptr<IPropertyStore> propertyStore;
winrt::check_hresult(item->GetPropertyStore(GPS_READWRITE | GPS_EXTRINSICPROPERTIESONLY, IID_PPV_ARGS(propertyStore.put())));
PROPVARIANT propVar{};
if (setError)
{
propVar.vt = VT_UI4;
propVar.ulVal = static_cast<unsigned long>(E_FAIL);
winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
}
else
{
// Clear by setting to empty
propVar.vt = VT_EMPTY;
winrt::check_hresult(propertyStore->SetValue(PKEY_LastSyncError, propVar));
}
winrt::check_hresult(propertyStore->Commit());
}
catch (...)
{
// winrt::to_hresult() will eat the exception if it is a result of winrt::check_hresult,
// otherwise the exception will get rethrown and this method will crash out as it should
wprintf(L"Failed to set error state with %08x\n", static_cast<HRESULT>(winrt::to_hresult()));
}

A connection is made between server and client but unable to send data via OutputStream in J2ME

I started to program client/server applications in J2ME recently.Now I'm working with c++ builder 2010 indy components (e.g. TidTTCPServer) and J2ME. My application is designed to restart the kerio winroute firewall service from a remote machine.
My server application is written in c++ builder 2010, I've put a TidTCTServer component into a form which binded to 127.0.0.1:4500. That's listening on port 4500 in local machine.
Then i've added a listbox that i need to add every upcoming packets converted to UnicodeString.
//void __fastcall TForm1::servExecute(TIdContext *AContext)
UnicodeString s;
UnicodeString txt;
txt=Trim(AContext->Connection->IOHandler->ReadLn());
otvet->Items->Add(txt);
otvet->ItemIndex=otvet->Items->Count-1;
if (txt=="1") {
AContext->Connection->IOHandler->WriteLn("Suhrob");
AContext->Connection->Disconnect();
}
if (txt=="2") {
AContext->Connection->IOHandler->WriteLn("Shodi");
AContext->Connection->Disconnect();
}
//----------------------------------------------------------------------------
// void __fastcall TForm1::servConnect(TIdContext *AContext)
++counter;
status->Panels->Items[0]->Text="Connections:" + IntToStr(counter);
status->Panels->Items[1]->Text="Connected to " + AContext->Connection->Socket->Binding->PeerIP + ":" + AContext->Connection->Socket->Binding->PeerPort;
and my client side code looks smth like this:
else if (command == send) {
// write pre-action user code here
InputStream is=null;
OutputStream os=null;
SocketConnection client=null;
ServerSocketConnection server=null;
try {
server = (ServerSocketConnection) Connector.open("socket://"+IP.getString()+":"+PORT.getString());
// wait for a connection
client = (SocketConnection) Connector.open("socket://"+IP.getString()+":"+PORT.getString());
// set application-specific options on the socket. Call setSocketOption to set other options
client.setSocketOption(SocketConnection.DELAY, 0);
client.setSocketOption(SocketConnection.KEEPALIVE, 0);
is = client.openInputStream();
os = client.openOutputStream();
// send something to server
os.write("texttosend".getBytes());
// read server response
int c = 0;
while((c = is.read()) != -1) {
// do something with the response
System.out.println((char)c);
}
// close streams and connection
}
catch( ConnectionNotFoundException error )
{
Alert alert = new Alert(
"Error", "Not responding!", null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
switchDisplayable(alert, list);
}
catch (IOException e)
{
Alert alert = new Alert("ERror", e.toString(), null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
switchDisplayable(alert, list);
e.printStackTrace();
}
finally {
if (is != null) {
try {
is.close();
} catch (Exception ex) {
System.out.println("Failed to close is!");
}
try {
os.close();
} catch (Exception ex) {
System.out.println("Failed to close os!");
}
}
if (server != null) {
try {
server.close();
} catch (Exception ex) {
System.out.println("Failed to close server!");
}
}
if (client != null) {
try {
client.close();
} catch (Exception ex) {
System.out.println("Failed to close client!");
}
}
}
my client application gets connected with the server but when i try to send data such as
os.write("texttosend".getBytes());
I cannot get text data on the server using. That's I am not getting sent packets in the server from client.
txt=Trim(AContext->Connection->IOHandler->ReadLn());
Guys, where am I wrong? is the way i'm doing is ok?
Or do I need to use StreamConnection instead of SocketConnection?
And when i use telnet to send data it works cool, strings will be added to listbox
telnet 127.0.0.1 4500
texttosend
23
asf
Any help is appreciated !!!
Thanks in advance!
The main problem is that you are using ReadLn() on the server end. ReadLn() does not exit until a data terminator is encountered (a LF line break character is the default terminator) or if a reading timeout occurs (Indy uses infinite timeouts by default). Your J2ME code is not sending any data terminator, so there is nothing to tell ReadLn() when to stop reading. The reason it works with Telnet is because it does send line break characters.
The other problem with your code is that TIdTCPServer is a multi-threaded component, but your code is updating the UI components in a thread-unsafe manner. You MUST synchronize with the main thread, such as by using Indy's TIdSync and/or TIdNotify classes, in order to update your UI safely from inside of the server's event handlers.
Yes, flush method is necessary to call after sending bytes, but ..... finally....
then i tried to include my connection code in a new thread that implements Runnable worked perfectly. Now I've found where I was wrong!!!!!!!!!!!!!!
That's guys you need to include above code in the following block.
Thread t= new Thread(this);
t.start();
public void run()
{
//here paste the code
}
Try OutputStream.flush()?
If not, try writing to a known working server, instead of one you've created yourself (something like writing "HELO" to an SMTP server), this will help you figure out which end the error is at.