Add external API with WindowMessages
authorAndre Heinecke <aheinecke@intevation.de>
Thu, 8 Nov 2018 12:13:06 +0000 (13:13 +0100)
committerAndre Heinecke <aheinecke@intevation.de>
Thu, 8 Nov 2018 12:15:08 +0000 (13:15 +0100)
* src/windowmessages.cpp: Handle new messages.
* src/windowmessagees.h: Add new codes.
* tests/Makefile.am: Update accordingly.
* tests/run-messenger.cpp: New.

--
The run-messenger can be used as an example how to use
this API. As we block saves while decrypted data is open
we add API to close the mails now. Either all or a specific
uuid.

e.g.:

run-messenger.exe 1301 1147d7ed-22fb-48d2-8678-a814df5009eb

GnuPG-Bug-Id: T4241

src/windowmessages.cpp
src/windowmessages.h
tests/Makefile.am
tests/run-messenger.cpp [new file with mode: 0644]

index e269d0a..da73117 100644 (file)
@@ -43,6 +43,13 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
   if (message == WM_USER + 42)
     {
       TSTART;
+
+      if (!lParam)
+        {
+          log_error ("%s:%s: Recieved user msg without lparam",
+                     SRCNAME, __func__);
+          TRETURN DefWindowProc(hWnd, message, wParam, lParam);
+        }
       wm_ctx_t *ctx = (wm_ctx_t *) lParam;
       log_debug ("%s:%s: Recieved user msg: %i",
                  SRCNAME, __func__, ctx->wmsg_type);
@@ -283,6 +290,58 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
         TRETURN 0;
     }
+  else if (message == WM_USER + 43)
+    {
+      switch (wParam)
+        {
+          case (EXT_API_CLOSE_ALL):
+            {
+              log_debug ("%s:%s: Closing all mails.",
+                         SRCNAME, __func__);
+              Mail::closeAllMails_o ();
+              TRETURN 0;
+            }
+          default:
+            log_debug ("%s:%s: Unknown external msg %i",
+                       SRCNAME, __func__, wParam);
+        }
+    }
+  else if (message == WM_COPYDATA)
+    {
+      log_debug ("%s:%s Received copydata message.",
+                 SRCNAME, __func__);
+      if (!lParam)
+        {
+          STRANGEPOINT;
+          TRETURN DefWindowProc(hWnd, message, wParam, lParam);
+        }
+      const COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
+
+      if (cds->dwData == EXT_API_CLOSE)
+        {
+          log_debug ("%s:%s CopyData with external close. Payload: %.*s",
+                     SRCNAME, __func__, (int)cds->cbData, (char *) cds->lpData);
+
+          std::string uid ((char*) cds->lpData, cds->cbData);
+          auto mail = Mail::getMailForUUID (uid.c_str ());
+          if (!mail)
+            {
+              log_error ("%s:%s Failed to find mail for: %s",
+                         SRCNAME, __func__, uid.c_str() );
+              TRETURN DefWindowProc(hWnd, message, wParam, lParam);
+            }
+
+          mail->refCurrentItem ();
+          Mail::closeInspector_o (mail);
+          TRACEPOINT;
+          Mail::close (mail);
+          log_debug ("%s:%s: Close for %p uid: %s finished.",
+                     SRCNAME, __func__, mail, uid.c_str ());
+          mail->releaseCurrentItem();
+          TRETURN 0;
+        }
+
+    }
   return DefWindowProc(hWnd, message, wParam, lParam);
 }
 
index 599a90c..a8d24de 100644 (file)
@@ -56,6 +56,9 @@ typedef enum _gpgol_wmsg_type
   DO_AUTO_SECURE,
   DONT_AUTO_SECURE,
   CONFIG_KEY_DONE,
+  /* External API, keep it stable! */
+  EXT_API_CLOSE = 1301,
+  EXT_API_CLOSE_ALL = 1302,
 } gpgol_wmsg_type;
 
 typedef struct
index 336794f..02afc54 100644 (file)
@@ -67,10 +67,11 @@ run_parser_SOURCES = run-parser.cpp $(parser_SRC)
 else
 run_parser_SOURCES = run-parser.cpp $(parser_SRC) \
                        ../src/w32-gettext.cpp ../src/w32-gettext.h
+run_messenger_SOURCES = run-messenger.cpp
 endif
 
 if !HAVE_W32_SYSTEM
 noinst_PROGRAMS = t-parser run-parser
 else
-noinst_PROGRAMS = run-parser
+noinst_PROGRAMS = run-parser run-messenger
 endif
diff --git a/tests/run-messenger.cpp b/tests/run-messenger.cpp
new file mode 100644 (file)
index 0000000..99c4cf2
--- /dev/null
@@ -0,0 +1,84 @@
+/* run-messenger.cpp - Test for GpgOL's external windowmessage API.
+ * Copyright (C) 2016 by Bundesamt für Sicherheit in der Informationstechnik
+ * Software engineering by Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GpgOL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <windows.h>
+
+#include <stdio.h>
+
+static int
+show_usage (int ex)
+{
+  fputs ("usage: run-messgenger id [PAYLOAD]\n\n"
+         "Options:\n"
+         , stderr);
+  exit (ex);
+}
+
+
+int main(int argc, char **argv)
+{
+  int last_argc = -1;
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--help"))
+        {
+          show_usage (0);
+        }
+    }
+
+  if (argc != 1 && argc != 2)
+    {
+      show_usage (1);
+    }
+
+  int id = atoi (*argv);
+
+  HWND gpgol = FindWindowA ("GpgOLResponder", "GpgOLResponder");
+
+  if (!gpgol)
+    {
+      fprintf (stderr, "Failed to find GpgOL Window");
+      exit (1);
+    }
+
+  if (argc == 1)
+    {
+      printf ("Sending message: %i\n", id);
+      SendMessage (gpgol, WM_USER + 43, id, NULL);
+      exit (0);
+    }
+
+  /* Send message with payload */
+  char *payload = argv[1];
+  COPYDATASTRUCT cds;
+
+  cds.dwData = id;
+  cds.cbData = strlen (payload) + 1;
+  cds.lpData = payload;
+
+  printf ("Sending message: %i\n with param: %s", id, payload);
+  SendMessage (gpgol, WM_COPYDATA, 0, (LPARAM) &cds);
+  exit (0);
+}