diff options
Diffstat (limited to 'branches/gpgme-0-3-branch/complus')
18 files changed, 3153 insertions, 0 deletions
diff --git a/branches/gpgme-0-3-branch/complus/ChangeLog b/branches/gpgme-0-3-branch/complus/ChangeLog new file mode 100644 index 00000000..fe34a662 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/ChangeLog @@ -0,0 +1,15 @@ +2001-07-30 Werner Koch <[email protected]> + + Encryption basically works. + + + Copyright 2001 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 file 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. +
\ No newline at end of file diff --git a/branches/gpgme-0-3-branch/complus/Makefile.am b/branches/gpgme-0-3-branch/complus/Makefile.am new file mode 100644 index 00000000..1965b9ff --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/Makefile.am @@ -0,0 +1,49 @@ +# Copyright (C) 2000 Werner Koch (dd9jn) +# Copyright (C) 2001 g10 Code GmbH +# +# This file is part of GPGME. +# +# GPGME is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GPGME 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +## Process this file with automake to produce Makefile.in + +# Because there is no free IDL compiler for OLE, we have to distribute +# a binary typelibrary. To generate a new one, copy the idl file to a +# system with an install MIDL and run the command +# midl /nocpp gpgcom.idl +# Sorry, there is no other way yet. +EXTRA_DIST = gpgcom.idl gpgcom.tlb gpgcom.rc vbtest.html vbtest.vbs README + +# No need to install this because we are cross-compiling anyway. +noinst_PROGRAMS = gpgcom tgpgcom + +INCLUDES = -I$(top_srcdir)/jnlib +LDADD = ../gpgme/libgpgme.la -L ../jnlib -ljnlib -lole32 -loleaut32 +gpgcom_LDADD = gpgcom_res.o $(LDADD) + +gpgcom_SOURCES = gpgcom.c main.h \ + debug.c utf8.c \ + igpgme.h igpgme.c + +tgpgcom_SOURCES = tgpgcom.c\ + debug.c \ + igpgme.h + +#regtlb_SOURCES = regtlb.c +#guidgen_SOURCES = guidgen.c + +gpgcom_res.o: gpgcom.rc + mingw32 windres $< gpgcom_res.o + diff --git a/branches/gpgme-0-3-branch/complus/README b/branches/gpgme-0-3-branch/complus/README new file mode 100644 index 00000000..7dc3bb1d --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/README @@ -0,0 +1,72 @@ + How to install and use the Gpgcom Windows Component + =================================================== + 2001-07-31 + + +Installation should be pretty easy: +----------------------------------- + + * Get and install the latest GnuPG binary for windows + (ftp://ftp.gnupg.org/gcrypt/binary/gnupg-w32-1.0.6.zip) + + * Check that you have an untampered version of this package by + comparing an MD5SUM against the one on the webpage or by checking + the signature of the package using "gpg --verify". See the + webpacge for details. + + * Because you are reading this file, you probably have already + unpacked it distribution using a unzip utility :-). You should + find these files: + + README - This file + gpgcom.exe - The Gpgcom server + vbtest.html - A Test webpage + vbtest.vbs - A VB script to be used with the cscript utility + + * If you are updating Gpgcom, run the old Gpgcom like this: + + c:\gnupg\gpgcom -UnregServer + + (Replace c:\gnupg with the actually used path) + + * Copy the file gpgcom.exe to a some location. C:\gnupg seems to be + a good choice. + + * Register the component using this command: + + c:\gnupg\gpgcom -RegServer + + * Ready + +Testing the installation: +------------------------- + + * Make sure that you have a working GnuPG (gpg.exe) and that at least + one key is installed. + + * Edit the vbtest.vbs script and replace "alice" in the line + + gpg.AddRecipient "alice" + + with a keyID or user name you have in your key ring. + + * Run the test script: + + cscript vbtest.vbs + + and you should see a valid MIME message with the encrypted text. + + +Using Gpgcom +------------ + +Gpgcom currently support only encryption but will be extended to the +full range of operations GnuPG provides. The 2 examples should goive +yopu a hint on how to use it. We suggest that you always set armor to +true, so that the returned text is a string. If you don't use armor, +the "ciphertext" property will return an array with the binary +message. + + + + diff --git a/branches/gpgme-0-3-branch/complus/debug.c b/branches/gpgme-0-3-branch/complus/debug.c new file mode 100644 index 00000000..d7cb0a08 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/debug.c @@ -0,0 +1,40 @@ +/* debug.c - COM+ debug helpers + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <windows.h> +#include <ole2.h> + + +const char * +debugstr_guid (const GUID *id) +{ + static char str[100]; + + if (!id) + return "(null)"; + sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], + id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); + return str; +} + diff --git a/branches/gpgme-0-3-branch/complus/example.c b/branches/gpgme-0-3-branch/complus/example.c new file mode 100644 index 00000000..a7d838d5 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/example.c @@ -0,0 +1,598 @@ +/* + * Copyright 1999 Marcus Meissner + */ +#include <string.h> +#include <stdio.h> +#include <assert.h> + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "debugtools.h" + +#include "initguid.h" +#include "vfw.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj); +static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface); +static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface); +static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size); +static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam); +static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi); +static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size); +static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size); +static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface); +static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam); + +struct ICOM_VTABLE(IAVIFile) iavift = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IAVIFile_fnQueryInterface, + IAVIFile_fnAddRef, + IAVIFile_fnRelease, + IAVIFile_fnInfo, + IAVIFile_fnGetStream, + IAVIFile_fnCreateStream, + IAVIFile_fnWriteData, + IAVIFile_fnReadData, + IAVIFile_fnEndRecord, + IAVIFile_fnDeleteStream +}; + +static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj); +static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface); +static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface); +static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2); +static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size); +static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags); +static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize); +static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize); +static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread); +static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten); +static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples); +static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread); +static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size); +static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen); + +struct ICOM_VTABLE(IAVIStream) iavist = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IAVIStream_fnQueryInterface, + IAVIStream_fnAddRef, + IAVIStream_fnRelease, + IAVIStream_fnCreate, + IAVIStream_fnInfo, + IAVIStream_fnFindSample, + IAVIStream_fnReadFormat, + IAVIStream_fnSetFormat, + IAVIStream_fnRead, + IAVIStream_fnWrite, + IAVIStream_fnDelete, + IAVIStream_fnReadData, + IAVIStream_fnWriteData, + IAVIStream_fnSetInfo +}; + +typedef struct IAVIStreamImpl { + /* IUnknown stuff */ + ICOM_VFIELD(IAVIStream); + DWORD ref; + /* IAVIStream stuff */ + LPVOID lpInputFormat; + DWORD inputformatsize; + BOOL iscompressing; + DWORD curframe; + + /* Compressor stuff */ + HIC hic; + LPVOID lpCompressFormat; + ICINFO icinfo; + DWORD compbufsize; + LPVOID compbuffer; + + DWORD decompbufsize; + LPVOID decompbuffer; + LPVOID decompformat; + AVICOMPRESSOPTIONS aco; + + LPVOID lpPrev; /* pointer to decompressed frame later */ + LPVOID lpPrevFormat; /* pointer to decompressed info later */ +} IAVIStreamImpl; + +/*********************************************************************** + * AVIFileInit + */ +void WINAPI +AVIFileInit(void) { + FIXME("(),stub!\n"); +} + +typedef struct IAVIFileImpl { + /* IUnknown stuff */ + ICOM_VFIELD(IAVIFile); + DWORD ref; + /* IAVIFile stuff... */ +} IAVIFileImpl; + +static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) { + ICOM_THIS(IAVIFileImpl,iface); + + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); + if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) || + !memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile)) + ) { + *obj = iface; + return S_OK; + } + return OLE_E_ENUM_NOMORE; +} + +static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) { + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->AddRef()\n",iface); + return ++(This->ref); +} + +static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) { + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->Release()\n",iface); + if (!--(This->ref)) { + HeapFree(GetProcessHeap(),0,iface); + return 0; + } + return This->ref; +} + +static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) { + FIXME("(%p)->Info(%p,%ld)\n",iface,afi,size); + + /* FIXME: fill out struct? */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) { + FIXME("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam); + /* FIXME: create interface etc. */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) { + ICOM_THIS(IAVIStreamImpl,iface); + char fcc[5]; + IAVIStreamImpl *istream; + + FIXME("(%p,%p,%p)\n",This,avis,asi); + istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl)); + istream->ref = 1; + ICOM_VTBL(istream) = &iavist; + fcc[4]='\0'; + memcpy(fcc,(char*)&(asi->fccType),4); + FIXME("\tfccType '%s'\n",fcc); + memcpy(fcc,(char*)&(asi->fccHandler),4); + FIXME("\tfccHandler '%s'\n",fcc); + FIXME("\tdwFlags 0x%08lx\n",asi->dwFlags); + FIXME("\tdwCaps 0x%08lx\n",asi->dwCaps); + FIXME("\tname '%s'\n",debugstr_w(asi->szName)); + + istream->curframe = 0; + *avis = (PAVISTREAM)istream; + return S_OK; +} + +static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) { + FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size); + /* FIXME: write data to file */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) { + FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size); + /* FIXME: read at most size bytes from file */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) { + FIXME("(%p)->EndRecord()\n",iface); + /* FIXME: end record? */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) { + FIXME("(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam); + /* FIXME: delete stream? */ + return E_FAIL; +} + +/*********************************************************************** + * AVIFileOpenA + */ +HRESULT WINAPI AVIFileOpenA( + PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler +) { + IAVIFileImpl *iavi; + + FIXME("(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,debugstr_guid(lpHandler)); + iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl)); + iavi->ref = 1; + ICOM_VTBL(iavi) = &iavift; + *ppfile = (LPVOID)iavi; + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) { + ICOM_THIS(IAVIStreamImpl,iface); + + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); + if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) || + !memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream)) + ) { + *obj = This; + return S_OK; + } + /* can return IGetFrame interface too */ + return OLE_E_ENUM_NOMORE; +} + +static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->AddRef()\n",iface); + return ++(This->ref); +} + +static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->Release()\n",iface); + if (!--(This->ref)) { + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->ref; +} + +static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) { + FIXME("(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) { + FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size); + return E_FAIL; +} + +static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) { + FIXME("(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) { + FIXME("(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize); + return E_FAIL; +} + +/*********************************************************************** + * IAVIStream::SetFormat + */ +static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) { + IAVIStreamImpl *as = (IAVIStreamImpl*)iface; + + FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize); + if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat); + as->inputformatsize = formatsize; + as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize); + memcpy(as->lpInputFormat,format,formatsize); + if (as->iscompressing) { + int xsize; + /* Set up the Compressor part */ + xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat); + as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize); + ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat); + ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat); + as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat); + as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize); + + /* Set up the Decompressor part (for prev frames?) */ + xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat); + as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize); + ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat); + as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage; + as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize); + memset(as->decompbuffer,0xff,as->decompbufsize); + assert(HeapValidate(GetProcessHeap(),0,NULL)); + + ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat); + ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat); + as->lpPrev = as->lpPrevFormat = NULL; + } + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) { + FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { + IAVIStreamImpl *as = (IAVIStreamImpl*)iface; + DWORD ckid,xflags; + + FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); + + ICCompress( + as->hic,flags, + as->lpCompressFormat, + as->compbuffer, + as->lpInputFormat,buffer, + &ckid,&xflags, + as->curframe,0xffffff/*framesize*/,as->aco.dwQuality, + as->lpPrevFormat,as->lpPrev + ); + ICDecompress( + as->hic, + flags, /* FIXME: check */ + as->lpCompressFormat, + as->compbuffer, + as->decompformat, + as->decompbuffer + ); + /* We now have a prev format for the next compress ... */ + as->lpPrevFormat = as->decompformat; + as->lpPrev = as->decompbuffer; + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) { + FIXME("(%p)->Delete(%ld,%ld)\n",iface,start,samples); + return E_FAIL; +} +static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) { + FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) { + FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) { + FIXME("(%p)->SetInfo(%p,%ld)\n",iface,info,infolen); + return E_FAIL; +} + +/*********************************************************************** + * AVIFileCreateStreamA + */ +HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) { + AVISTREAMINFOW psiw; + + /* Only the szName at the end is different */ + memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName)); + MultiByteToWideChar( CP_ACP, 0, psi->szName, -1, + psiw.szName, sizeof(psiw.szName) / sizeof(WCHAR) ); + return IAVIFile_CreateStream(iface,ppavi,&psiw); +} + +/*********************************************************************** + * AVIFileCreateStreamW + */ +HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) { + return IAVIFile_CreateStream(iface,avis,asi); +} + + +/*********************************************************************** + * AVIFileGetStream + */ +HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) { + return IAVIFile_GetStream(iface,avis,fccType,lParam); +} + +/*********************************************************************** + * AVIFileInfoA + */ +HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) { + AVIFILEINFOW afiw; + HRESULT hres; + + if (size < sizeof(AVIFILEINFOA)) + return AVIERR_BADSIZE; + hres = IAVIFile_Info(iface,&afiw,sizeof(afiw)); + memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType)); + WideCharToMultiByte( CP_ACP, 0, afiw.szFileType, -1, + afi->szFileType, sizeof(afi->szFileType), NULL, NULL ); + afi->szFileType[sizeof(afi->szFileType)-1] = 0; + return hres; +} + +/*********************************************************************** + * AVIStreamInfoW + */ +HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG + size) { + return IAVIFile_Info(iface,asi,size); +} + +/*********************************************************************** + * AVIStreamInfoA + */ +HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG + size) { + AVISTREAMINFOW asiw; + HRESULT hres; + + if (size<sizeof(AVISTREAMINFOA)) + return AVIERR_BADSIZE; + hres = IAVIFile_Info(iface,&asiw,sizeof(asiw)); + memcpy(asi,&asiw,sizeof(asiw)-sizeof(asiw.szName)); + WideCharToMultiByte( CP_ACP, 0, asiw.szName, -1, + asi->szName, sizeof(asi->szName), NULL, NULL ); + asi->szName[sizeof(asi->szName)-1] = 0; + return hres; +} + +/*********************************************************************** + * AVIFileInfoW + */ +HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) { + return IAVIFile_Info(iface,afi,size); +} + +/*********************************************************************** + * AVIMakeCompressedStream + */ +HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) { + char fcc[5]; + IAVIStreamImpl *as; + FIXME("(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler); + fcc[4]='\0'; + memcpy(fcc,&(aco->fccType),4); + FIXME("\tfccType: '%s'\n",fcc); + memcpy(fcc,&(aco->fccHandler),4); + FIXME("\tfccHandler: '%s'\n",fcc); + FIXME("\tdwFlags: 0x%08lx\n",aco->dwFlags); + + /* we just create a duplicate for now */ + IAVIStream_AddRef(ppsSource); + *ppsCompressed = ppsSource; + as = (IAVIStreamImpl*)ppsSource; + + /* this is where the fun begins. Open a compressor and prepare it. */ + as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS); + + /* May happen. for instance if the codec is not able to compress */ + if (!as->hic) + return AVIERR_UNSUPPORTED; + + ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO)); + FIXME("Opened compressor: '%s' '%s'\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription)); + as->iscompressing = TRUE; + memcpy(&(as->aco),aco,sizeof(*aco)); + if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) { + ICCOMPRESSFRAMES icf; + + /* now what to fill in there ... Hmm */ + memset(&icf,0,sizeof(icf)); + icf.lDataRate = aco->dwBytesPerSecond; + icf.lQuality = aco->dwQuality; + icf.lKeyRate = aco->dwKeyFrameEvery; + + icf.GetData = (void *)0xdead4242; + icf.PutData = (void *)0xdead4243; + ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf)); + } + return S_OK; +} + +/*********************************************************************** + * AVIStreamSetFormat + */ +HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) { + return IAVIStream_SetFormat(iface,pos,format,formatsize); +} + +/*********************************************************************** + * AVIStreamReadFormat + */ +HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) { + return IAVIStream_ReadFormat(iface,pos,format,formatsize); +} + +/*********************************************************************** + * AVIStreamWrite( + */ +HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { + return IAVIStream_Write(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); +} + +/*********************************************************************** + * AVIStreamRead + */ +HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) { + return IAVIStream_Read(iface,start,samples,buffer,buffersize,bytesread,samplesread); +} + +/*********************************************************************** + * AVIStreamWriteData + */ +HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) { + return IAVIStream_WriteData(iface,fcc,lp,size); +} + +/*********************************************************************** + * AVIStreamReadData + */ +HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) { + return IAVIStream_ReadData(iface,fcc,lp,lpread); +} + +/*********************************************************************** + * AVIStreamStart + */ +LONG WINAPI AVIStreamStart(PAVISTREAM iface) { + AVISTREAMINFOW si; + + IAVIStream_Info(iface,&si,sizeof(si)); + return si.dwStart; +} + +/*********************************************************************** + * AVIStreamLength + */ +LONG WINAPI AVIStreamLength(PAVISTREAM iface) { + AVISTREAMINFOW si; + HRESULT ret; + + ret = IAVIStream_Info(iface,&si,sizeof(si)); + if (ret) /* error */ + return 1; + return si.dwLength; +} + +/*********************************************************************** + * AVIStreamRelease + */ +ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) { + return IAVIStream_Release(iface); +} + +/*********************************************************************** + * AVIStreamGetFrameOpen + */ +PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) { + FIXME("(%p)->(%p),stub!\n",iface,bmi); + return NULL; +} + +/*********************************************************************** + * AVIStreamGetFrame + */ +LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) { + return IGetFrame_GetFrame(pg,pos); +} + +/*********************************************************************** + * AVIStreamGetFrameClose + */ +HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) { + if (pg) IGetFrame_Release(pg); + return 0; +} + +/*********************************************************************** + * AVIFileRelease + */ +ULONG WINAPI AVIFileRelease(PAVIFILE iface) { + return IAVIFile_Release(iface); +} + +/*********************************************************************** + * AVIFileExit + */ +void WINAPI AVIFileExit(void) { + FIXME("(), stub.\n"); +} diff --git a/branches/gpgme-0-3-branch/complus/gpgcom.c b/branches/gpgme-0-3-branch/complus/gpgcom.c new file mode 100644 index 00000000..7c967be8 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/gpgcom.c @@ -0,0 +1,545 @@ +/* gpgcom.c - COM+ component to access GnuPG + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> +#include <windows.h> + +#include <ole2.h> + +#include "argparse.h" + +#include "main.h" +#include "igpgme.h" + +static void register_server (void); +static void unregister_server (void); +static void enter_complus (void); + + +enum cmd_and_opt_values { aNull = 0, + oQuiet = 'q', + oVerbose = 'v', + + oNoVerbose = 500, + oOptions, + oDebug, + oDebugAll, + oNoGreeting, + oNoOptions, + oHomedir, + oGPGBinary, + oRegServer, + oUnregServer, + oEmbedding, +aTest }; + + +static ARGPARSE_OPTS opts[] = { + + { 301, NULL, 0, N_("@Options:\n ") }, + + { oVerbose, "verbose", 0, N_("verbose") }, + { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, + { oOptions, "options" , 2, N_("read options from file")}, + { oDebug, "debug" ,4|16, N_("set debugging flags")}, + { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, + { oGPGBinary, "gpg-program", 2 , "" }, + { oRegServer, "RegServer" , 0, "" }, + { oUnregServer, "UnregServer" , 0, "" }, + { oEmbedding, "Embedding" , 0, "" }, +{0} }; + + + + +static const char * +my_strusage( int level ) +{ + const char *p; + switch( level ) { + case 11: p = "gpgcom"; + break; + case 13: p = VERSION; break; + /*case 17: p = PRINTABLE_OS_NAME; break;*/ + case 19: p = + _("Please report bugs to <[email protected]>.\n"); + break; + case 1: + case 40: p = + _("Usage: gpgcom [options] (-h for help)"); + break; + case 41: p = + _("Syntax: gpgcom [options]\n" + "GnuPG COM+ component\n"); + break; + + default: p = NULL; + } + return p; +} + + +int +main (int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + int orig_argc; + char **orig_argv; + FILE *configfp = NULL; + char *configname = NULL; + unsigned configlineno; + int parse_debug = 0; + int default_config =1; + int greeting = 0; + int nogreeting = 0; + int action = 0; + + set_strusage( my_strusage ); + /*log_set_name ("gpa"); not yet implemented in logging.c */ + + opt.homedir = getenv("GNUPGHOME"); + if( !opt.homedir || !*opt.homedir ) { + #ifdef HAVE_DRIVE_LETTERS + opt.homedir = "c:/gnupg"; + #else + opt.homedir = "~/.gnupg"; + #endif + } + + /* check whether we have a config file on the commandline */ + orig_argc = argc; + orig_argv = argv; + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ + while( arg_parse( &pargs, opts) ) { + if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll ) + parse_debug++; + else if( pargs.r_opt == oOptions ) { + /* yes there is one, so we do not try the default one, but + * read the option file when it is encountered at the commandline + */ + default_config = 0; + } + else if( pargs.r_opt == oNoOptions ) + default_config = 0; /* --no-options */ + else if( pargs.r_opt == oHomedir ) + opt.homedir = pargs.r.ret_str; + } + + if( default_config ) + configname = make_filename(opt.homedir, "gpgme.conf", NULL ); + + + argc = orig_argc; + argv = orig_argv; + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 1 | (1<<5); /* do not remove the args, allow one dash */ + next_pass: + if( configname ) { + configlineno = 0; + configfp = fopen( configname, "r" ); + if( !configfp ) { + if( default_config ) { + if( parse_debug ) + log_info(_("NOTE: no default option file `%s'\n"), + configname ); + } + else { + log_error(_("option file `%s': %s\n"), + configname, strerror(errno) ); + exit(2); + } + free(configname); configname = NULL; + } + if( parse_debug && configname ) + log_info(_("reading options from `%s'\n"), configname ); + default_config = 0; + } + + while( optfile_parse( configfp, configname, &configlineno, + &pargs, opts) ) { + switch( pargs.r_opt ) { + case oQuiet: opt.quiet = 1; break; + case oVerbose: opt.verbose++; break; + + case oDebug: opt.debug |= pargs.r.ret_ulong; break; + case oDebugAll: opt.debug = ~0; break; + + case oOptions: + /* config files may not be nested (silently ignore them) */ + if( !configfp ) { + free(configname); + configname = xstrdup(pargs.r.ret_str); + goto next_pass; + } + break; + case oNoGreeting: nogreeting = 1; break; + case oNoVerbose: opt.verbose = 0; break; + case oNoOptions: break; /* no-options */ + case oHomedir: opt.homedir = pargs.r.ret_str; break; + case oGPGBinary: break; + + case oRegServer: action = 1; break; + case oUnregServer: action = 2; break; + case oEmbedding: action = 3; break; + + default : pargs.err = configfp? 1:2; break; + } + } + if( configfp ) { + fclose( configfp ); + configfp = NULL; + free(configname); configname = NULL; + goto next_pass; + } + free( configname ); configname = NULL; + if( log_get_errorcount(0) ) + exit(2); + if( nogreeting ) + greeting = 0; + + if( greeting ) { + fprintf(stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + fprintf(stderr, "%s\n", strusage(15) ); + } + #ifdef IS_DEVELOPMENT_VERSION + log_info("NOTE: this is a development version!\n"); + #endif + + if ( action == 1 ) + register_server (); + else if (action == 2 ) + unregister_server (); + else if (action == 3 ) + enter_complus (); + else { + fprintf (stderr, "This is a COM+ component with no user interface.\n" + "gpgme --help will give you a list of options\n" ); + exit (1); + } + + return 0; +} + + +static void +register_progid ( const char *name ) +{ + HKEY hk = 0; + char buf[500]; + + /* Create a ProgID entry to point to the ClassID */ + sprintf (buf, "%.400s", name); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + sprintf (buf, "g10 Code's GnuPG made easy COMponent" ); + if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, 0)) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + sprintf (buf, "%.400s\\CLSID", name); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + sprintf (buf, "%.100s", debugstr_guid (&CLSID_Gpgme) ); + if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; +} + + +static void +register_typelib (void) +{ + ITypeLib *pTypeLib; + HRESULT hr; + char name[500]; + wchar_t *wname; + size_t n; + + if ( !GetModuleFileNameA (0, name, sizeof (name)-10) ) { + fprintf (stderr,"GetModuleFileName() failed: %d\n", + (int)GetLastError()); + exit (1); + } + n = mbstowcs (NULL, name, strlen(name)+1); + wname = xmalloc ((n+1)*sizeof *wname); + mbstowcs (wname, name, strlen (name)+1); + + hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED); + if (hr) + fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr); + + hr = LoadTypeLibEx (wname, REGKIND_REGISTER, &pTypeLib); + if (hr) + fprintf (stderr, "LoadTypeLibEx() failed: hr=%lx\n", hr); + + ITypeLib_Release (pTypeLib); + CoUninitialize (); + free (wname); +} + +static void +unregister_typelib (void) +{ + UnRegisterTypeLib (&TLBID_Gpgcom, 1, 0, LANG_NEUTRAL, SYS_WIN32); +} + +static void +register_server () +{ + HKEY hk = 0; + char buf[500]; + + + register_typelib (); + + /* Create a key for the CLSID */ + sprintf (buf, "CLSID\\%.100s", debugstr_guid (&CLSID_Gpgme) ); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + /* Store our class name as default value */ + strcpy (buf, "Gpgme"); + if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + + /* Set the application ID */ + sprintf (buf, "%.100s", debugstr_guid (&APPID_Gpgcom) ); + if (RegSetValueExA (hk, "AppID", 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + + /* Create the LocalServer32 subkey under the CLSID key */ + sprintf (buf, "CLSID\\%.100s\\LocalServer32", + debugstr_guid (&CLSID_Gpgme) ); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + /* retrieve the module name and add it under the key */ + if ( !GetModuleFileNameA (0, buf, sizeof (buf)-10) ) { + fprintf (stderr,"GetModuleFileName() failed\n"); + exit (1); + } + if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + + /* Create the ProgID subkey under the CLSID key */ + sprintf (buf, "CLSID\\%.100s\\ProgID", + debugstr_guid (&CLSID_Gpgme) ); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + if (RegSetValueExA (hk, 0, 0, REG_SZ, "Gpgcom.Gpgme.1", 0)) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + /* Create the VersionIndependentProgID subkey under the CLSID key */ + sprintf (buf, "CLSID\\%.100s\\VersionIndependentProgID", + debugstr_guid (&CLSID_Gpgme) ); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + if (RegSetValueExA (hk, 0, 0, REG_SZ, "Gpgcom.Gpgme", 0)) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + + + /* Create a key to store AppID info */ + sprintf (buf, "AppID\\%.100s", debugstr_guid (&APPID_Gpgcom) ); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + /* Store the name as default value */ + strcpy (buf, "Gpgcom"); + if (RegSetValueExA (hk, 0, 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + + register_progid ("Gpgcom.Gpgme"); + register_progid ("Gpgcom.Gpgme.1"); + + /* Create a convenience cross reference to the AppID */ + sprintf (buf, "AppID\\gpgcom.exe"); + if (RegCreateKeyA (HKEY_CLASSES_ROOT, buf, &hk)) { + fprintf (stderr,"RegCreateKey(`%s') failed\n", buf); + exit (1); + } + sprintf (buf, "%.100s", debugstr_guid (&APPID_Gpgcom) ); + if (RegSetValueExA (hk, "AppID", 0, REG_SZ, buf, strlen (buf))) { + fprintf (stderr,"RegSetValueEx(`%s') failed\n", buf); + exit (1); + } + if (RegCloseKey (hk)) { + fprintf (stderr,"RegCloseKey() failed\n"); + exit (1); + } + hk = 0; + + fprintf (stderr,"*** Component registered\n"); +} + +static void +unregister_server () +{ + char buf[500]; + + unregister_typelib (); + sprintf (buf, "CLSID\\%.100s\\LocalServer32", + debugstr_guid (&CLSID_Gpgme) ); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + sprintf (buf, "CLSID\\%.100s\\ProgID", debugstr_guid (&CLSID_Gpgme) ); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + sprintf (buf, "CLSID\\%.100s", debugstr_guid (&CLSID_Gpgme) ); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + sprintf (buf, "Gpgcom.Gpgme.1\\CLSID"); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + sprintf (buf, "Gpgcom.Gpgme.1"); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + sprintf (buf, "Gpgcom.Gpgme\\CLSID"); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + sprintf (buf, "Gpgcom.Gpgme"); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + + sprintf (buf, "AppID\\%.100s", debugstr_guid (&APPID_Gpgcom) ); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + sprintf (buf, "AppID\\gpgcom.exe" ); + if (RegDeleteKey (HKEY_CLASSES_ROOT, buf)) + fprintf (stderr,"RegDeleteKey(`%s') failed\n", buf); + + fprintf (stderr,"*** component unregistered\n"); +} + + +static void +enter_complus () +{ + HANDLE running; + DWORD reg; + IClassFactory *factory; + CLSID clsid; + HRESULT hr; + + fprintf (stderr,"*** enter enter_complus()\n"); + CoInitializeEx (NULL, COINIT_MULTITHREADED); + running = CreateEvent (NULL, FALSE, FALSE, NULL ); + fprintf (stderr,"*** CoInitialize() done; event=%lx\n", (unsigned long)running ); + + igpgme_register_exit_event (running); + factory = igpgme_factory_new ( &clsid ); + fprintf (stderr,"*** igpgme_factory_new() done; got=%p\n", factory ); + hr = CoRegisterClassObject (&clsid, (IUnknown*)factory, + CLSCTX_LOCAL_SERVER, + REGCLS_SUSPENDED|REGCLS_MULTIPLEUSE, ® ); + if (hr) { + fprintf (stderr, "CoRegisterClassObject() failed: hr=%lx\n", hr); + exit (1); + } + hr = CoResumeClassObjects (); + if (hr) + fprintf (stderr, "CoRegisterClassObject() failed: hr=%lx\n", hr); + fprintf (stderr,"*** class object registered; waiting\n" ); + + WaitForSingleObject ( running, INFINITE ); + fprintf (stderr,"*** shutting down\n" ); + igpgme_register_exit_event (NULL); + CloseHandle (running); + CoRevokeClassObject ( reg ); + fprintf (stderr,"*** class object revoked\n" ); + igpgme_factory_release (factory); + fprintf (stderr,"*** factory released\n" ); + CoUninitialize (); + fprintf (stderr,"*** leave enter_complus()\n" ); +} + diff --git a/branches/gpgme-0-3-branch/complus/gpgcom.idl b/branches/gpgme-0-3-branch/complus/gpgcom.idl new file mode 100644 index 00000000..654eec04 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/gpgcom.idl @@ -0,0 +1,62 @@ +/* ignupg.idl - Interface definition for the COM+ class GnuPG + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +import "unknwn.idl"; +import "oaidl.idl"; + + +[ object, uuid(3811fd50-7f72-11d5-8c9e-0080ad190cd5), dual] +interface IGpgme : IDispatch +{ + HRESULT GetVersion([out] BSTR *retval); + HRESULT GetEngineInfo([out] BSTR *retval); + HRESULT Cancel(void); + [propput] HRESULT Armor([in] BOOL flag); + [propget] HRESULT Armor([out, retval] BOOL *retval); + [propput] HRESULT Textmode([in] BOOL flag); + [propget] HRESULT Textmode([out, retval] BOOL *retval); + [propput] HRESULT Plaintext([in] VARIANT val); + [propget] HRESULT Plaintext([out, retval] VARIANT *retval); + [propput] HRESULT Ciphertext([in] VARIANT val); + [propget] HRESULT Ciphertext([out,retval] VARIANT *retval); + HRESULT ClearRecipients(void); + HRESULT AddRecipient([in] BSTR name, + [in, optional, defaultvalue(-1)] signed short trust); + HRESULT ResetSignKeys(void); + HRESULT AddSignKey([in] BSTR name); + HRESULT Encrypt(void); + HRESULT Sign([in,optional,defaultvalue(0)] signed short signmode); + HRESULT SignEncrypt([in,optional,defaultvalue(0)] signed short signmode); + +}; + + +[ uuid(3811fd48-7f72-11d5-8c9e-0080ad190cd5), + helpstring("g10Code.gpgcom, type library"), + version(1.0) ] +library GpgcomLib +{ + [ uuid(3811fd40-7f72-11d5-8c9e-0080ad190cd5) ] + coclass Gpgcom + { + [default] interface IGpgme; + } +}; diff --git a/branches/gpgme-0-3-branch/complus/gpgcom.rc b/branches/gpgme-0-3-branch/complus/gpgcom.rc new file mode 100644 index 00000000..d9ac5666 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/gpgcom.rc @@ -0,0 +1,22 @@ +/* gpgcom.rc - Resource file for gpgcom + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +1 TYPELIB "gpgcom.tlb" + diff --git a/branches/gpgme-0-3-branch/complus/gpgcom.tlb b/branches/gpgme-0-3-branch/complus/gpgcom.tlb Binary files differnew file mode 100644 index 00000000..ae3d1627 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/gpgcom.tlb diff --git a/branches/gpgme-0-3-branch/complus/guidgen.c b/branches/gpgme-0-3-branch/complus/guidgen.c new file mode 100644 index 00000000..a4ac07dc --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/guidgen.c @@ -0,0 +1,130 @@ +/* guidgen.c - Tool to create GUIDs + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> +#include <windows.h> + +#include "obj_base.h" + +#include "argparse.h" + + +enum cmd_and_opt_values { aNull = 0, + oVerbose = 'v', + +aTest }; + + +static ARGPARSE_OPTS opts[] = { + + { 301, NULL, 0, "@Options:\n " }, + + { oVerbose, "verbose", 0, "verbose" }, +{0} }; + +static struct { + int verbose; +} opt; + + +static void create_guid (void); + +static const char * +my_strusage( int level ) +{ + const char *p; + switch( level ) { + case 11: p = "guidgen"; + break; + case 13: p = VERSION; break; + /*case 17: p = PRINTABLE_OS_NAME; break;*/ + case 19: p = + "Please report bugs to <[email protected]>.\n"; + break; + case 1: + case 40: p = + "Usage: guidgen [options] (-h for help)"; + break; + case 41: p = + "Syntax: guidgen [options]\n" + "Generate GUIDs\n"; + break; + + default: p = NULL; + } + return p; +} + + +int +main (int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + + set_strusage( my_strusage ); + /*log_set_name ("gpa"); not yet implemented in logging.c */ + + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 0; + while( arg_parse( &pargs, opts) ) { + switch( pargs.r_opt ) { + case oVerbose: opt.verbose++; break; + + default : pargs.err = 2; break; + } + } + + if (!argc) + create_guid(); + else { + int n; + + for (n = atoi (argv[0]); n > 0; n-- ) + create_guid (); + } + + return 0; +} + + +static void +create_guid () +{ + GUID guid, *id; + id = &guid; + if ( CoCreateGuid (id) ) { + fprintf (stderr,"failed to create GUID\n"); + exit (1); + } + printf( "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], + id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); +} + + diff --git a/branches/gpgme-0-3-branch/complus/igpgme.c b/branches/gpgme-0-3-branch/complus/igpgme.c new file mode 100644 index 00000000..9aa64a24 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/igpgme.c @@ -0,0 +1,859 @@ +/* igpgme.c - COM+ class IGpgme + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> +#include <windows.h> + +#include "../gpgme/gpgme.h" + +/* FIXME: Put them into an extra header */ +void *_gpgme_malloc (size_t n ); +void *_gpgme_calloc (size_t n, size_t m ); +void *_gpgme_realloc (void *p, size_t n); +char *_gpgme_strdup (const char *p); +void _gpgme_free ( void *a ); + + + +#define INITGUID +#include "igpgme.h" + +/* + * Declare the interface implementation structures + */ +typedef struct IGpgmeImpl IGpgmeImpl; +typedef struct IClassFactoryImpl IClassFactoryImpl; + +static HANDLE my_exit_event; + +struct IGpgmeImpl { + /* IUnknown required stuff */ + ICOM_VFIELD (IGpgme); + DWORD ref; + /* Delegation to IDispatch */ + struct { + IUnknown *disp; + ITypeInfo *tinfo; + } std_disp; + /* Our stuff */ + GpgmeCtx mainctx; + GpgmeData plaintext; + int plaintext_given_as_bstr; + GpgmeData ciphertext; + int ciphertext_is_armored; + GpgmeRecipients rset; +}; + + +struct IClassFactoryImpl { + /* IUnknown fields */ + ICOM_VFIELD(IClassFactory); + DWORD ref; +}; + +/********************************************************** + ************** helper functions ************************ + *********************************************************/ +static HRESULT +map_gpgme_error (GpgmeError err) +{ + HRESULT hr; + + if (!err) + return 0; + if ( err < 0 || err > 0x1000 ) { + fprintf (stderr,"*** GpgmeError `%s' mapped to GPGME_General_Error\n", + gpgme_strerror (err) ); + err = GPGME_General_Error; + } + hr = MAKE_HRESULT (SEVERITY_ERROR, FACILITY_ITF, 0x1000 + err); + fprintf (stderr,"*** GpgmeError `%s' mapped to %lx\n", + gpgme_strerror (err), (unsigned long)hr ); + return hr; +} + + +/********************************************************** + ************** IGpgme Implementation ******************* + *********************************************************/ + +static HRESULT WINAPI +m_IGpgme_QueryInterface (IGpgme *iface, REFIID refiid, LPVOID *obj) +{ + ICOM_THIS (IGpgmeImpl,iface); + + /*fprintf (stderr,"*** m_IGpgme_QueryInterface(%p,%s)", + This, debugstr_guid(refiid));*/ + if ( IsEqualGUID (&IID_IUnknown, refiid) + || IsEqualGUID (&IID_IGpgme, refiid) ) { + *obj = This; + IGpgme_AddRef (iface); + fprintf (stderr," -> got %p\n", *obj); + return 0; + } + else if ( IsEqualGUID (&IID_IDispatch, refiid) ) { + HRESULT hr = IDispatch_QueryInterface (This->std_disp.disp, + refiid, obj); + /*fprintf (stderr," -> delegated, hr=%lx, got %p\n", + hr, hr? NULL: *obj);*/ + return hr; + } + /*fprintf (stderr," -> none\n");*/ + *obj = NULL; + return E_NOINTERFACE; +} + + +static ULONG WINAPI +m_IGpgme_AddRef (IGpgme *iface) +{ + ICOM_THIS (IGpgmeImpl,iface); + + return ++This->ref; +} + + +static ULONG WINAPI +m_IGpgme_Release (IGpgme *iface) +{ + ICOM_THIS (IGpgmeImpl,iface); + + if (--This->ref) + return This->ref; + + gpgme_release (This->mainctx); This->mainctx = NULL; + gpgme_data_release (This->plaintext); This->plaintext = NULL; + gpgme_data_release (This->ciphertext); This->ciphertext = NULL; + gpgme_recipients_release (This->rset); This->rset = NULL; + if (This->std_disp.disp) + IDispatch_Release (This->std_disp.disp); + if (This->std_disp.tinfo) + ITypeInfo_Release (This->std_disp.tinfo); + HeapFree(GetProcessHeap(),0,iface); + { + ULONG count = CoReleaseServerProcess (); + if (!count && my_exit_event) + SetEvent (my_exit_event); + } + return 0; +} + + +static HRESULT WINAPI +m_stub_IDispatch_GetTypeInfoCount (IGpgme *iface, unsigned int *pctinfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_stub_IDispatch_GetTypeInfo (IGpgme *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_stub_IDispatch_GetIDsOfNames (IGpgme *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_stub_IDispatch_Invoke (IGpgme *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExepInfo, UINT *puArgErr) +{ + return E_NOTIMPL; +} + + + +static HRESULT WINAPI +m_IGpgme_GetVersion (IGpgme *iface, BSTR *retvat) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_IGpgme_GetEngineInfo (IGpgme *iface, BSTR *retval) +{ + return E_NOTIMPL; +} + + +static HRESULT WINAPI +m_IGpgme_Cancel (IGpgme *iface) +{ + return E_NOTIMPL; +} + + +static HRESULT WINAPI +m_IGpgme_SetArmor (IGpgme *iface, BOOL yes) +{ + ICOM_THIS (IGpgmeImpl,iface); + + gpgme_set_armor (This->mainctx, yes); + return 0; +} + +static HRESULT WINAPI +m_IGpgme_GetArmor (IGpgme *iface, BOOL *retval) +{ + ICOM_THIS (IGpgmeImpl,iface); + + *retval = gpgme_get_armor (This->mainctx); + return 0; +} + + +static HRESULT WINAPI +m_IGpgme_SetTextmode (IGpgme *iface, BOOL yes) +{ + ICOM_THIS (IGpgmeImpl,iface); + + gpgme_set_textmode (This->mainctx, yes); + return 0; +} + +static HRESULT WINAPI +m_IGpgme_GetTextmode (IGpgme *iface, BOOL *retval) +{ + ICOM_THIS (IGpgmeImpl,iface); + + *retval = gpgme_get_textmode (This->mainctx); + return 0; +} + + +/* + * Put the data from VAL into a a Gpgme data object, which is passed by + * reference. Valid types of the Variant are: BSTR, SAFEARRAY of BYTE and + * SAFEARRAY of VARIANTS of signed or unsigned integers. + */ +static HRESULT WINAPI +set_data_from_variant (GpgmeData *data, VARIANT val, int *given_as_bstr) +{ + GpgmeError err = 0; + HRESULT hr; + unsigned char *buf; + SAFEARRAY *array; + size_t len; + int i; + + if ( val.vt == VT_BSTR) { + len = bstrtoutf8 (val.u.bstrVal, NULL, 0); + buf = _gpgme_malloc (len); + if (!buf) + return E_OUTOFMEMORY; + + if (bstrtoutf8 (val.u.bstrVal, buf, len) < 0) { + fprintf (stderr,"problem with bstrtoutf8\n"); + _gpgme_free (buf); + return E_FAIL; + } + + #if 0 + fprintf (stderr,"Got a BSTR (utf8):"); + for (i=0; i < len; i++) + fprintf (stderr, " %0X", buf[i] ); + putc ('\n', stderr); + #endif + gpgme_data_release (*data); *data = NULL; + err = gpgme_data_new_from_mem (data, buf, len, 0 /*no need to copy*/ ); + if (!err && given_as_bstr) + *given_as_bstr = 1; + } + else if ( val.vt == (VT_ARRAY|VT_UI1)) { + array = val.u.parray; + + /*fprintf (stderr,"Got an ARRAY of bytes:");*/ + hr = SafeArrayAccessData (array, (void**)&buf); + if (hr) { + fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr); + return hr; + } + len = array->rgsabound[0].cElements; + /*for (i=0; i < len; i++) + fprintf (stderr, " %0X", buf[i] ); + putc ('\n', stderr);*/ + + gpgme_data_release (*data); *data = NULL; + err = gpgme_data_new_from_mem (data, buf, len, 1 ); + SafeArrayUnaccessData (array); + if (given_as_bstr) + *given_as_bstr = 0; + } + else if ( val.vt == (VT_ARRAY|VT_VARIANT)) { + VARIANT *vp; + array = val.u.parray; + + /*fprintf (stderr,"Got an ARRAY of VARIANTS:");*/ + hr = SafeArrayAccessData (array, (void**)&vp); + if (hr) { + fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr); + return hr; + } + len = array->rgsabound[0].cElements; + /* allocate the array using the gpgme allocator so that we can + * later use a new without the copy set*/ + buf = _gpgme_malloc (len); + if (!buf) { + SafeArrayUnaccessData (array); + return E_OUTOFMEMORY; + } + /* coerce all array elements into rawtext */ + for (i=0; i < len; i++) { + switch (vp[i].vt) { + case VT_I1: buf[i] = (BYTE)vp[i].u.cVal; break; + case VT_I2: buf[i] = ((UINT)vp[i].u.iVal) & 0xff; break; + case VT_I4: buf[i] = ((ULONG)vp[i].u.lVal) & 0xff; break; + case VT_INT: buf[i] = ((UINT)vp[i].u.intVal) & 0xff; break; + case VT_UI1: buf[i] = vp[i].u.bVal; break; + case VT_UI2: buf[i] = vp[i].u.uiVal & 0xff; break; + case VT_UI4: buf[i] = vp[i].u.ulVal & 0xff; break; + case VT_UINT: buf[i] = vp[i].u.uintVal & 0xff; break; + default: + fprintf (stderr, "Invalid value in array as pos %d\n", i); + _gpgme_free (buf); + SafeArrayUnaccessData (array); + return E_INVALIDARG; + } + } + + /*for (i=0; i < len; i++) + fprintf (stderr, " %0X", buf[i] ); + putc ('\n', stderr);*/ + + gpgme_data_release (*data); *data = NULL; + err = gpgme_data_new_from_mem (data, buf, len, 0); + SafeArrayUnaccessData (array); + if (given_as_bstr) + *given_as_bstr = 0; + } + else { + fprintf (stderr, "Got a variant type = %d (0x%x)\n", + (int)val.vt, (int)val.vt ); + return E_INVALIDARG; /* not a safearray of bytes */ + } + return map_gpgme_error (err); +} + + +static HRESULT WINAPI +set_data_to_variant (GpgmeData data, VARIANT *retval, int use_bstr) +{ + GpgmeError err; + HRESULT hr; + SAFEARRAY *array; + char *p; + size_t nread, len; + int i; + + /* Get some info on the data */ + err = gpgme_data_rewind (data); + if (err ) { + fprintf (stderr, "*** gpgme_data_rewind failed: %d\n", err); + return map_gpgme_error (err); + } + err = gpgme_data_read (data, NULL, 0, &nread); + if (err && err != GPGME_EOF ) { + fprintf (stderr, "*** gpgme_data_read [length] failed: %d\n", err); + return map_gpgme_error (err); + } + len = nread; /*(eof returns a length of 0)*/ + /*fprintf (stderr,"*** %d bytes are availabe\n", (int)len);*/ + + /* convert it to the target data type */ + if (use_bstr) { + BSTR bs; + unsigned char *helpbuf; + + /* It is easier to allocate some helper storage */ + helpbuf = _gpgme_malloc (len); + if (!helpbuf) + return E_OUTOFMEMORY; + err = gpgme_data_read (data, helpbuf, len, &nread); + if (err ) { + _gpgme_free (helpbuf); + fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n", err); + return map_gpgme_error (err); + } + + bs = SysAllocStringLen (NULL, len+1); + if (!bs) { + _gpgme_free (helpbuf); + return E_OUTOFMEMORY; + } + + for (i=0, p=helpbuf; i < len; i++, p++) + bs[i] = *p; + bs[i] = 0; + _gpgme_free (helpbuf); + + /* Ready */ + VariantInit (retval); + retval->vt = VT_BSTR; + retval->u.bstrVal = bs; + } +#if 0 + else if (use_byte_array) { + array = SafeArrayCreateVector (VT_UI1, 0, len); + if (!array) + return E_OUTOFMEMORY; + + p = NULL; + hr = SafeArrayAccessData (array, (void**)&p); + if (hr) { + fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr); + SafeArrayDestroyData (array); + SafeArrayDestroy (array); + return hr; + } + if (len) { + err = gpgme_data_read (data, p, len, &nread); + if (err ) { + SafeArrayUnaccessData (array); + SafeArrayDestroyData (array); + SafeArrayDestroy (array); + fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n", + err); + return map_gpgme_error (err); + } + } + SafeArrayUnaccessData (array); + + /* pass the data to the caller */ + VariantInit (retval); + retval->vt = (VT_ARRAY|VT_UI1); + retval->u.parray = array; + } +#endif + else { /* Create an array of variants of bytes */ + VARIANT *v; + unsigned char *helpbuf; + + /* It is easier to allocate some helper storage */ + helpbuf = _gpgme_malloc (len); + if (!helpbuf) + return E_OUTOFMEMORY; + err = gpgme_data_read (data, helpbuf, len, &nread); + if (err ) { + _gpgme_free (helpbuf); + fprintf (stderr, "*** gpgme_data_read [data] failed: %d\n", err); + return map_gpgme_error (err); + } + + /* The create the array */ + array = SafeArrayCreateVector (VT_VARIANT, 0, len); + if (!array) { + _gpgme_free (helpbuf); + return E_OUTOFMEMORY; + } + + v = NULL; + hr = SafeArrayAccessData (array, (void**)&v); + if (hr) { + fprintf (stderr,"*** SafeArrayAccessData failed: hr=%lx\n", hr); + _gpgme_free (helpbuf); + SafeArrayDestroyData (array); + SafeArrayDestroy (array); + return hr; + } + + for (p=helpbuf; len; len--, v++) { + VariantInit (v); + v->vt = VT_UI1; + v->u.bVal = *p; + } + SafeArrayUnaccessData (array); + _gpgme_free (helpbuf); + + /* pass the data to the caller */ + VariantInit (retval); + retval->vt = (VT_ARRAY|VT_VARIANT); + retval->u.parray = array; + } + return 0; +} + + +static HRESULT WINAPI +m_IGpgme_SetPlaintext (IGpgme *iface, VARIANT val) +{ + ICOM_THIS (IGpgmeImpl,iface); + + return set_data_from_variant (&This->plaintext, val, + &This->plaintext_given_as_bstr); +} + + +static HRESULT WINAPI +m_IGpgme_GetPlaintext (IGpgme *iface, VARIANT *retval) +{ + ICOM_THIS (IGpgmeImpl,iface); + + /*fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This );*/ + return set_data_to_variant (This->plaintext, retval, + This->plaintext_given_as_bstr); +} + +static HRESULT WINAPI +m_IGpgme_SetCiphertext (IGpgme *iface, VARIANT val) +{ + ICOM_THIS (IGpgmeImpl,iface); + + return set_data_from_variant (&This->ciphertext, val, NULL); +} + +static HRESULT WINAPI +m_IGpgme_GetCiphertext (IGpgme *iface, VARIANT *retval) +{ + ICOM_THIS (IGpgmeImpl,iface); + + return set_data_to_variant (This->ciphertext, retval, + This->ciphertext_is_armored); +} + +static HRESULT WINAPI +m_IGpgme_ClearRecipients (IGpgme *iface) +{ + ICOM_THIS (IGpgmeImpl,iface); + + gpgme_recipients_release (This->rset); This->rset = NULL; + return 0; +} + + +static HRESULT WINAPI +m_IGpgme_AddRecipient (IGpgme *iface, BSTR name, signed short int trust) +{ + GpgmeError err; + int n; + char *p; + ICOM_THIS (IGpgmeImpl,iface); + + /*fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p, %d)\n", + This, (int)trust);*/ + if (!This->rset) { + err = gpgme_recipients_new (&This->rset); + if (err) + return map_gpgme_error (err); + } + + n = bstrtoutf8 (name, NULL, 0); + p = HeapAlloc (GetProcessHeap(), 0, n ); + if (!p) { + fprintf (stderr,"HeapAlloc failed: ec=%d\n", (int)GetLastError () ); + return E_OUTOFMEMORY; + } + if (bstrtoutf8 (name, p, n) < 0) { + fprintf (stderr,"problem with bstrtoutf8\n"); + HeapFree (GetProcessHeap(), 0, p); + return E_FAIL; + } + err = gpgme_recipients_add_name (This->rset, p); + HeapFree (GetProcessHeap(), 0, p); + return map_gpgme_error (err); +} + +static HRESULT WINAPI +m_IGpgme_ResetSignKeys (IGpgme *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_IGpgme_AddSignKey (IGpgme *iface, BSTR name) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_IGpgme_Encrypt (IGpgme *iface) +{ + GpgmeError err; + ICOM_THIS (IGpgmeImpl,iface); + + gpgme_data_release (This->ciphertext); + err = gpgme_data_new (&This->ciphertext); + if (err) + return map_gpgme_error (err); + + + This->ciphertext_is_armored = gpgme_get_armor (This->mainctx); + err = gpgme_op_encrypt (This->mainctx, This->rset, + This->plaintext, This->ciphertext); +#if 0 + if (!err ) { + char buf[100]; + size_t nread; + + err = gpgme_data_rewind ( This->ciphertext ); + if (err ) + fprintf (stderr, "*** gpgme_data_rewind failed: %d\n", err); + while ( !(err = gpgme_data_read ( This->ciphertext, + buf, 100, &nread )) ) { + fwrite ( buf, nread, 1, stderr ); + } + if (err != GPGME_EOF) + fprintf (stderr, "*** gpgme_data_read failed: %d\n", err); + err = 0; + } +#endif + + return map_gpgme_error (err); +} + +static HRESULT WINAPI +m_IGpgme_Sign (IGpgme *iface, short int signmode) +{ + ICOM_THIS (IGpgmeImpl,iface); + + fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This ); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +m_IGpgme_SignEncrypt (IGpgme *iface, short int signmode) +{ + ICOM_THIS (IGpgmeImpl,iface); + + fprintf (stderr,"*** " __PRETTY_FUNCTION__ "(%p)\n", This ); + + return E_NOTIMPL; +} + +#if 0 +static HRESULT WINAPI +m_IGpgme_GetSigStatus(GpgmeCtx c, int idx, + GpgmeSigStat *r_stat, time_t *r_created ); +{ + return 0; +} + + +static HRESULT WINAPI +m_IGpgme_GetSigKey (GpgmeCtx c, int idx, GpgmeKey *r_key); +{ + return 0; +} + +static HRESULT WINAPI +m_IGpgme_GetNotation(IGpgme *c, BSTR *retval) +{ + return 0; +} +#endif + + +static ICOM_VTABLE(IGpgme) igpgme_vtbl = +{ + /* IUnknown methods */ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + m_IGpgme_QueryInterface, + m_IGpgme_AddRef, + m_IGpgme_Release, + /* IDispatch methods */ + m_stub_IDispatch_GetTypeInfoCount, + m_stub_IDispatch_GetTypeInfo, + m_stub_IDispatch_GetIDsOfNames, + m_stub_IDispatch_Invoke, + /* Our methods */ + m_IGpgme_GetVersion, + m_IGpgme_GetEngineInfo, + m_IGpgme_Cancel, + m_IGpgme_SetArmor, + m_IGpgme_GetArmor, + m_IGpgme_SetTextmode, + m_IGpgme_GetTextmode, + m_IGpgme_SetPlaintext, + m_IGpgme_GetPlaintext, + m_IGpgme_SetCiphertext, + m_IGpgme_GetCiphertext, + m_IGpgme_ClearRecipients, + m_IGpgme_AddRecipient, + m_IGpgme_ResetSignKeys, + m_IGpgme_AddSignKey, + m_IGpgme_Encrypt, + m_IGpgme_Sign, + m_IGpgme_SignEncrypt +}; + + + +/*************************************************************** + ****************** Gpgme Factory **************************** + ***************************************************************/ + +static HRESULT WINAPI +m_GpgmeFactory_QueryInterface (IClassFactory *iface, + REFIID refiid, LPVOID *obj) +{ + ICOM_THIS (IClassFactoryImpl,iface); + + /*fprintf (stderr,"*** m_GpgmeFactory_QueryInterface(%p,%s)", + This, debugstr_guid(refiid));*/ + if ( IsEqualGUID (&IID_IUnknown, refiid) + || IsEqualGUID (&IID_IClassFactory, refiid) ) { + *obj = This; + /*fprintf (stderr," -> got %p\n", obj);*/ + return 0; + } + *obj = NULL; + /*fprintf (stderr," -> none\n");*/ + return E_NOINTERFACE; +} + +static ULONG WINAPI +m_GpgmeFactory_AddRef (IClassFactory *iface) +{ + ICOM_THIS(IClassFactoryImpl,iface); + return ++(This->ref); +} + +static ULONG WINAPI +m_GpgmeFactory_Release (IClassFactory *iface) +{ + ICOM_THIS(IClassFactoryImpl,iface); + return --(This->ref); +} + +static HRESULT WINAPI +m_GpgmeFactory_CreateInstance (IClassFactory *iface, IUnknown *outer, + REFIID refiid, LPVOID *r_obj ) +{ + /*ICOM_THIS(IClassFactoryImpl,iface);*/ + + fprintf (stderr,"*** m_GpgmeFactory_CreateInstance(%s)", + debugstr_guid(refiid) ); + if ( IsEqualGUID (&IID_IUnknown, refiid) + || IsEqualGUID (&IID_IGpgme, refiid) ) { + IGpgmeImpl *obj; + GpgmeCtx ctx; + GpgmeError err; + + + err = gpgme_new (&ctx); + if (err) { + fprintf (stderr," -> gpgme_new failed: %s\n", gpgme_strerror (err)); + return E_OUTOFMEMORY; + } + + obj = HeapAlloc (GetProcessHeap(), 0, sizeof *obj ); + if ( !obj) { + fprintf (stderr," -> out of core\n"); + gpgme_release (ctx); + return E_OUTOFMEMORY; + } + memset (obj, 0, sizeof *obj); + + ICOM_VTBL(obj) = &igpgme_vtbl; + obj->ref = 1; + obj->mainctx = ctx; + { /* Fixme: need to release some stuff on error */ + HRESULT hr; + ITypeLib *pTypeLib; + + hr = LoadRegTypeLib (&TLBID_Gpgcom, 1, 0, LANG_NEUTRAL, &pTypeLib); + if (hr) { + fprintf (stderr," -> LoadRegTypeLib failed: %lx\n", hr); + return hr; + } + hr = ITypeLib_GetTypeInfoOfGuid (pTypeLib, &IID_IGpgme, + &obj->std_disp.tinfo); + ITypeLib_Release (pTypeLib); + if (hr) { + fprintf (stderr," -> GetTypeInfoOfGuid failed: %lx\n", hr); + return hr; + } + hr = CreateStdDispatch ((IUnknown*)obj, obj, obj->std_disp.tinfo, + &obj->std_disp.disp); + if (hr) { + fprintf (stderr," -> CreateStdDispatch failed: %lx\n", hr); + return hr; + } + } + + CoAddRefServerProcess (); + *r_obj = obj; + fprintf (stderr," -> created %p\n", obj ); + return 0; + } + fprintf (stderr," -> no interface\n" ); + *r_obj = NULL; + return E_NOINTERFACE; +} + +static HRESULT WINAPI +m_GpgmeFactory_LockServer (IClassFactory *iface, BOOL dolock ) +{ + if (dolock) { + CoAddRefServerProcess (); + } + else { + ULONG count = CoReleaseServerProcess (); + if (!count && my_exit_event) + SetEvent (my_exit_event); + } + return 0; +} + +static ICOM_VTABLE(IClassFactory) igpgme_factory_vtbl = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + m_GpgmeFactory_QueryInterface, + m_GpgmeFactory_AddRef, + m_GpgmeFactory_Release, + m_GpgmeFactory_CreateInstance, + m_GpgmeFactory_LockServer +}; +static IClassFactoryImpl igpgme_CF = {&igpgme_factory_vtbl, 1 }; + +void +igpgme_register_exit_event (HANDLE ev) +{ + my_exit_event = ev; +} + + +IClassFactory * +igpgme_factory_new ( CLSID *r_clsid ) +{ + *r_clsid = CLSID_Gpgme; + IClassFactory_AddRef((IClassFactory*)&igpgme_CF); + return (IClassFactory*)&igpgme_CF; +} + +void +igpgme_factory_release ( IClassFactory *factory ) +{ + /* it's static - nothing to do */ +} diff --git a/branches/gpgme-0-3-branch/complus/igpgme.h b/branches/gpgme-0-3-branch/complus/igpgme.h new file mode 100644 index 00000000..fa967627 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/igpgme.h @@ -0,0 +1,163 @@ +/* igpgme.h - COM+ class IGpgme + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef IGPGME_H +#define IGPGME_H 1 + +#include <ole2.h> + +DEFINE_GUID(CLSID_Gpgme, 0x3811fd40, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); +#if 0 +DEFINE_GUID(CLSID_GpgmeData, 0x3811fd41, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); +DEFINE_GUID(CLSID_GpgmeKey, 0x3811fd42, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); +DEFINE_GUID(CLSID_GpgmeRSet, 0x3811fd43, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); +#endif + +DEFINE_GUID(TLBID_Gpgcom, 0x3811fd48, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); +DEFINE_GUID(APPID_Gpgcom, 0x3811fd4f, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); + + +DEFINE_GUID(IID_IGpgme, 0x3811fd50, 0x7f72, 0x11d5, + 0x8c, 0x9e, 0x00, 0x80, 0xad, 0x19, 0x0c, 0xd5); + +typedef struct IGpgme IGpgme; + +void igpgme_register_exit_event (HANDLE ev); +IClassFactory *igpgme_factory_new( CLSID *r_clsid ); +void igpgme_factory_release ( IClassFactory *factory ); + + +/******************************************** + ***** The IGpgme interface ***************** + ********************************************/ + +#define ICOM_INTERFACE IGpgme + +#define IGpgme_METHODS \ + ICOM_METHOD1(HRESULT,GetVersion, BSTR*,) \ + ICOM_METHOD1(HRESULT,GetEngineInfo, BSTR*,) \ + ICOM_METHOD(HRESULT,Cancel) \ + ICOM_METHOD1(HRESULT,SetArmor,BOOL,) \ + ICOM_METHOD1(HRESULT,GetArmor,BOOL*,) \ + ICOM_METHOD1(HRESULT,SetTextmode,BOOL,) \ + ICOM_METHOD1(HRESULT,GetTextmode,BOOL*,) \ + ICOM_METHOD1(HRESULT,SetPlaintext,VARIANT,) \ + ICOM_METHOD1(HRESULT,GetPlaintext,VARIANT*,) \ + ICOM_METHOD1(HRESULT,SetCiphertext,VARIANT,) \ + ICOM_METHOD1(HRESULT,GetCiphertext,VARIANT*,) \ + ICOM_METHOD(HRESULT,ClearRecipients) \ + ICOM_METHOD2(HRESULT,AddRecipient,BSTR,,signed short int,) \ + ICOM_METHOD(HRESULT,ResetSignKeys) \ + ICOM_METHOD1(HRESULT,AddSignKey,BSTR,) \ + ICOM_METHOD(HRESULT,Encrypt) \ + ICOM_METHOD1(HRESULT,Sign,signed short int,) \ + ICOM_METHOD1(HRESULT,SignEncrypt,signed short int,) + +#if 0 + ICOM_METHOD1(HRESULT,SetKeylistMode,) + ICOM_METHOD1(HRESULT,SetPassphraseCB,) + ICOM_METHOD1(HRESULT,SetProgressCB,) + ICOM_METHOD1(HRESULT,SignersClear,) + ICOM_METHOD1(HRESULT,SignersAdd,) + ICOM_METHOD1(HRESULT,SignersEnum,) + ICOM_METHOD1(HRESULT,GetSigStatus,) + ICOM_METHOD1(HRESULT,GetNotation,) +#endif + +#define IGpgme_IMETHODS \ + IDispatch_IMETHODS \ + IGpgme_METHODS + +ICOM_DEFINE(IGpgme,IDispatch) +#undef ICOM_INTERFACE + + +/*** IUnknown methods ***/ +#define IGpgme_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IGpgme_AddRef(p) ICOM_CALL (AddRef,p) +#define IGpgme_Release(p) ICOM_CALL (Release,p) +/*** IGpgme methods ***/ +#define IGpgme_GetVersion(p,r) ICOM_CALL1(GetVersion,p,r) +#define IGpgme_GetEngineInfo(p,r) ICOM_CALL1(GetEngineInfo,p,r) +#define IGpgme_Cancel(p,a) ICOM_CALL1(Cancel,p,a) +#define IGpgme_SetArmor(p,a) ICOM_CALL1(SetArmor,p,a) +#define IGpgme_GetArmor(p,a) ICOM_CALL1(GetArmor,p,a) +#define IGpgme_SetTextmode(p,a) ICOM_CALL1(SetTextmode,p,a) +#define IGpgme_GetTextmode(p,a) ICOM_CALL1(GetTextmode,p,a) +#define IGpgme_SetPlaintext(p,a) ICOM_CALL1(SetPlaintext,p,a) +#define IGpgme_GetPlaintext(p,a) ICOM_CALL1(GetPlaintext,p,a) +#define IGpgme_SetCiphertext(p,a) ICOM_CALL1(SetCiphertext,p,a) +#define IGpgme_GetCiphertext(p,a) ICOM_CALL1(GetCiphertext,p,a) +#define IGpgme_ClearRecipients(p) ICOM_CALL (ClearRecipients,p) +#define IGpgme_AddRecipient(p,a,b) ICOM_CALL2(AddRecipient,p,a,b) +#define IGpgme_ResetSignKeys(p) ICOM_CALL (ResetSignKeys,p) +#define IGpgme_AddSignKey(p,a) ICOM_CALL (AddSignKey,p,a) +#define IGpgme_Encrypt(p) ICOM_CALL (Encrypt,p) +#define IGpgme_Sign(p,a) ICOM_CALL (Sign,p,a) +#define IGpgme_SignEncrypt(p,a) ICOM_CALL (SignEncrypt,p,a) +#if 0 +#define IGpgme_SetKeylistMode(p,a) ICOM_CALL1(SetKeylistMode,p,a) +#define IGpgme_SetPassphraseCB(p,a) ICOM_CALL1(SetPassphraseCB,p,a) +#define IGpgme_SetProgressCB(p,a) ICOM_CALL1(SetProgressCB,p,a) +#define IGpgme_SignersClear(p,a) ICOM_CALL1(SignersClear,p,a) +#define IGpgme_SignersAdd(p,a) ICOM_CALL1(SignersAdd,p,a) +#define IGpgme_SignersEnum(p,a) ICOM_CALL1(SignersEnum,p,a) +#define IGpgme_GetSigStatus(p,a) ICOM_CALL1(GetSigStatus,p,a) +#define IGpgme_GetSigKey(p,a) ICOM_CALL1(GetSigKey,p,a) +#define IGpgme_GetNotation(p,a) ICOM_CALL1(GetNotation,p,a) +#endif + + +#if 0 +/******************************************** + ***** The IGpgmeKey interface ************** + ********************************************/ + +#define ICOM_INTERFACE IGpgmeKey + +#define IGpgmeKey_METHODS \ + ICOM_METHOD1(HRESULT,GetVersion, BSTR,) \ + ICOM_METHOD1(HRESULT,GetEngineInfo, BSTR,) + + +#define IGpgmeKey_IMETHODS \ + IUnknown_IMETHODS \ + IGpgmeKey_METHODS + +ICOM_DEFINE(IGpgmeKey,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IGpgmeKey_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IGpgmeKey_AddRef(p) ICOM_CALL (AddRef,p) +#define IGpgmeKey_Release(p) ICOM_CALL (Release,p) +/*** IGpgmeKey methods ***/ +#define IGpgmeKey_GetVersion(p,r) ICOM_CALL1(GetVersion,p,r) +#define IGpgmeKey_GetEngineInfo(p,r) ICOM_CALL1(GetEngineInfo,p,r) +#endif + +#endif /*IGPGME_H*/ + diff --git a/branches/gpgme-0-3-branch/complus/main.h b/branches/gpgme-0-3-branch/complus/main.h new file mode 100644 index 00000000..7e48ad4f --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/main.h @@ -0,0 +1,49 @@ +/* main.h - GPGME COM+ component + * Copyright (C) 2000 Werner Koch (dd9jn) + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef COMPLUS_MAIN_H +#define COMPLUS_MAIN_H + +#include "xmalloc.h" +#include "stringhelp.h" +#include "logging.h" + + +#define _(a) (a) +#define N_(a) (a) + + +struct { + int verbose; + int quiet; + unsigned int debug; + char *homedir; +} opt; + + + +#endif /* COMPLUS_MAIN_H */ + + + + + + + diff --git a/branches/gpgme-0-3-branch/complus/regtlb.c b/branches/gpgme-0-3-branch/complus/regtlb.c new file mode 100644 index 00000000..4ea1342c --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/regtlb.c @@ -0,0 +1,70 @@ +/* regtlb.c - Register a type library + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> +#include <windows.h> + +#include "xmalloc.h" +#include "oleauto.h" + +int +main (int argc, char **argv) +{ + ITypeLib *pTypeLib; + wchar_t *fname; + HRESULT hr; + size_t n; + + if ( argc != 2 ) { + fprintf (stderr,"usage: regtlb foo.tlb\n"); + return 1; + } + + n = mbstowcs (NULL, argv[1], strlen(argv[1])+1); + fprintf (stderr, "need %d bytes\n", (int)n); + fname = xmalloc ((n+1)*sizeof *fname); + mbstowcs (fname, argv[1], strlen (argv[1])+1); + + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + if (hr) + fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr); + + hr = LoadTypeLibEx (fname, REGKIND_REGISTER, &pTypeLib); + if (hr) + fprintf (stderr, "LoadTypeLibEx() failed: hr=%lx\n", hr); + + ITypeLib_Release (pTypeLib); + + CoUninitialize (); + return 0; +} + + + + + + diff --git a/branches/gpgme-0-3-branch/complus/tgpgcom.c b/branches/gpgme-0-3-branch/complus/tgpgcom.c new file mode 100644 index 00000000..27516b1d --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/tgpgcom.c @@ -0,0 +1,157 @@ +/* tgpgcom.c - Test the IGpgme classes + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <time.h> +#include <windows.h> + +#define INITGUID +#include "igpgme.h" + + +int +main (int argc, char **argv) +{ + IUnknown *pUnknown = NULL; + IGpgme *pGpgme; + HRESULT hr; + BSTR bs; + + hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED); + if (hr) + fprintf (stderr, "CoInitializeEx() failed: hr=%lu\n", hr); + + fprintf (stderr, "system initialized\n"); + hr = CoCreateInstance (&CLSID_Gpgme, NULL, CLSCTX_LOCAL_SERVER, + &IID_IUnknown, (void**)&pUnknown ); + if (hr) + fprintf (stderr, "CoCreateInstance() failed: hr=%lx\n", hr); + if (!pUnknown) + exit (1); + + fprintf (stderr,"got object %p - querying %s\n", + pUnknown, debugstr_guid(&IID_IGpgme)); + hr = IGpgme_QueryInterface (pUnknown, &IID_IGpgme, (void**)&pGpgme); + if (hr) { + fprintf (stderr, "QueryInterface() failed: hr=%lx\n", hr); + goto leave; + } + fprintf (stderr, "got interface %p\n", pGpgme); + + hr = IGpgme_SetArmor (pGpgme, 1); + fprintf (stderr, "SetArmor returned %lx\n", hr); + + hr = IGpgme_SetTextmode (pGpgme, 0); + fprintf (stderr, "SetTextmode returned %lx\n", hr); + + hr = IGpgme_ClearRecipients (pGpgme); + fprintf (stderr, "ClearRecipients returned %lx\n", hr); + + bs = SysAllocString (L"alice"); + if (!bs) + fprintf (stderr, "SysAllocString failed: ec=%d\n", (int)GetLastError()); + else { + int i; + + for (i=-4; i < 12; i++ ) + fprintf (stderr," %02X", ((unsigned char*)bs)[i] ); + putc ('\n', stderr); + } + hr = IGpgme_AddRecipient (pGpgme, bs, -1); + fprintf (stderr, "AddRecipients returned %lx\n", hr); + + { + SAFEARRAY *sa; + VARIANT v; + char *p; + + sa = SafeArrayCreateVector (VT_UI1, 0, 20); + if (!sa) { + fprintf (stderr, "SafeArrayCreateVector failed\n"); + goto leave; + } + + hr = SafeArrayAccessData (sa, (void**)&p); + if (hr) { + fprintf (stderr,"SafeArrayAccessData failed: hr=%lx\n", hr); + goto leave; + } + + memcpy (p, "=> Omnis enim res <=", 20 ); + SafeArrayUnaccessData (sa); + + VariantInit (&v); + v.vt = (VT_ARRAY|VT_UI1); + v.u.parray = sa; + + hr = IGpgme_SetPlaintext (pGpgme, v ); + fprintf (stderr, "SetPlaintext returned %lx\n", hr); + SafeArrayDestroyData (sa); + SafeArrayDestroy (sa); + + VariantClear (&v); + } + + hr = IGpgme_Encrypt (pGpgme); + fprintf (stderr, "Encrypt returned %lx\n", hr); + + { + VARIANT v; + + hr = IGpgme_GetCiphertext (pGpgme, &v); + fprintf (stderr, "GetCiphertext returned %lx\n", hr); + if (!hr) { + if (v.vt != (VT_ARRAY|VT_UI1)) + fprintf (stderr, "Invalid array typed returned\n"); + else { + unsigned char *p; + + hr = SafeArrayAccessData (v.u.parray, (void**)&p); + if (hr) + fprintf (stderr,"*** SafeArrayAccessData failed: %lx\n", hr); + else { + size_t arraysize = v.u.parray->rgsabound[0].cElements; + fprintf (stderr,"*** got %d bytes\n", (int)arraysize); + for (;arraysize; arraysize--, p++ ) + putc (*p, stderr); + SafeArrayUnaccessData (v.u.parray); + } + } + } + } + IGpgme_Release (pGpgme); + + leave: + CoUninitialize (); + fprintf (stderr, "system uninitialized\n"); + return 0; +} + + + + + + diff --git a/branches/gpgme-0-3-branch/complus/utf8.c b/branches/gpgme-0-3-branch/complus/utf8.c new file mode 100644 index 00000000..0237a629 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/utf8.c @@ -0,0 +1,236 @@ +/* + * UTF-8 support routines + * + * Copyright 2000 Alexandre Julliard + * + * Taken from WINE, so the usual WINE copyright applies: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <windows.h> + +#include <ole2.h> + +/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ +static const char utf8_length[128] = +{ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */ + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */ + 3,3,3,3,3,3,3,3,4,4,4,4,5,5,0,0 /* 0xf0-0xff */ +}; + +/* first byte mask depending on UTF-8 sequence length */ +static const unsigned char utf8_mask[6] = { 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; + +/* minimum Unicode value depending on UTF-8 sequence length */ +static const unsigned int utf8_minval[6] = { 0x0, 0x80, 0x800, 0x10000, 0x200000, 0x4000000 }; + + +/* query necessary dst length for src string */ +inline static int get_length_wcs_utf8( const WCHAR *src, unsigned int srclen ) +{ + int len; + + for (len = 0; srclen; srclen--, src++, len++) + { + if (*src >= 0x80) + { + len++; + if (*src >= 0x800) len++; + } + } + return len; +} + +/* wide char to UTF-8 string conversion */ +/* return -1 on dst buffer overflow */ +int utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen ) +{ + char *orig_dst = dst; + + if (!dstlen) return get_length_wcs_utf8( src, srclen ); + + for (; srclen; srclen--, src++) + { + WCHAR ch = *src; + + if (ch < 0x80) /* 0x00-0x7f: 1 byte */ + { + if (!dstlen--) return -1; /* overflow */ + *dst++ = ch; + continue; + } + + if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ + { + if ((dstlen -= 2) < 0) return -1; /* overflow */ + dst[1] = 0x80 | (ch & 0x3f); + ch >>= 6; + dst[0] = 0xc0 | ch; + dst += 2; + continue; + } + + /* 0x800-0xffff: 3 bytes */ + + if ((dstlen -= 3) < 0) return -1; /* overflow */ + dst[2] = 0x80 | (ch & 0x3f); + ch >>= 6; + dst[1] = 0x80 | (ch & 0x3f); + ch >>= 6; + dst[0] = 0xe0 | ch; + dst += 3; + } + return dst - orig_dst; +} + +/* query necessary dst length for src string */ +inline static int get_length_mbs_utf8( const unsigned char *src, int srclen ) +{ + int ret; + const unsigned char *srcend = src + srclen; + + for (ret = 0; src < srcend; ret++) + { + unsigned char ch = *src++; + if (ch < 0xc0) continue; + + switch(utf8_length[ch-0x80]) + { + case 5: + if (src >= srcend) return ret; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) continue; + src++; + case 4: + if (src >= srcend) return ret; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) continue; + src++; + case 3: + if (src >= srcend) return ret; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) continue; + src++; + case 2: + if (src >= srcend) return ret; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) continue; + src++; + case 1: + if (src >= srcend) return ret; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) continue; + src++; + } + } + return ret; +} + +/* UTF-8 to wide char string conversion */ +/* return -1 on dst buffer overflow, -2 on invalid input char */ +int utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen ) +{ + int len, count; + unsigned int res; + const char *srcend = src + srclen; + + if (!dstlen) return get_length_mbs_utf8( src, srclen ); + + for (count = dstlen; count && (src < srcend); count--, dst++) + { + unsigned char ch = *src++; + if (ch < 0x80) /* special fast case for 7-bit ASCII */ + { + *dst = ch; + continue; + } + len = utf8_length[ch-0x80]; + res = ch & utf8_mask[len]; + + switch(len) + { + case 5: + if (src >= srcend) goto done; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) goto bad; + res = (res << 6) | ch; + src++; + case 4: + if (src >= srcend) goto done; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) goto bad; + res = (res << 6) | ch; + src++; + case 3: + if (src >= srcend) goto done; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) goto bad; + res = (res << 6) | ch; + src++; + case 2: + if (src >= srcend) goto done; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) goto bad; + res = (res << 6) | ch; + src++; + case 1: + if (src >= srcend) goto done; /* ignore partial char */ + if ((ch = *src ^ 0x80) >= 0x40) goto bad; + res = (res << 6) | ch; + src++; + if (res < utf8_minval[len]) goto bad; + if (res >= 0x10000) goto bad; /* FIXME: maybe we should do surrogates here */ + *dst = res; + continue; + } + bad: + if (flags & MB_ERR_INVALID_CHARS) return -2; /* bad char */ + *dst = (WCHAR)'?'; + } + if (src < srcend) return -1; /* overflow */ +done: + return dstlen - count; +} + + +int +bstrtoutf8 ( BSTR src, char *dst, size_t dstlen ) +{ + size_t srclen, needed; + int n; + + srclen = src? SysStringLen (src): 0; + + needed = srclen? (utf8_wcstombs (src, srclen, NULL, 0) + 1) : 1; + if (!dst || !dstlen) + return needed; + if (dstlen < needed) + return -1; + if (srclen) { + n = utf8_wcstombs (src, srclen, dst, dstlen); + if (n < 0) + return -1; + } + else + n = 0; + dst[n] = 0; + return n; +} + + + diff --git a/branches/gpgme-0-3-branch/complus/vbtest.html b/branches/gpgme-0-3-branch/complus/vbtest.html new file mode 100644 index 00000000..03df4636 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/vbtest.html @@ -0,0 +1,47 @@ +<html> +<head><title>g10 code - GPGCOM test</title> + +<object id="gpg" + classid="CLSID:3811fd40-7f72-11d5-8c9e-0080ad190cd5"> +</object> + +<script language="VBScript"> +Sub encrypt_text + On error resume next + Dim TheForm, plain + + set TheForm = Document.forms ("MyForm") + gpg.armor = True + gpg.plaintext = TheForm.clear.value + gpg.ClearRecipients + gpg.AddRecipient TheForm.recp.value + Err.Clear + gpg.Encrypt + if Err <> 0 then + TheForm.encoded.value = "Error: " & CStr(Err.Number) + else + TheForm.encoded.value = gpg.ciphertext + end if +end sub +</script> +</head> +<body> +<h1>Silly Gpgcom test page</h1> + +<form id="MyForm"> +<textarea name="clear" rows = 3 cols=40>Please enter the text here</textarea> +<p> +Encrypt for <input name="recp" value="alice"> +<input type="button" name="MyAction" value="Encrypt" + language="VBScript" onclick="encrypt_text()"> +<p> +<textarea name="encoded" rows=10 cols=75></textarea> +</form> + +<p> + +</body> +</html> + + + diff --git a/branches/gpgme-0-3-branch/complus/vbtest.vbs b/branches/gpgme-0-3-branch/complus/vbtest.vbs new file mode 100644 index 00000000..8246b456 --- /dev/null +++ b/branches/gpgme-0-3-branch/complus/vbtest.vbs @@ -0,0 +1,39 @@ +' Demo script to generate a RFC2015 compliant message using Gpgcom +Dim gpg, body, crlf + +crlf = chr(10) & chr(13) + +' Create out Gpgcom object +set gpg = CreateObject("Gpgcom.Gpgme") +' We must use the ASCII armor and switch to textmode +gpg.armor = true +gpg.textmode = true + +' Set the secret message +gpg.plaintext = "This is the secret message." 'or: InputBox('Enter message:") + +' Set the Recipient. You may also use a keyID or an fingerprint +gpg.AddRecipient "alice" + +' And encrypt the stuff +gpg.encrypt + +' Build the MIME message +body = "Content-Type: multipart/encrypted; boundary=" +body = body & Chr(34) & "=-=-=-=" & Chr(34) & crlf & " protocol=" & Chr(34) +body = body & "application/pgp-encrypted" & Chr(34) & crlf & crlf +body = body & "--=-=-=-=" & crlf +body = body & "Content-Type: application/pgp-encrypted" & crlf & crlf +body = body & "Version: 1" & crlf & crlf +body = body & "--=-=-=-=" & crlf +body = body & "Content-Type: application/octet-stream" & crlf & crlf +body = body & gpg.ciphertext +body = body & "--=-=-=-=--" & crlf + +' And display it +Print body + +' output function for the windows scripting host +sub Print(x) + WScript.Echo x +end sub |