New code to install forms so that appropriate icons are shown in the Viewer.
authorWerner Koch <wk@gnupg.org>
Mon, 4 Aug 2008 11:11:42 +0000 (11:11 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 4 Aug 2008 11:11:42 +0000 (11:11 +0000)
Note that we do not have these icons yet .

18 files changed:
ChangeLog
Makefile.am
NEWS
configure.ac
forms/Makefile.am [new file with mode: 0644]
forms/encr-l.ico [new file with mode: 0755]
forms/encr-s.ico [new file with mode: 0755]
forms/gpgol-ms_de.cfg [new file with mode: 0644]
forms/gpgol_de.cfg [new file with mode: 0644]
forms/sign-l.ico [new file with mode: 0755]
forms/sign-s.ico [new file with mode: 0755]
src/ChangeLog
src/common.c
src/common.h
src/ext-commands.cpp
src/main.c
src/mymapi.h
src/olflange.cpp

index 634f1fa..05f2048 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-04  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (SUBDIRS): Add forms.
+       * forms/Makefile.am: New.
+       * forms/gpgol_de.cfg, forms/gpgol-ms_de.cfg: New.
+       
 2008-06-04  Werner Koch  <wk@g10code.com>
 
        * doc/gpgol.texi (Assuan Protocol): Remove protocol specs.  They
index 8b230b6..0e67c1d 100644 (file)
@@ -23,7 +23,7 @@ DISTCHECK_CONFIGURE_FLAGS = --host=i586-mingw32msvc --build=i686-pc-linux-gnu \
 EXTRA_DIST = autogen.sh
 
 
-SUBDIRS = src po m4 doc
+SUBDIRS = src forms po m4 doc
 
 dist-hook:
        echo "$(VERSION)" > $(distdir)/VERSION
diff --git a/NEWS b/NEWS
index 985a1e7..73e608f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ Noteworthy changes for version 0.10.15
  * New menu item to remove all GpgOL created flags and attachments
    from all messages in a folder.
 
+ * Icons are now installed for messages processed by GpgOL.  For now
+   only for the German version of Outlook.
+
 
 Noteworthy changes for version 0.10.14 (2008-05-28)
 ===================================================
index 8ec8ad6..f9726e7 100644 (file)
@@ -251,6 +251,7 @@ fi
 AC_CONFIG_FILES([ Makefile
 src/Makefile
 src/versioninfo.rc        
+forms/Makefile
 doc/Makefile
 po/Makefile.in
 m4/Makefile
diff --git a/forms/Makefile.am b/forms/Makefile.am
new file mode 100644 (file)
index 0000000..f80a72d
--- /dev/null
@@ -0,0 +1,22 @@
+# forms - Automake template
+# Copyright (C) 2008 g10 Code GmbH
+# 
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+## Process this file with automake to produce Makefile.in
+
+icons = encr-l.ico encr-s.ico sign-l.ico sign-s.ico
+
+cfg_german = gpgol_de.cfg gpgol-ms_de.cfg 
+
+
+dist_pkgdata_DATA = $(icons) $(cfg_german)
+
+
+
diff --git a/forms/encr-l.ico b/forms/encr-l.ico
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/forms/encr-s.ico b/forms/encr-s.ico
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/forms/gpgol-ms_de.cfg b/forms/gpgol-ms_de.cfg
new file mode 100644 (file)
index 0000000..141d8c4
--- /dev/null
@@ -0,0 +1,35 @@
+[Description]
+MessageClass=IPM.Note.GpgOL.MultipartSigned
+DesignerRuntimeGuid={0006F020-0000-0000-C000-000000000046}
+CLSID={00061033-0000-0000-C000-000000000046}
+DisplayName=Form for class IPM.Note.GpgOL.MultipartSigned
+Category=Standard
+Subcategory=Formular
+Comment=
+LargeIcon=sign-l.ico
+SmallIcon=sign-s.ico
+VersionMajor=1
+VersionMinor=0
+Locale=deu
+Hidden=1
+Owner=Public Domain
+
+[Properties]
+
+[Verbs]
+Verb1=1
+
+[Verb.1]
+DisplayName=Ö&ffnen
+Code=0
+Flags=0
+Attribs=2
+
+[Extensions]
+Extensions1=1
+
+[Extension.1]
+Type=30
+NmidPropset={00020D0C-0000-0000-C000-000000000046}
+NmidInteger=1
+Value=1011111111111111
diff --git a/forms/gpgol_de.cfg b/forms/gpgol_de.cfg
new file mode 100644 (file)
index 0000000..d4be76c
--- /dev/null
@@ -0,0 +1,36 @@
+[Description]
+MessageClass=IPM.Note.GpgOL
+DesignerRuntimeGuid={0006F020-0000-0000-C000-000000000046}
+CLSID={00061033-0000-0000-C000-000000000046}
+DisplayName=Form for class IPM.Note.GpgOL
+Category=Standard
+Subcategory=Formular
+Comment=
+LargeIcon=encr-l.ico
+SmallIcon=encr-s.ico
+VersionMajor=1
+VersionMinor=0
+Locale=deu
+Hidden=1
+Owner=Public Domain
+
+[Properties]
+
+[Verbs]
+Verb1=1
+
+[Verb.1]
+DisplayName=Ö&ffnen
+Code=0
+Flags=0
+Attribs=2
+
+[Extensions]
+Extensions1=1
+
+[Extension.1]
+Type=30
+NmidPropset={00020D0C-0000-0000-C000-000000000046}
+NmidInteger=1
+Value=1011111111111111
+
diff --git a/forms/sign-l.ico b/forms/sign-l.ico
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/forms/sign-s.ico b/forms/sign-s.ico
new file mode 100755 (executable)
index 0000000..e69de29
index 92e4453..0fbfea2 100644 (file)
@@ -1,3 +1,11 @@
+2008-08-04  Werner Koch  <wk@g10code.com>
+
+       * olflange.cpp (install_forms): New.
+       (GpgolExt): Install forms if needed.
+       * common.c (get_data_dir): New.
+       * common.h (struct): Add field FORMS_REVISION.
+       * main.c (read_options, write_options): Read and write that option.
+
 2008-07-31  Werner Koch  <wk@g10code.com>
 
        * ext-commands.h (class GpgolExtCommands): Add m_nCmdRevertFolder.
index f4e9783..32fe466 100644 (file)
@@ -628,6 +628,39 @@ default_homedir (void)
   return dir;
 }
 
+/* Return the data dir used for forms etc.   Returns NULL on error. */
+char *
+get_data_dir (void)
+{
+  char *instdir;
+  char *p;
+  char *dname;
+
+  instdir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", GNUPG_REGKEY,
+                                     "Install Directory");
+  if (!instdir)
+    return NULL;
+  
+  /* Build the key: "<instdir>/share/gpgol".  */
+#define SDDIR "\\share\\gpgol"
+  dname = malloc (strlen (instdir) + strlen (SDDIR) + 1);
+  if (!dname)
+    {
+      free (instdir);
+      return NULL;
+    }
+  p = dname;
+  strcpy (p, instdir);
+  p += strlen (instdir);
+  strcpy (p, SDDIR);
+  
+  free (instdir);
+  
+#undef SDDIR
+  return dname;
+}
+
+
 
 /* Do in-place decoding of quoted-printable data of LENGTH in BUFFER.
    Returns the new length of the buffer and stores true at R_SLBRK if
index 78dea38..c05a58d 100644 (file)
@@ -135,6 +135,9 @@ struct
   /* The SVN revision as stored in the registry.  */
   int svn_revision; 
 
+  /* The SVN revision of the the binary used to install the forms.  */
+  int forms_revision;
+
   /* Disable message processing until restart.  This is required to
      implement message reverting as a perparation to remove GpgOL.  */
   int disable_gpgol;
@@ -195,6 +198,7 @@ char *get_save_filename (HWND root, const char *srcname);
 char *utf8_to_wincp (const char *string);
 
 const char *default_homedir (void);
+char *get_data_dir (void);
 
 size_t qp_decode (char *buffer, size_t length, int *r_slbrk);
 void b64_init (b64_state_t *state);
index f33afd0..728a895 100644 (file)
@@ -92,8 +92,6 @@ ul_release (LPVOID punk, const char *func, int lnr)
 
 
 
-
-
 /* Constructor */
 GpgolExtCommands::GpgolExtCommands (GpgolExt* pParentInterface)
 { 
index eef98e3..7d04b12 100644 (file)
@@ -633,6 +633,10 @@ read_options (void)
   opt.svn_revision = val? atol (val) : 0;
   xfree (val); val = NULL;
 
+  load_extension_value ("formsRevision", &val);
+  opt.forms_revision = val? atol (val) : 0;
+  xfree (val); val = NULL;
+
   load_extension_value ("bodyAsAttachment", &val);
   opt.body_as_attachment = val == NULL || *val != '1'? 0 : 1;
   xfree (val); val = NULL;
@@ -710,6 +714,7 @@ write_options (void)
     {"enableDefaultKey",         0, opt.enable_default_key},
     {"preferHtml",               0, opt.prefer_html},
     {"svnRevision",              1, opt.svn_revision},
+    {"formsRevision",            1, opt.forms_revision},
     {"bodyAsAttachment",         0, opt.body_as_attachment},
     {NULL, 0}
   };
index 406c747..89bb6a2 100644 (file)
@@ -32,6 +32,7 @@
    2007-07-23  Add IMAPISession; taken from WINE.
    2007-07-24  Add IMsgStore, IMAPIContainer and IMAPIFolder taken from specs.
                Reorganized code.
+   2008-08-01  Add IMAPIFormContainer taken from specs.
 */
 
 #ifndef MAPI_H
@@ -114,8 +115,8 @@ typedef struct MapiMessage_s *lpMapiMessage;
 #define MAPI_MESSAGE    0x00000005u
 #define MAPI_MAILUSER   0x00000006u
 #define MAPI_ATTACH     0x00000007u
-#define MAPI_DISTLIST   0x00000008u    
-#define MAPI_PROFSECT   0x00000009u    
+#define MAPI_DISTLIST   0x00000008u
+#define MAPI_PROFSECT   0x00000009u
 #define MAPI_STATUS     0x0000000Au
 #define MAPI_SESSION    0x0000000Bu
 #define MAPI_FORMINFO   0x0000000Cu
@@ -174,7 +175,7 @@ typedef struct MapiMessage_s *lpMapiMessage;
 
 
 #define FORCE_SUBMIT                  0x00000001ul
-                                      
+
 #define MSGFLAG_READ                  0x00000001ul
 #define MSGFLAG_UNMODIFIED            0x00000002ul
 #define MSGFLAG_SUBMIT                0x00000004ul
@@ -185,7 +186,7 @@ typedef struct MapiMessage_s *lpMapiMessage;
 #define MSGFLAG_RESEND                0x00000080ul
 #define MSGFLAG_RN_PENDING            0x00000100ul
 #define MSGFLAG_NRN_PENDING           0x00000200ul
-                                      
+
 #define SUBMITFLAG_LOCKED             0x00000001ul
 #define SUBMITFLAG_PREPROCESS         0x00000002ul
 
@@ -672,6 +673,9 @@ typedef struct IProfSect *LPPROFSECT;
 struct ISpoolerHook;
 typedef struct ISpoolerHook *LPSPOOLERHOOK;
 
+struct IMAPIFormContainer;
+typedef struct IMAPIFormContainer *LPMAPIFORMCONTAINER;
+
 
 /*** IUnknown methods ***/
 #define MY_IUNKNOWN_METHODS \
@@ -1013,6 +1017,84 @@ DECLARE_INTERFACE_(ISpoolerHook, IUnknown)
 };
 
 
+
+/* IMAPIFormContainer */
+
+#define MAPIFORM_INSTALL_OVERWRITEONCONFLICT  0x10
+
+typedef struct _SMAPIFormPropEnumVal
+{
+  LPTSTR pszDisplayName;
+  ULONG nVal;
+} SMAPIFormPropEnumVal, *LPMAPIFORMPROPENUMVAL;
+
+
+typedef struct _SMAPIFormProp
+{
+  ULONG      ulFlags;
+  ULONG      nPropType;
+  MAPINAMEID nmid;
+  LPTSTR     pszDisplayName;
+  ULONG      nSpecialType;
+  union {
+    struct {
+      MAPINAMEID nmidIdx;
+      ULONG cfpevAvailable;
+      LPMAPIFORMPROPENUMVAL pfpevAvailable;
+    } s1;
+  } u;
+} SMAPIFormProp, *LPMAPIFORMPROP;
+
+typedef struct _SMAPIFormPropArray
+{
+  ULONG cProps;
+  ULONG ulPad;
+  SMAPIFormProp aFormProp[MAPI_DIM];
+} SMAPIFormPropArray, *LPMAPIFORMPROPARRAY;
+
+typedef struct _SMessageClassArray
+{
+  ULONG  cValues;
+  LPCSTR aMessageClass[MAPI_DIM];
+} SMessageClassArray, *LPSMESSAGECLASSARRAY;
+
+
+/* Fixme: The void ptr in ResolveMessageClass and SMAPIFormInfoArray
+   should be a LPMAPIFORMINFO, but we have not yet defined the
+   corresponding class. */
+typedef struct _SMAPIFormInfoArray
+{
+  ULONG cForms;
+  void * aFormInfo[MAPI_DIM];
+} SMAPIFormInfoArray, *LPSMAPIFORMINFOARRAY;
+
+#define MY_IMAPIFORMCONTAINER_METHODS                                         \
+  STDMETHOD(GetLastError)(THIS_ HRESULT, ULONG, LPMAPIERROR FAR*) PURE;       \
+  STDMETHOD(InstallForm)(THIS_ ULONG ulUIParam, ULONG ulFlags,                \
+                         LPCTSTR szCfgPathName) PURE;                         \
+  STDMETHOD(RemoveForm)(THIS_ LPCSTR szMessageClass) PURE;                    \
+  STDMETHOD(ResolveMessageClass) (THIS_ LPCSTR szMessageClass, ULONG ulFlags, \
+                                  void * FAR *pforminfo) PURE;                \
+  STDMETHOD(ResolveMultipleMessageClasses)                                    \
+    (THIS_ LPSMESSAGECLASSARRAY pMsgClassArray, ULONG ulFlags,                \
+     LPSMAPIFORMINFOARRAY FAR *ppfrminfoarray) PURE;                          \
+  STDMETHOD(CalcFormPropSet)(THIS_  ULONG ulFlags,                            \
+                             LPMAPIFORMPROPARRAY FAR *ppResults) PURE;        \
+  STDMETHOD(GetDisplay)(THIS_ ULONG ulFlags,                                  \
+                        LPTSTR FAR *pszDisplayName) PURE;
+
+
+EXTERN_C const IID IID_IMAPIFormContainer;
+#undef INTERFACE
+#define INTERFACE IMAPIFormContainer
+DECLARE_INTERFACE_(IMAPIFormContainer, IUnknown)
+{
+  MY_IUNKNOWN_METHODS;
+  MY_IMAPIFORMCONTAINER_METHODS;
+};
+
+
+\f
 #undef MY_IUNKNOWN_METHODS
 #undef MY_IMAPIPROP_METHODS
 #undef MY_IMSGSTORE_METHODS
@@ -1022,6 +1104,7 @@ DECLARE_INTERFACE_(ISpoolerHook, IUnknown)
 #undef MY_IMAPITABLE_METHODS
 #undef MY_IMAPISESSION_METHODS
 #undef MY_ISPOOLERHOOK_METHODS
+#undef MY_IMAPIFORMCONTAINER_METHODS
 
 
 \f
@@ -1087,6 +1170,10 @@ HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER,LPFREEBUFFER,
                                 ULONG,LPSTR,LPSTR,LPSTREAM*);
 #endif
 
+
+STDAPI MAPIOpenLocalFormContainer (LPMAPIFORMCONTAINER FAR *ppfcnt);
+
+
 #ifdef __cplusplus
 }
 #endif
index b53aeb7..cb7d849 100644 (file)
@@ -1,6 +1,6 @@
 /* olflange.cpp - Connect GpgOL to Outlook
  *     Copyright (C) 2001 G Data Software AG, http://www.gdata.de
- *     Copyright (C) 2004, 2005, 2007 g10 Code GmbH
+ *     Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
  * 
  * This file is part of GpgOL.
  * 
@@ -67,6 +67,7 @@ DEFINE_GUID(CLSID_GPGOL, 0x42d30988, 0x1a3a, 0x11da,
 
 static bool g_initdll = FALSE;
 
+static void install_forms (void);
 
 
 \f
@@ -429,6 +430,8 @@ GpgolExt::GpgolExt (void)
                       " dialog can be found in the main menu at:"
                       " Extras->Options->GpgOL.\n"),
                       "GpgOL", MB_ICONINFORMATION|MB_OK);
+      if ( SVN_REVISION > opt.forms_revision )
+        install_forms ();
     }
 }
 
@@ -635,3 +638,77 @@ GpgolExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
 }
 
 
+static void
+install_forms (void)
+{
+  HRESULT hr;
+  LPMAPIFORMCONTAINER formcontainer = NULL;
+  static char *forms[] = 
+    {
+      "gpgol",
+      "gpgol-ms",
+      NULL,
+    };
+  int formidx;
+  LANGID langid;
+  const char *langsuffix;
+  char buffer[MAX_PATH+10];
+  char *datadir;
+  int any_error = 0;
+
+  langid = PRIMARYLANGID (LANGIDFROMLCID (GetThreadLocale ()));
+  switch (langid)
+    {
+    case LANG_GERMAN: langsuffix = "de"; break;
+    default: 
+      log_debug ("%s:%s: No forms available for primary language %d\n",
+                 SRCNAME, __func__, buffer);
+      /* Don't try again.  */
+      opt.forms_revision = SVN_REVISION;
+      write_options ();
+      return;
+    }
+
+  MAPIOpenLocalFormContainer (&formcontainer);
+  if (!formcontainer)
+    {
+      log_error ("%s:%s: error getting local form container\n",
+                 SRCNAME, __func__);
+      return;
+    }
+
+  datadir = get_data_dir ();
+  if (!datadir)
+    {
+      log_error ("%s:%s: error getting data directory\n",
+                 SRCNAME, __func__);
+      return;
+    }
+
+  for (formidx=0; forms[formidx]; formidx++)
+    {
+
+      snprintf (buffer, MAX_PATH, "%s\\%s_%s.cfg",
+                datadir, forms[formidx], langsuffix);
+      hr = formcontainer->InstallForm (0, MAPIFORM_INSTALL_OVERWRITEONCONFLICT,
+                                       buffer);
+      if (hr)
+        {
+          any_error = 1;
+          log_error ("%s:%s: installing form `%s' failed: hr=%#lx\n",
+                     SRCNAME, __func__, buffer, hr);
+        }
+      else
+        log_debug ("%s:%s: form `%s' installed\n",  SRCNAME, __func__, buffer);
+    }
+
+  xfree (datadir);
+
+  if (!any_error)
+    {
+      opt.forms_revision = SVN_REVISION;
+      write_options ();
+    }
+}
+
+