Add a passphrase callback and minor changes to the interface

This commit is contained in:
Werner Koch 2000-12-12 13:31:25 +00:00
parent 874f12ea70
commit edcc338a59
34 changed files with 3250 additions and 145 deletions

3
README
View File

@ -9,7 +9,8 @@ http://www.gnupg.org/cvs-access.html . If you use passphrases for
your keys, you should get the gpg-agent which comes with the GnuPG
unstable version (either CVS HEAD or
ftp.gnupg.org/pub/gcrypt/alpha/gnupg/gnupg-1.1.2.tar.gz) and install
the agent from the agent subdirectory.
the agent from the agent subdirectory or use the new
gpgme_set_passphrase_cb()
Please subscribe to the gnupg-devel@gnupg.org mailing list if you want
to do serious work.

View File

@ -1,12 +1,17 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = WINE-LICENSE WINE-AUTHORS
# No need to install this becuase we are cross-compiling anyway.
noinst_PROGRAMS = gpgme
noinst_PROGRAMS = gpgcom
INCLUDES = -I$(top_srcdir)/jnlib
LDADD = -L ../jnlib -ljnlib
gpgme_SOURCES = main.c main.h
comheaders = obj_base.h basetsd.h guiddef.h wtypes.h
gpgcom_SOURCES = main.c main.h \
$(comheaders) \
ignupg.c ignupg.h

331
complus/WINE-AUTHORS Normal file
View File

@ -0,0 +1,331 @@
@c This file is processed by GNU's TeXinfo
@c If you modify it or move it to another location, make sure that
@c TeXinfo works (type `make' in directory documentation).
@c This is a list of the Wine authors and copyright holders.
Wine is available thanks to the work of:
James Abbatiello,
Michael Abd-El-Malek,
Howard Abrams,
Mark G. Adams,
Bruno Afonso,
Samir Al-Battran,
Guy Albertelli,
Gustavo Junior Alves,
Bob Amstadt,
Dag Asheim,
Jim Aston,
Martin Ayotte,
Viktor Babrian,
Karl Backström,
Bradley Baetz,
Peter Bajusz,
Andre Malafaya Baptista,
Aaron Barnes,
Jean-Claude Batista,
Marcel Baur,
Francis Beaudet,
Tom Bech,
Matthew Becker,
Georg Beyerle,
Ross Biro,
Dennis Björklund,
Zygo Blaxell,
Martin Boehme,
Francois Boisvert,
Pim Bollen,
Uwe Bonnes,
Peter Bortas,
Noel Borthwick,
Erik Bos,
Fons Botman,
Sylvain Bouchard,
Frederic Boulanger,
Justin Bradford,
John Brezak,
Andrew Bulhak,
John Burton,
Jonathan Buzzard,
Jose Marcos López Caravaca,
Eddie Carpenter,
Niels de Carpentier,
Mike Castle,
Ron Cemer,
Gordon Chaffee,
Gael de Chalendar,
Jimen Ching,
Geoff Clare,
Robert 'Admiral' Coeyman,
Richard Cohen,
Jean-Claude Cote,
Stephen Crowley,
Pascal Cuoq,
David A. Cuthbert,
Brian Joseph Czapiga,
Ulrich Czekalla,
Huw D. M. Davies,
Moses DeJong,
Petar Djukic,
Roman Dolejsi,
Frans van Dorsselaer,
Rikhardur Egilsson,
Morten Eriksen,
Chris Faherty,
Carsten Fallesen,
Paul Falstad,
David Faure,
Wesley Filardo,
Claus Fischer,
Olaf Flebbe,
Chad Fraleigh,
Matthew Francis,
Philippe Froidevaux,
Peter Galbavy,
Peter Ganten,
Ramon Garcia,
Jeff Garzik,
Julio Cesar Gazquez,
Klaas van Gend,
Abey George,
Brian Gerst,
Matthew Ghio,
Jody Goldberg,
David Golding,
François Gouget,
Hans de Graaff,
David Grant,
Albert den Haan,
Jess Haas,
Robert W Hall,
Noomen Hamza,
Charles M. Hannum,
Adrian Harvey,
John Harvey,
James Hatheway,
Kalevi J Hautaniemi,
Bill Hawes,
Lars Heete,
Cameron Heide,
Bernd Herd,
Theodore S. Hetke,
Haithem Hmida,
Jochen Hoenicke,
Henning Hoffmann,
Kevin Holbrook,
Nick Holloway,
Onno Hovers,
Jeffrey Hsu,
Peter Hunnisett,
Miguel de Icaza,
Jukka Iivonen,
Kostya Ivanov,
Serge Ivanov,
Lee Jaekil,
Gautam Jain,
Niels Kristian Bech Jensen,
Rajeev Jhangiani,
Bill Jin,
Jeff Johann,
Alexandre Julliard,
Bang Jun-Young,
James Juran,
Achim Kaiser,
Alexander Kanavin,
Jukka Kangas,
Pavel Kankovsky,
Michael Karcher,
Niclas Karlsson,
Jochen Karrer,
Don Kelly,
Andreas Kirschbaum,
Rein Klazes,
Albrecht Kleine,
Dietmar Kling,
Eric Kohl,
Jon Konrath,
Alex Korobka,
Zoltan Kovacs,
Greg Kreider,
Anand Kumria,
Ove Kåven,
Scott A. Laird,
David Lee Lambert,
Stephen Langasek,
Sean Langley,
Dan Langlois,
Alexander Larsson,
David Lassonde,
Stefan Leichter,
Karl Lessard,
Pascal Lessard,
Andrew Lewycky,
John Li,
Weisheng Li,
Xiang Li,
Per Lindström,
Brian Litzinger,
Juergen Lock,
Martin von Loewis,
Michiel van Loon,
Richard A Lough,
Alexander V. Lukyanov,
Jiuming Luo,
Stephane Lussier,
David Luyer,
José Marcos López,
Kenneth MacDonald,
Peter MacDonald,
Pierre Mageau,
William Magro,
Juergen Marquardt,
Ricardo Massaro,
Keith Matthews,
Joerg Mayer,
Michael McCormack,
Jason McMullan,
Caolan McNamara,
Marcus Meissner,
Graham Menhennitt,
David Metcalfe,
Toufic Milan,
Paul Millar,
Bruce Milner,
Steffen Moeller,
Andreas Mohr,
Slava Monich,
James Moody,
Chris Morgan,
Kai Morich,
Richard Mortimer,
Vasudev Mulchandani,
Rick Mutzke,
Philippe De Muyter,
Itai Nahshon,
Jonathan Naylor,
Tim Newsome,
Thuy Nguyen,
Kristian Nielsen,
Damien O'Neill,
Henrik Olsen,
Gerard Patel,
Michael Patra,
Murali Pattathe,
Dimitrie O. Paun,
Bernd Paysan,
Brad Pepers,
Jim Peterson,
Gerald Pfeifer,
Dave Pickles,
Ian Pilcher,
Brian Pirie,
Michael Poole,
Eric Pouech,
Robert Pouliot,
Vahid Pourlotfali,
Chad Powell,
Joseph Pranevich,
Alex Priem,
Paul Quinn,
Pete Ratzlaff,
Ron Record,
Petter Reinholdtsen,
Keith Reynolds,
Slaven Rezic,
John Richardson,
Rick Richardson,
Douglas Ridgway,
Robert Riggs,
Bernhard Rosenkraenzer,
Matthew Robertson,
Pavel Roskin,
Herbert Rosmanith,
Lilia Roumiantseva,
Johannes Ruscheinski,
Adam Sacarny,
Ivan de Saedeleer,
Thomas Sandford,
Constantine Sapuntzakis,
Pablo Saratxaga,
Carl van Schaik,
Daniel Schepler,
Christian Schlaile,
Peter Schlaile,
Ulrich Schmid,
Bernd Schmidt,
Ian Schmidt,
Juergen Schmied,
Ingo Schneider,
Victor Schneider,
John Sheets,
Yngvi Sigurjonsson,
Stephen Simmons,
Jesper Skov,
Rick Sladkey,
William Smith,
Jaroslaw Piotr Sobieszek,
Patrick Spinler,
Sylvain St-Germain,
Gavriel State,
Sheri Steeves,
Norman Stevens,
Dominik Strasser,
Patrik Stridvall,
Vadim Strizhevsky,
Bertho Stultiens,
Abraham Sudhakar,
Charles Suprin,
James Sutherland,
Erik Svendsen,
Tristan Tarrant,
Andrew Taylor,
Joshua Thielen,
Dirk Thierbach,
Jean-Louis Thirot,
Duncan C Thomson,
Adrian Thurston,
Goran Thyni,
Steve Tibbett,
Dmitry Timoshkov,
Jimmy Tirtawangsa,
Jon Tombs,
Linus Torvalds,
Luc Tourangeau,
Jeff Tranter,
Gregory Trubetskoy,
Petri Tuomola,
Sergey Turchanov,
Lionel Ulmer,
Moshe Vainer,
Michael Veksler,
Sven Verdoolaege,
Todd Vierling,
Erez Volk,
Jerome Vouillon,
Duc Vuong,
Ronan Waide,
Martin Walker,
Owen Wang,
Eric Warnke,
Leigh Wedding,
Randy Weems,
Manfred Weichel,
Ulrich Weigand,
Morten Welinder,
Jeremy White,
Len White,
Lawson Whitney,
Jan Willamowius,
Carl Williams,
Eric Williams,
Cliff Wright,
Karl Guenter Wuensch,
Eric Youngdale,
James Youngman,
Nikita V. Youshchenko,
Mikolaj Zalewski,
John Zero,
Yuxi Zhang,
Nathan Zorich,
Luiz Otavio L. Zorzella,
and Per Ångström.

26
complus/WINE-LICENSE Normal file
View File

@ -0,0 +1,26 @@
This is the license file as it appeared in the CVS version of
Wine at cvs@rhlx01.fht-esslingen.de:/home/wine as of 2000-12-04
where only AUTHORS has been renamed to WINE-AUTHORS. It applies
to the header files establishing the COM+ framework
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
for a complete list)
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.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

160
complus/basetsd.h Normal file
View File

@ -0,0 +1,160 @@
/* basetsd.h - Compilers that uses ILP32, LP64 or P64 type models
for both Win32 and Win64 are supported by this file.
Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
for a complete list)
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.
*/
#ifndef __WINE_BASETSD_H
#define __WINE_BASETSD_H
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
/*
* Win32 was easy to implement under Unix since most (all?) 32-bit
* Unices uses the same type model (ILP32) as Win32, where int, long
* and pointer are 32-bit.
*
* Win64, however, will cause some problems when implemented under Unix.
* Linux/{Alpha, Sparc64} and most (all?) other 64-bit Unices uses
* the LP64 type model where int is 32-bit and long and pointer are
* 64-bit. Win64 on the other hand uses the P64 (sometimes called LLP64)
* type model where int and long are 32 bit and pointer is 64-bit.
*/
/* Type model indepent typedefs */
typedef char __int8;
typedef unsigned char __uint8;
typedef short __int16;
typedef unsigned short __uint16;
typedef int __int32;
typedef unsigned int __uint32;
typedef long long __int64;
typedef unsigned long long __uint64;
#if defined(_WIN64)
typedef __uint32 __ptr32;
typedef void *__ptr64;
#else /* FIXME: defined(_WIN32) */
typedef void *__ptr32;
typedef __uint64 __ptr64;
#endif
/* Always signed and 32 bit wide */
typedef __int32 LONG32;
typedef __int32 INT32;
typedef LONG32 *PLONG32;
typedef INT32 *PINT32;
/* Always unsigned and 32 bit wide */
typedef __uint32 ULONG32;
typedef __uint32 DWORD32;
typedef __uint32 UINT32;
typedef ULONG32 *PULONG32;
typedef DWORD32 *PDWORD32;
typedef UINT32 *PUINT32;
/* Always signed and 64 bit wide */
typedef __int64 LONG64;
typedef __int64 INT64;
typedef LONG64 *PLONG64;
typedef INT64 *PINT64;
/* Always unsigned and 64 bit wide */
typedef __uint64 ULONG64;
typedef __uint64 DWORD64;
typedef __uint64 UINT64;
typedef ULONG64 *PULONG64;
typedef DWORD64 *PDWORD64;
typedef UINT64 *PUINT64;
/* Win32 or Win64 dependent typedef/defines. */
#ifdef _WIN64
typedef __int64 INT_PTR, *PINT_PTR;
typedef __uint64 UINT_PTR, *PUINT_PTR;
#define MAXINT_PTR 0x7fffffffffffffff
#define MININT_PTR 0x8000000000000000
#define MAXUINT_PTR 0xffffffffffffffff
typedef __int32 HALF_PTR, *PHALF_PTR;
typedef __int32 UHALF_PTR, *PUHALF_PTR;
#define MAXHALF_PTR 0x7fffffff
#define MINHALF_PTR 0x80000000
#define MAXUHALF_PTR 0xffffffff
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef __uint64 ULONG_PTR, *PULONG_PTR;
typedef __uint64 DWORD_PTR, *PDWORD_PTR;
#else /* FIXME: defined(_WIN32) */
typedef __int32 INT_PTR, *PINT_PTR;
typedef __uint32 UINT_PTR, *PUINT_PTR;
#define MAXINT_PTR 0x7fffffff
#define MININT_PTR 0x80000000
#define MAXUINT_PTR 0xffffffff
typedef __int16 HALF_PTR, *PHALF_PTR;
typedef __uint16 UHALF_PTR, *PUHALF_PTR;
#define MAXUHALF_PTR 0xffff
#define MAXHALF_PTR 0x7fff
#define MINHALF_PTR 0x8000
typedef __int32 LONG_PTR, *PLONG_PTR;
typedef __uint32 ULONG_PTR, *PULONG_PTR;
typedef __uint32 DWORD_PTR, *PDWORD_PTR;
#endif /* defined(_WIN64) || defined(_WIN32) */
typedef INT_PTR SSIZE_T, *PSSIZE_T;
typedef UINT_PTR SIZE_T, *PSIZE_T;
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
#endif /* !defined(__WINE_BASETSD_H) */

598
complus/example.c Normal file
View File

@ -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");
}

95
complus/guiddef.h Normal file
View File

@ -0,0 +1,95 @@
/* guiddef.h
Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
for a complete list)
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.
*/
/* already defined bu Mingw32/cpd
#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
#endif
*/
#undef DEFINE_GUID
#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
const GUID name = \
{ l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
extern const GUID name
#endif
#define DEFINE_OLEGUID(name, l, w1, w2) \
DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
#ifndef _GUIDDEF_H_
#define _GUIDDEF_H_
/* typedef GUID *LPGUID;
typedef GUID CLSID,*LPCLSID; */
typedef GUID IID,*LPIID;
typedef GUID FMTID,*LPFMTID;
#if defined(__cplusplus) && !defined(CINTERFACE)
#define REFGUID const GUID &
#define REFCLSID const CLSID &
#define REFIID const IID &
#define REFFMTID const FMTID &
#else /* !defined(__cplusplus) && !defined(CINTERFACE) */
#define REFGUID const GUID* const
#define REFCLSID const CLSID* const
#define REFIID const IID* const
#define REFFMTID const FMTID* const
#endif /* !defined(__cplusplus) && !defined(CINTERFACE) */
#if defined(__cplusplus) && !defined(CINTERFACE)
#define IsEqualGUID(rguid1, rguid2) (!memcmp(&(rguid1), &(rguid2), sizeof(GUID)))
#else /* defined(__cplusplus) && !defined(CINTERFACE) */
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
#endif /* defined(__cplusplus) && !defined(CINTERFACE) */
#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
#if defined(__cplusplus) && !defined(CINTERFACE)
inline bool operator==(const GUID& guidOne, const GUID& guidOther)
{
return !memcmp(&guidOne,&guidOther,sizeof(GUID));
}
inline bool operator!=(const GUID& guidOne, const GUID& guidOther)
{
return !(guidOne == guidOther);
}
#endif
extern const IID GUID_NULL;
#define IID_NULL GUID_NULL
#define CLSID_NULL GUID_NULL
#define FMTID_NULL GUID_NULL
#endif /* _GUIDDEF_H_ */

202
complus/ignupg.c Normal file
View File

@ -0,0 +1,202 @@
/* ignupg.c - COM+ class IGnuPG
* 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
*/
#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 "ignupg.h"
/*
* Declare the interface implementation structures
*/
typedef struct IGnuPGImpl IGnuPGImpl;
typedef struct IClassFactoryImpl IClassFactoryImpl;
struct IGnuPGImpl {
/* IUnknown required stuff */
ICOM_VFIELD (IGnuPG);
DWORD ref;
/* Our stuff */
int foo;
};
struct IClassFactoryImpl {
/* IUnknown fields */
ICOM_VFIELD(IClassFactory);
DWORD ref;
};
/**********************************************************
************** IGnuPG Implementation *******************
**********************************************************/
static HRESULT WINAPI
IGnuPGImpl_QueryInterface (IGnuPG *iface, REFIID refiid, LPVOID *obj)
{
ICOM_THIS (IGnuPGImpl,iface);
fprintf (stderr,"(%p)->QueryInterface(%s,%p)\n",
This, "debugstr_guid(refiid)", obj);
if ( IsEqualGUID (&IID_IUnknown, refiid)
|| !IsEqualGUID (&IID_IGnuPG, refiid) ) {
*obj = iface;
return 0;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI
IGnuPGImpl_AddRef (IGnuPG *iface)
{
ICOM_THIS (IGnuPGImpl,iface);
return ++This->ref;
}
static ULONG WINAPI
IGnuPGImpl_Release (IGnuPG *iface)
{
ICOM_THIS (IGnuPGImpl,iface);
if (--This->ref)
return This->ref;
HeapFree(GetProcessHeap(),0,iface);
return 0;
}
static ICOM_VTABLE(IGnuPG) gnupg_vtbl =
{
/* IUnknow methods */
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IGnuPGImpl_QueryInterface,
IGnuPGImpl_AddRef,
IGnuPGImpl_Release,
/* Our methods */
};
/***************************************************************
****************** GnuPG Factory ****************************
***************************************************************/
static HRESULT WINAPI
GnuPGFactory_QueryInterface (IClassFactory *iface, REFIID refiid, LPVOID *obj)
{
/*ICOM_THIS(IClassFactoryImpl,iface);*/
return E_NOINTERFACE;
}
static ULONG WINAPI
GnuPGFactory_AddRef (IClassFactory *iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
return ++(This->ref);
}
static ULONG WINAPI
GnuPGFactory_Release (IClassFactory *iface)
{
ICOM_THIS(IClassFactoryImpl,iface);
return --(This->ref);
}
static HRESULT WINAPI
GnuPGFactory_CreateInstance (IClassFactory *iface, IUnknown *outer,
REFIID refiid, LPVOID *r_obj )
{
/*ICOM_THIS(IClassFactoryImpl,iface);*/
if ( IsEqualGUID (&IID_IGnuPG, refiid) ) {
IGnuPGImpl *obj;
obj = HeapAlloc (GetProcessHeap(), 0, sizeof *obj );
if ( !obj)
return E_OUTOFMEMORY;
ICOM_VTBL(obj) = &gnupg_vtbl;
obj->ref = 1;
*r_obj = obj;
return 0;
}
*r_obj = NULL;
return E_NOINTERFACE;
}
static HRESULT WINAPI
GnuPGFactory_LockServer (IClassFactory *iface, BOOL dolock )
{
/*ICOM_THIS(IClassFactoryImpl,iface);*/
return 0;
}
static ICOM_VTABLE(IClassFactory) gnupg_factory_vtbl = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
GnuPGFactory_QueryInterface,
GnuPGFactory_AddRef,
GnuPGFactory_Release,
GnuPGFactory_CreateInstance,
GnuPGFactory_LockServer
};
static IClassFactoryImpl GnuPG_CF = {&gnupg_factory_vtbl, 1 };
IClassFactory *
gnupg_factory_new ( CLSID *r_clsid )
{
*r_clsid = CLSID_GnuPG;
IClassFactory_AddRef((IClassFactory*)&GnuPG_CF);
return (IClassFactory*)&GnuPG_CF;
}
void
gnupg_factory_release ( IClassFactory *factory )
{
/* it's static - nothing to do */
}

68
complus/ignupg.h Normal file
View File

@ -0,0 +1,68 @@
/* ignupg.h - COM+ class IGnuPG
* 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 IGNUPG_H
#define IGNUPG_H 1
#include "obj_base.h"
DEFINE_GUID(CLSID_GnuPG, 0x42424242, 0x62e8, 0x11cf,
0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
DEFINE_GUID(IID_IGnuPG, 0x24242424, 0x4981, 0x11CE,
0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);
typedef struct IGnuPG IGnuPG;
#define ICOM_INTERFACE IGnuPG
#define IGnuPG_METHODS \
ICOM_METHOD1(HRESULT,Initialize, REFIID,) \
ICOM_METHOD1(HRESULT,EnumDevices, LPVOID,)
#define IGnuPG_IMETHODS \
IUnknown_IMETHODS \
IGnuPG_METHODS
ICOM_DEFINE(IGnuPG,IUnknown)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IGnuPG_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IGnuPG_AddRef(p) ICOM_CALL (AddRef,p)
#define IGnuPG_Release(p) ICOM_CALL (Release,p)
/*** IGnuPG methods ***/
#define IGnuPG_Initialize(p,a) ICOM_CALL1(Initialize,p,a)
#define IGnuPG_EnumDevices(p,a,b) ICOM_CALL2(EnumDevice,p,a,b)
#endif /*IGNUPG_H*/

View File

@ -28,6 +28,8 @@
#include <time.h>
#include <windows.h>
#include "obj_base.h"
#include "argparse.h"
#include "main.h"
@ -71,6 +73,9 @@ static ARGPARSE_OPTS opts[] = {
{ oEmbedding, "Embedding" , 0, "@" },
{0} };
static const char *
my_strusage( int level )
{
@ -258,30 +263,23 @@ enter_complus ()
{
HANDLE running;
int reg;
void *factory;
IClassFactory *factory;
CLSID clsid;
/* CoInitializeEx (NULL, COINIT_MULTITHREADED); */
CoInitializeEx (NULL, COINIT_MULTITHREADED);
running = CreateEvent (NULL, FALSE, FALSE, NULL );
#if 0
factory = create_class_factory ();
CoRegisterClassObject (CLSID_gpgme, factory,
factory = gnupg_factory_new ( &clsid );
CoRegisterClassObject (&clsid, (IUnknown*)factory,
CLSCTX_LOCAL_SERVER,
REGCLS_SUSPENDED|REGCLASS_MULTIPLEUSE, &reg );
REGCLS_SUSPENDED|REGCLS_MULTIPLEUSE, &reg );
CoResumeClassObjects ();
#endif
WaitForSingleObject ( running, INFINITE );
CloseHandle (running);
#if 0
CoRevokeClassObject ( reg );
factory->release ();
CoUnitialize ();
#endif
gnupg_factory_release (factory);
CoUninitialize ();
}

View File

@ -38,6 +38,10 @@ struct {
} opt;
/*-- ignupg.c --*/
IClassFactory *gnupg_factory_new ( CLSID *r_clsid );
void gnupg_factory_release ( IClassFactory *factory );
#endif /* COMPLUS_MAIN_H */

800
complus/obj_base.h Normal file
View File

@ -0,0 +1,800 @@
/* obj_base.h - This file defines the macros and types necessary to
define COM interfaces, and the three most basic COM interfaces:
IUnknown, IMalloc and IClassFactory.
Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
for a complete list)
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.
*/
#ifndef __WINE_WINE_OBJ_BASE_H
#define __WINE_WINE_OBJ_BASE_H
/* check these values! */
#define E_NOINTERFACE 0x80040002
#define E_OUTOFMEMORY 0x8007000E
/*****************************************************************************
* define ICOM_MSVTABLE_COMPAT
* to implement the microsoft com vtable compatibility workaround for g++.
*
* NOTE: Turning this option on will produce a winelib that is incompatible
* with the binary emulator.
*
* If the compiler supports the com_interface attribute, leave this off, and
* define the ICOM_USE_COM_INTERFACE_ATTRIBUTE macro below. This may also
* require the addition of the -vtable-thunks option for g++.
*
* If you aren't interested in Winelib C++ compatibility at all, leave both
* options off.
*
* The preferable method for using ICOM_USE_COM_INTERFACE_ATTRIBUTE macro
* would be to define it only for your Winelib application. This allows you
* to have both binary and Winelib compatibility for C and C++ at the same
* time :)
*/
/* #define ICOM_MSVTABLE_COMPAT 1 */
/* #define ICOM_USE_COM_INTERFACE_ATTRIBUTE 1 */
/*****************************************************************************
* Defines the basic types
*/
#include "wtypes.h"
#include "guiddef.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NONAMELESSSTRUCT
#define LISet32(li, v) ((li).HighPart = (v) < 0 ? -1 : 0, (li).LowPart = (v))
#define ULISet32(li, v) ((li).HighPart = 0, (li).LowPart = (v))
#else
#define LISet32(li, v) ((li).s.HighPart = (v) < 0 ? -1 : 0, (li).s.LowPart = (v))
#define ULISet32(li, v) ((li).s.HighPart = 0, (li).s.LowPart = (v))
#endif
/*****************************************************************************
* GUID API
*/
HRESULT WINAPI StringFromCLSID16(REFCLSID id, LPOLESTR16*);
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR*);
HRESULT WINAPI CLSIDFromString16(LPCOLESTR16, CLSID *);
HRESULT WINAPI CLSIDFromString(LPCOLESTR, CLSID *);
HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid);
HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid);
HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID);
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax);
/*****************************************************************************
* Macros to define a COM interface
*/
/*
* The goal of the following set of definitions is to provide a way to use the same
* header file definitions to provide both a C interface and a C++ object oriented
* interface to COM interfaces. The type of interface is selected automatically
* depending on the language but it is always possible to get the C interface in C++
* by defining CINTERFACE.
*
* It is based on the following assumptions:
* - all COM interfaces derive from IUnknown, this should not be a problem.
* - the header file only defines the interface, the actual fields are defined
* separately in the C file implementing the interface.
*
* The natural approach to this problem would be to make sure we get a C++ class and
* virtual methods in C++ and a structure with a table of pointer to functions in C.
* Unfortunately the layout of the virtual table is compiler specific, the layout of
* g++ virtual tables is not the same as that of an egcs virtual table which is not the
* same as that generated by Visual C+. There are workarounds to make the virtual tables
* compatible via padding but unfortunately the one which is imposed to the WINE emulator
* by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
*
* So the solution I finally adopted does not use virtual tables. Instead I use inline
* non virtual methods that dereference the method pointer themselves and perform the call.
*
* Let's take Direct3D as an example:
*
* #define ICOM_INTERFACE IDirect3D
* #define IDirect3D_METHODS \
* ICOM_METHOD1(HRESULT,Initialize, REFIID,) \
* ICOM_METHOD2(HRESULT,EnumDevices, LPD3DENUMDEVICESCALLBACK,, LPVOID,) \
* ICOM_METHOD2(HRESULT,CreateLight, LPDIRECT3DLIGHT*,, IUnknown*,) \
* ICOM_METHOD2(HRESULT,CreateMaterial,LPDIRECT3DMATERIAL*,, IUnknown*,) \
* ICOM_METHOD2(HRESULT,CreateViewport,LPDIRECT3DVIEWPORT*,, IUnknown*,) \
* ICOM_METHOD2(HRESULT,FindDevice, LPD3DFINDDEVICESEARCH,, LPD3DFINDDEVICERESULT,)
* #define IDirect3D_IMETHODS \
* IUnknown_IMETHODS \
* IDirect3D_METHODS
* ICOM_DEFINE(IDirect3D,IUnknown)
* #undef ICOM_INTERFACE
*
* #ifdef ICOM_CINTERFACE
* // *** IUnknown methods *** //
* #define IDirect3D_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
* #define IDirect3D_AddRef(p) ICOM_CALL (AddRef,p)
* #define IDirect3D_Release(p) ICOM_CALL (Release,p)
* // *** IDirect3D methods *** //
* #define IDirect3D_Initialize(p,a) ICOM_CALL1(Initialize,p,a)
* #define IDirect3D_EnumDevices(p,a,b) ICOM_CALL2(EnumDevice,p,a,b)
* #define IDirect3D_CreateLight(p,a,b) ICOM_CALL2(CreateLight,p,a,b)
* #define IDirect3D_CreateMaterial(p,a,b) ICOM_CALL2(CreateMaterial,p,a,b)
* #define IDirect3D_CreateViewport(p,a,b) ICOM_CALL2(CreateViewport,p,a,b)
* #define IDirect3D_FindDevice(p,a,b) ICOM_CALL2(FindDevice,p,a,b)
* #endif
*
* Comments:
* - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this'
* pointer. Defining this macro here saves us the trouble of having to repeat the interface
* name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1
* cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not
* 'IDirect3D_VTABLE'.
* - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the
* inherited methods to form ICOM_IMETHODS.
* - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must
* be written manually (rather than using a macro to generate the equivalent code) to avoid
* macro recursion (which compilers don't like).
* - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to
* explicitly use the interface name for macro expansion reasons again.
* Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's
* Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance
* is taken care of by the language.
* - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer
* method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The
* only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and
* to have it take only the type information (with const if necessary) as parameters.
* The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following
* macros will not work. This time it's because the ICOM_CALL macro expansion is done only once
* the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone
* anyway.
* - You may have noticed the double commas after each parameter type. This allows you to put the
* name of that parameter which I think is good for documentation. It is not required and since
* I did not know what to put there for this example (I could only find doc about IDirect3D2),
* I left them blank.
* - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access
* to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate
* the inherited method definitions there. This time I could have used a trick to use only one
* macro whatever the number of parameters but I prefered to have it work the same way as above.
* - You probably have noticed that we don't define the fields we need to actually implement this
* interface: reference count, pointer to other resources and miscellaneous fields. That's
* because these interfaces are just that: interfaces. They may be implemented more than once, in
* different contexts and sometimes not even in Wine. Thus it would not make sense to impose
* that the interface contains some specific fields.
*
*
* In C this gives:
* typedef struct IDirect3DVtbl IDirect3DVtbl;
* struct IDirect3D {
* IDirect3DVtbl* lpVtbl;
* };
* struct IDirect3DVtbl {
* HRESULT (*fnQueryInterface)(IDirect3D* me, REFIID riid, LPVOID* ppvObj);
* ULONG (*fnQueryInterface)(IDirect3D* me);
* ULONG (*fnQueryInterface)(IDirect3D* me);
* HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
* HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
* HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
* HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
* HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
* HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
* };
*
* #ifdef ICOM_CINTERFACE
* // *** IUnknown methods *** //
* #define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->fnQueryInterface(p,a,b)
* #define IDirect3D_AddRef(p) (p)->lpVtbl->fnAddRef(p)
* #define IDirect3D_Release(p) (p)->lpVtbl->fnRelease(p)
* // *** IDirect3D methods *** //
* #define IDirect3D_Initialize(p,a) (p)->lpVtbl->fnInitialize(p,a)
* #define IDirect3D_EnumDevices(p,a,b) (p)->lpVtbl->fnEnumDevice(p,a,b)
* #define IDirect3D_CreateLight(p,a,b) (p)->lpVtbl->fnCreateLight(p,a,b)
* #define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->fnCreateMaterial(p,a,b)
* #define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->fnCreateViewport(p,a,b)
* #define IDirect3D_FindDevice(p,a,b) (p)->lpVtbl->fnFindDevice(p,a,b)
* #endif
*
* Comments:
* - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing
* the user needs to know to use the interface. Of course the structure we will define to
* implement this interface will have more fields but the first one will match this pointer.
* - The code generated by ICOM_DEFINE defines both the structure representing the interface and
* the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to
* automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS
* to define the IDirect3D methods.
* - Each method is declared as a pointer to function field in the jump table. The implementation
* will fill this jump table with appropriate values, probably using a static variable, and
* initialize the lpVtbl field to point to this variable.
* - The IDirect3D_Xxx macros then just derefence the lpVtbl pointer and use the function pointer
* corresponding to the macro name. This emulates the behavior of a virtual table and should be
* just as fast.
* - This C code should be quite compatible with the Windows headers both for code that uses COM
* interfaces and for code implementing a COM interface.
*
*
* And in C++ (with gcc's g++):
*
* typedef struct IDirect3D: public IUnknown {
* private: HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
* public: inline HRESULT Initialize(REFIID a) { return ((IDirect3D*)t.lpVtbl)->fnInitialize(this,a); };
* private: HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
* public: inline HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK a, LPVOID b)
* { return ((IDirect3D*)t.lpVtbl)->fnEnumDevices(this,a,b); };
* private: HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
* public: inline HRESULT CreateLight(LPDIRECT3DLIGHT* a, IUnknown* b)
* { return ((IDirect3D*)t.lpVtbl)->fnCreateLight(this,a,b); };
* private: HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
* public: inline HRESULT CreateMaterial(LPDIRECT3DMATERIAL* a, IUnknown* b)
* { return ((IDirect3D*)t.lpVtbl)->fnCreateMaterial(this,a,b); };
* private: HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
* public: inline HRESULT CreateViewport(LPDIRECT3DVIEWPORT* a, IUnknown* b)
* { return ((IDirect3D*)t.lpVtbl)->fnCreateViewport(this,a,b); };
* private: HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
* public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
* { return ((IDirect3D*)t.lpVtbl)->fnFindDevice(this,a,b); };
* };
*
* Comments:
* - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface
* definition. The reason for this is to avoid having to duplicate the mehod definitions: once
* to have the function pointers in the jump table and once to have the methods in the interface
* class. Here one macro can generate both. This means though that the first pointer, t.lpVtbl
* defined in IUnknown, must be interpreted as the jump table pointer if we interpret the
* structure as the the interface class, and as the function pointer to the QueryInterface
* method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this
* gymnastic is entirely taken care of in the header of IUnknown.
* - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions.
* - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and
* a non-vritual inline method which dereferences it and calls it. This way this method behaves
* just like a virtual method but does not create a true C++ virtual table which would break the
* structure layout. If you look at the implementation of these methods you'll notice that they
* would not work for void functions. We have to return something and fortunately this seems to
* be what all the COM methods do (otherwise we would need another set of macros).
* - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter
* names and the method invocation using only the formal parameter name. This is the reason why
* we need different macros to handle different numbers of parameters.
* - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE
* macro is defined in which case we would not be here.
* - This C++ code works well for code that just uses COM interfaces. But it will not work with
* C++ code implement a COM interface. That's because such code assumes the interface methods
* are declared as virtual C++ methods which is not the case here.
*
*
* Implementing a COM interface.
*
* This continues the above example. This example assumes that the implementation is in C.
*
* typedef struct _IDirect3D {
* void* lpVtbl;
* // ...
*
* } _IDirect3D;
*
* static ICOM_VTABLE(IDirect3D) d3dvt;
*
* // implement the IDirect3D methods here
*
* int IDirect3D_fnQueryInterface(IDirect3D* me)
* {
* ICOM_THIS(IDirect3D,me);
* // ...
* }
*
* // ...
*
* static ICOM_VTABLE(IDirect3D) d3dvt = {
* ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
* IDirect3D_fnQueryInterface,
* IDirect3D_fnAdd,
* IDirect3D_fnAdd2,
* IDirect3D_fnInitialize,
* IDirect3D_fnSetWidth
* };
*
* Comments:
* - We first define what the interface really contains. This is th e_IDirect3D structure. The
* first field must of course be the virtual table pointer. Everything else is free.
* - Then we predeclare our static virtual table variable, we will need its address in some
* methods to initialize the virtual table pointer of the returned interface objects.
* - Then we implement the interface methods. To match what has been declared in the header file
* they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that
* we can manipulate the fields. This is performed by the ICOM_THIS macro.
* - Finally we initialize the virtual table.
*/
#define ICOM_VTABLE(iface) iface##Vtbl
#define ICOM_VFIELD(iface) ICOM_VTABLE(iface)* lpVtbl
#define ICOM_VTBL(iface) (iface)->lpVtbl
#if !defined(__cplusplus) || defined(CINTERFACE)
#define ICOM_CINTERFACE 1
#endif
#ifndef ICOM_CINTERFACE
/* C++ interface */
#define ICOM_METHOD(ret,xfn) \
public: virtual ret CALLBACK (xfn)(void) = 0;
#define ICOM_METHOD1(ret,xfn,ta,na) \
public: virtual ret CALLBACK (xfn)(ta a) = 0;
#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
public: virtual ret CALLBACK (xfn)(ta a,tb b) = 0;
#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c) = 0;
#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0;
#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0;
#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) = 0;
#define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k) = 0;
#define ICOM_VMETHOD(xfn) \
public: virtual void CALLBACK (xfn)(void) = 0;
#define ICOM_VMETHOD1(xfn,ta,na) \
public: virtual void CALLBACK (xfn)(ta a) = 0;
#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
public: virtual void CALLBACK (xfn)(ta a,tb b) = 0;
#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c) = 0;
#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0;
#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0;
#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
#define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
#define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j) = 0;
#define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j, tk k) = 0;
#ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE
#define ICOM_DEFINE(iface,ibase) \
typedef struct iface: public ibase { \
iface##_METHODS \
} __attribute__ ((com_interface));
#else
#define ICOM_DEFINE(iface,ibase) \
typedef struct iface: public ibase { \
iface##_METHODS \
};
#endif /* ICOM_USE_COM_INTERFACE_ATTRIBUTE */
#define ICOM_CALL(xfn, p) (p)->xfn()
#define ICOM_CALL1(xfn, p,a) (p)->xfn(a)
#define ICOM_CALL2(xfn, p,a,b) (p)->xfn(a,b)
#define ICOM_CALL3(xfn, p,a,b,c) (p)->xfn(a,b,c)
#define ICOM_CALL4(xfn, p,a,b,c,d) (p)->xfn(a,b,c,d)
#define ICOM_CALL5(xfn, p,a,b,c,d,e) (p)->xfn(a,b,c,d,e)
#define ICOM_CALL6(xfn, p,a,b,c,d,e,f) (p)->xfn(a,b,c,d,e,f)
#define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g) (p)->xfn(a,b,c,d,e,f,g)
#define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h) (p)->xfn(a,b,c,d,e,f,g,h)
#define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i) (p)->xfn(a,b,c,d,e,f,g,h,i)
#define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j) (p)->xfn(a,b,c,d,e,f,g,h,i,j)
#define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) (p)->xfn(a,b,c,d,e,f,g,h,i,j,k)
#else
/* C interface */
#ifdef __WINE__
#define ICOM_METHOD(ret,xfn) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me);
#define ICOM_METHOD1(ret,xfn,ta,na) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a);
#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b);
#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
#define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
#define ICOM_VMETHOD(xfn) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me);
#define ICOM_VMETHOD1(xfn,ta,na) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a);
#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b);
#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,nh) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
#define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ni) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
#define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,nj) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
#define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,nk) \
void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
#define ICOM_CALL(xfn, p) ICOM_VTBL(p)->fn##xfn(p)
#define ICOM_CALL1(xfn, p,a) ICOM_VTBL(p)->fn##xfn(p,a)
#define ICOM_CALL2(xfn, p,a,b) ICOM_VTBL(p)->fn##xfn(p,a,b)
#define ICOM_CALL3(xfn, p,a,b,c) ICOM_VTBL(p)->fn##xfn(p,a,b,c)
#define ICOM_CALL4(xfn, p,a,b,c,d) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d)
#define ICOM_CALL5(xfn, p,a,b,c,d,e) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e)
#define ICOM_CALL6(xfn, p,a,b,c,d,e,f) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f)
#define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g)
#define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h)
#define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i)
#define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i,j)
#define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i,j,k)
#else
/* WINELIB case */
#define ICOM_METHOD(ret,xfn) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me);
#define ICOM_METHOD1(ret,xfn,ta,na) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a);
#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b);
#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
#define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
#define ICOM_VMETHOD(xfn) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me);
#define ICOM_VMETHOD1(xfn,ta,na) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a);
#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b);
#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,nh) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
#define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ni) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
#define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,nj) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
#define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,nk) \
void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
#define ICOM_CVMETHOD(xfn) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me);
#define ICOM_CVMETHOD1(xfn,ta,na) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a);
#define ICOM_CVMETHOD2(xfn,ta,na,tb,nb) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b);
#define ICOM_CVMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c);
#define ICOM_CVMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
#define ICOM_CVMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
#define ICOM_CVMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
#define ICOM_CVMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
#define ICOM_CVMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
#define ICOM_CVMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
#define ICOM_CVMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
#define ICOM_CVMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
#define ICOM_CALL(xfn, p) ICOM_VTBL(p)->xfn(p)
#define ICOM_CALL1(xfn, p,a) ICOM_VTBL(p)->xfn(p,a)
#define ICOM_CALL2(xfn, p,a,b) ICOM_VTBL(p)->xfn(p,a,b)
#define ICOM_CALL3(xfn, p,a,b,c) ICOM_VTBL(p)->xfn(p,a,b,c)
#define ICOM_CALL4(xfn, p,a,b,c,d) ICOM_VTBL(p)->xfn(p,a,b,c,d)
#define ICOM_CALL5(xfn, p,a,b,c,d,e) ICOM_VTBL(p)->xfn(p,a,b,c,d,e)
#define ICOM_CALL6(xfn, p,a,b,c,d,e,f) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f)
#define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g)
#define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h)
#define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i)
#define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j)
#define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j,k)
#endif /* __WINE__ */
#ifdef ICOM_MSVTABLE_COMPAT
#define ICOM_DEFINE(iface,ibase) \
typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
struct iface { \
const ICOM_VFIELD(iface); \
}; \
struct ICOM_VTABLE(iface) { \
long dummyRTTI1; \
long dummyRTTI2; \
ibase##_IMETHODS \
iface##_METHODS \
};
#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 0,0,
#else
#define ICOM_DEFINE(iface,ibase) \
typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
struct iface { \
const ICOM_VFIELD(iface); \
}; \
struct ICOM_VTABLE(iface) { \
ibase##_IMETHODS \
iface##_METHODS \
};
#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
#endif /* ICOM_MSVTABLE_COMPAT */
#define ICOM_THIS(impl,iface) impl* const This=(impl*)iface
#define ICOM_CTHIS(impl,iface) const impl* const This=(const impl*)iface
#endif
/*****************************************************************************
* Predeclare the interfaces
*/
DEFINE_OLEGUID(IID_IClassFactory, 0x00000001L, 0, 0);
typedef struct IClassFactory IClassFactory, *LPCLASSFACTORY;
DEFINE_OLEGUID(IID_IMalloc, 0x00000002L, 0, 0);
typedef struct IMalloc IMalloc,*LPMALLOC;
DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0);
typedef struct IUnknown IUnknown, *LPUNKNOWN;
/*****************************************************************************
* IUnknown interface
*/
#define ICOM_INTERFACE IUnknown
#define IUnknown_IMETHODS \
ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj) \
ICOM_METHOD (ULONG,AddRef) \
ICOM_METHOD (ULONG,Release)
#ifdef ICOM_CINTERFACE
typedef struct ICOM_VTABLE(IUnknown) ICOM_VTABLE(IUnknown);
struct IUnknown {
ICOM_VFIELD(IUnknown);
#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE)
} __attribute__ ((com_interface));
#else
};
#endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */
struct ICOM_VTABLE(IUnknown) {
#ifdef ICOM_MSVTABLE_COMPAT
long dummyRTTI1;
long dummyRTTI2;
#endif /* ICOM_MSVTABLE_COMPAT */
#else /* ICOM_CINTERFACE */
struct IUnknown {
#endif /* ICOM_CINTERFACE */
ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj)
ICOM_METHOD (ULONG,AddRef)
ICOM_METHOD (ULONG,Release)
#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE)
} __attribute__ ((com_interface));
#else
};
#endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IUnknown_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IUnknown_AddRef(p) ICOM_CALL (AddRef,p)
#define IUnknown_Release(p) ICOM_CALL (Release,p)
/*****************************************************************************
* IClassFactory interface
*/
#define ICOM_INTERFACE IClassFactory
#define IClassFactory_METHODS \
ICOM_METHOD3(HRESULT,CreateInstance, LPUNKNOWN,pUnkOuter, REFIID,riid, LPVOID*,ppvObject) \
ICOM_METHOD1(HRESULT,LockServer, BOOL,fLock)
#define IClassFactory_IMETHODS \
IUnknown_IMETHODS \
IClassFactory_METHODS
ICOM_DEFINE(IClassFactory,IUnknown)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IClassFactory_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IClassFactory_AddRef(p) ICOM_CALL (AddRef,p)
#define IClassFactory_Release(p) ICOM_CALL (Release,p)
/*** IClassFactory methods ***/
#define IClassFactory_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c)
#define IClassFactory_LockServer(p,a) ICOM_CALL1(LockServer,p,a)
/*****************************************************************************
* IMalloc interface
*/
#define ICOM_INTERFACE IMalloc
#define IMalloc_METHODS \
ICOM_METHOD1 (LPVOID,Alloc, DWORD,cb) \
ICOM_METHOD2 (LPVOID,Realloc, LPVOID,pv, DWORD,cb) \
ICOM_VMETHOD1( Free, LPVOID,pv) \
ICOM_METHOD1(DWORD, GetSize, LPVOID,pv) \
ICOM_METHOD1(INT, DidAlloc, LPVOID,pv) \
ICOM_METHOD (VOID, HeapMinimize)
#define IMalloc_IMETHODS \
IUnknown_IMETHODS \
IMalloc_METHODS
ICOM_DEFINE(IMalloc,IUnknown)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IMalloc_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IMalloc_AddRef(p) ICOM_CALL (AddRef,p)
#define IMalloc_Release(p) ICOM_CALL (Release,p)
/*** IMalloc32 methods ***/
#define IMalloc_Alloc(p,a) ICOM_CALL1(Alloc,p,a)
#define IMalloc_Realloc(p,a,b) ICOM_CALL2(Realloc,p,a,b)
#define IMalloc_Free(p,a) ICOM_CALL1(Free,p,a)
#define IMalloc_GetSize(p,a) ICOM_CALL1(GetSize,p,a)
#define IMalloc_DidAlloc(p,a) ICOM_CALL1(DidAlloc,p,a)
#define IMalloc_HeapMinimize(p) ICOM_CALL (HeapMinimize,p)
HRESULT WINAPI CoGetMalloc(DWORD dwMemContext,LPMALLOC* lpMalloc);
LPVOID WINAPI CoTaskMemAlloc(ULONG size);
void WINAPI CoTaskMemFree(LPVOID ptr);
/* FIXME: unimplemented */
LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size);
/*****************************************************************************
* Additional API
*/
HRESULT WINAPI CoCreateGuid(GUID* pguid);
HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree);
void WINAPI CoFreeAllLibraries(void);
void WINAPI CoFreeLibrary(HINSTANCE hLibrary);
void WINAPI CoFreeUnusedLibraries(void);
HRESULT WINAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv);
HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, LPVOID pvReserved, REFIID iid, LPVOID *ppv);
HRESULT WINAPI CoInitialize(LPVOID lpReserved);
HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit);
void WINAPI CoUninitialize(void);
typedef enum tagCOINIT
{
COINIT_APARTMENTTHREADED = 0x2, /* Apartment model */
COINIT_MULTITHREADED = 0x0, /* OLE calls objects on any thread */
COINIT_DISABLE_OLE1DDE = 0x4, /* Don't use DDE for Ole1 support */
COINIT_SPEED_OVER_MEMORY = 0x8 /* Trade memory for speed */
} COINIT;
/* FIXME: not implemented */
BOOL WINAPI CoIsOle1Class(REFCLSID rclsid);
HRESULT WINAPI CoLockObjectExternal(LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases);
/* class registration flags; passed to CoRegisterClassObject */
typedef enum tagREGCLS
{
REGCLS_SINGLEUSE = 0,
REGCLS_MULTIPLEUSE = 1,
REGCLS_MULTI_SEPARATE = 2,
REGCLS_SUSPENDED = 4
} REGCLS;
HRESULT WINAPI CoResumeClassObjects (void);
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid,LPUNKNOWN pUnk,DWORD dwClsContext,DWORD flags,LPDWORD lpdwRegister);
HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister);
/*****************************************************************************
* COM Server dll - exports
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
HRESULT WINAPI DllCanUnloadNow(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __WINE_WINE_OBJ_BASE_H */

272
complus/wtypes.h Normal file
View File

@ -0,0 +1,272 @@
/* wtypes.h - Defines the basic types used by COM interfaces.
Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
for a complete list)
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.
*/
#ifndef __WINE_WTYPES_H
#define __WINE_WTYPES_H
#include "basetsd.h"
#include "guiddef.h"
/*#include "rpc.h"*/
/*#include "rpcndr.h"*/
typedef WORD CLIPFORMAT, *LPCLIPFORMAT;
/* FIXME: does not belong here */
typedef CHAR OLECHAR16;
typedef LPSTR LPOLESTR16;
typedef LPCSTR LPCOLESTR16;
typedef OLECHAR16 *BSTR16;
typedef BSTR16 *LPBSTR16;
#define OLESTR16(x) x
typedef WCHAR OLECHAR;
typedef LPWSTR LPOLESTR;
typedef LPCWSTR LPCOLESTR;
typedef OLECHAR *BSTR;
typedef BSTR *LPBSTR;
/*
#ifndef _DWORDLONG_
#define _DWORDLONG_
typedef __uint64 DWORDLONG, *PDWORDLONG;
#endif
#ifndef _ULONGLONG_
#define _ULONGLONG_
typedef __int64 LONGLONG, *PLONGLONG;
typedef __uint64 ULONGLONG, *PULONGLONG;
#endif
*/
#define OLESTR(x) L##x
typedef enum tagDVASPECT
{
DVASPECT_CONTENT = 1,
DVASPECT_THUMBNAIL = 2,
DVASPECT_ICON = 4,
DVASPECT_DOCPRINT = 8
} DVASPECT;
typedef enum tagSTGC
{
STGC_DEFAULT = 0,
STGC_OVERWRITE = 1,
STGC_ONLYIFCURRENT = 2,
STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,
STGC_CONSOLIDATE = 8
} STGC;
typedef enum tagSTGMOVE
{
STGMOVE_MOVE = 0,
STGMOVE_COPY = 1,
STGMOVE_SHALLOWCOPY = 2
} STGMOVE;
typedef struct _COAUTHIDENTITY
{
USHORT* User;
ULONG UserLength;
USHORT* Domain;
ULONG DomainLength;
USHORT* Password;
ULONG PasswordLength;
ULONG Flags;
} COAUTHIDENTITY;
typedef struct _COAUTHINFO
{
DWORD dwAuthnSvc;
DWORD dwAuthzSvc;
LPWSTR pwszServerPrincName;
DWORD dwAuthnLevel;
DWORD dwImpersonationLevel;
COAUTHIDENTITY* pAuthIdentityData;
DWORD dwCapabilities;
} COAUTHINFO;
typedef struct _COSERVERINFO
{
DWORD dwReserved1;
LPWSTR pwszName;
COAUTHINFO* pAuthInfo;
DWORD dwReserved2;
} COSERVERINFO;
typedef enum tagCLSCTX
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_INPROC_SERVER16 = 0x8,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_INPROC_HANDLER16 = 0x20,
CLSCTX_INPROC_SERVERX86 = 0x40,
CLSCTX_INPROC_HANDLERX86 = 0x80,
CLSCTX_ESERVER_HANDLER = 0x100
} CLSCTX;
#define CLSCTX_INPROC (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER)
#define CLSCTX_ALL (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)
#define CLSCTX_SERVER (CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)
typedef enum tagMSHLFLAGS
{
MSHLFLAGS_NORMAL = 0,
MSHLFLAGS_TABLESTRONG = 1,
MSHLFLAGS_TABLEWEAK = 2,
MSHLFLAGS_NOPING = 4
} MSHLFLAGS;
typedef enum tagMSHCTX
{
MSHCTX_LOCAL = 0,
MSHCTX_NOSHAREDMEM = 1,
MSHCTX_DIFFERENTMACHINE = 2,
MSHCTX_INPROC = 3
} MSHCTX;
typedef unsigned short VARTYPE;
typedef ULONG PROPID;
/*
#ifndef _tagBLOB_DEFINED
#define _tagBLOB_DEFINED
#define _BLOB_DEFINED
#define _LPBLOB_DEFINED
typedef struct tagBLOB
{
ULONG cbSize;
BYTE *pBlobData;
} BLOB, *LPBLOB;
#endif
*/
#ifndef _tagCY_DEFINED
#define _tagCY_DEFINED
typedef union tagCY {
struct {
#ifdef BIG_ENDIAN
LONG Hi;
LONG Lo;
#else /* defined(BIG_ENDIAN) */
ULONG Lo;
LONG Hi;
#endif /* defined(BIG_ENDIAN) */
} DUMMYSTRUCTNAME;
LONGLONG int64;
} CY;
#endif /* _tagCY_DEFINED */
/*
* 0 == FALSE and -1 == TRUE
*/
#define VARIANT_TRUE ((VARIANT_BOOL)0xFFFF)
#define VARIANT_FALSE ((VARIANT_BOOL)0x0000)
typedef short VARIANT_BOOL,_VARIANT_BOOL;
typedef struct tagCLIPDATA
{
ULONG cbSize;
long ulClipFmt;
BYTE *pClipData;
} CLIPDATA;
/* Macro to calculate the size of the above pClipData */
#define CBPCLIPDATA(clipdata) ( (clipdata).cbSize - sizeof((clipdata).ulClipFmt) )
typedef LONG SCODE;
/*
#ifndef _FILETIME_
#define _FILETIME_
*/
/* 64 bit number of 100 nanoseconds intervals since January 1, 1601 */
/*
typedef struct
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *LPFILETIME;
#endif
*/
#ifndef _SECURITY_DEFINED
#define _SECURITY_DEFINED
/*
typedef struct {
BYTE Value[6];
} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY;
typedef struct _SID {
BYTE Revision;
BYTE SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
DWORD SubAuthority[1];
} SID,*PSID;
*/
/*
* ACL
*/
/*
typedef struct _ACL {
BYTE AclRevision;
BYTE Sbz1;
WORD AclSize;
WORD AceCount;
WORD Sbz2;
} ACL, *PACL;
typedef DWORD SECURITY_INFORMATION;
typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
typedef DWORD ACCESS_MASK, *PACCESS_MASK;
typedef PVOID PGENERIC_MAPPING;
*/
/* The security descriptor structure */
/*
typedef struct {
BYTE Revision;
BYTE Sbz1;
SECURITY_DESCRIPTOR_CONTROL Control;
PSID Owner;
PSID Group;
PACL Sacl;
PACL Dacl;
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
*/
#endif /* _SECURITY_DEFINED */
#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED
#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x1
#define ROTFLAGS_ALLOWANYCLIENT 0x2
#endif /* !defined(_ROTFLAGS_DEFINED) */
#endif /* __WINE_WTYPES_H */

View File

@ -13,7 +13,7 @@ AM_MAINTAINER_MODE
# AGE, set REVISION to 0.
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
# CURRENT, set AGE and REVISION to 0.
AM_INIT_AUTOMAKE(gpgme,0.1.1)
AM_INIT_AUTOMAKE(gpgme,0.1.2)
LIBGPGME_LT_CURRENT=0
LIBGPGME_LT_AGE=0
LIBGPGME_LT_REVISION=3
@ -24,6 +24,8 @@ AC_SUBST(LIBGPGME_LT_AGE)
AC_SUBST(LIBGPGME_LT_REVISION)
AM_MAINTAINER_MODE
dnl
dnl Checks for programs
dnl
@ -47,7 +49,7 @@ case "${target}" in
AC_DEFINE(HAVE_DRIVE_LETTERS)
AC_DEFINE(HAVE_DOSISH_SYSTEM)
GPG='c:\\gnupg\\gpg.exe'
component_system='COM+'
#component_system='COM+'
;;
*)
;;

View File

@ -24,7 +24,7 @@ libgpgme_la_SOURCES = \
key.c key.h \
keylist.c \
rungpg.c rungpg.h status-table.h \
io.h posix-io.c w32-io.c \
syshdr.h io.h posix-io.c w32-io.c \
gpgme.c version.c errors.c

View File

@ -69,7 +69,8 @@ struct gpgme_context_s {
volatile int key_cond; /* something new is available */
struct key_queue_item_s *key_queue;
char *prompt_1;
GpgmePassphraseCb passphrase_cb;
void *passphrase_cb_value;
};

View File

@ -25,8 +25,7 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "syshdr.h"
#include "util.h"
#include "context.h"

View File

@ -33,7 +33,7 @@ struct decrypt_result_s {
int no_passphrase;
int okay;
int failed;
void *last_pw_handle;
};
@ -76,8 +76,6 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
case STATUS_NEED_PASSPHRASE:
case STATUS_NEED_PASSPHRASE_SYM:
fprintf (stderr, "need a passphrase ...\n" );
_gpgme_set_prompt (ctx, 1, "Hey! We need your passphrase!");
/* next thing gpg has to do is to read it from the passphrase-fd */
break;
case STATUS_MISSING_PASSPHRASE:
@ -101,9 +99,44 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
}
}
static const char *
command_handler ( void *opaque, GpgStatusCode code, const char *key )
{
GpgmeCtx c = opaque;
if ( c->result_type == RESULT_TYPE_NONE ) {
if ( create_result_struct ( c ) ) {
c->out_of_core = 1;
return NULL;
}
}
if ( !code ) {
/* We have been called for cleanup */
if ( c->passphrase_cb ) {
/* Fixme: take the key in account */
c->passphrase_cb (c->passphrase_cb_value, 0,
&c->result.decrypt->last_pw_handle );
}
return NULL;
}
if ( !key || !c->passphrase_cb )
return NULL;
if ( code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter") ) {
return c->passphrase_cb (c->passphrase_cb_value,
"Hey, Mr. Hoover wants your passphrase!",
&c->result.decrypt->last_pw_handle );
}
return NULL;
}
GpgmeError
gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
gpgme_op_decrypt_start ( GpgmeCtx c,
GpgmeData ciph, GpgmeData plain )
{
int rc = 0;
@ -124,16 +157,16 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, decrypt_status_handler, c );
if (c->passphrase_cb) {
rc = _gpgme_gpg_set_command_handler ( c->gpg, command_handler, c );
if (rc)
goto leave;
}
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--decrypt" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
if (passphrase) {
_gpgme_gpg_add_arg (c->gpg, "--passphrase-fd" );
_gpgme_gpg_add_data (c->gpg, passphrase, -2 );
}
/* Check the supplied data */
if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) {
@ -169,7 +202,6 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
/**
* gpgme_op_decrypt:
* @c: The context
* @passphrase: A data object with the passphrase or NULL.
* @in: ciphertext input
* @out: plaintext output
*
@ -180,10 +212,10 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_decrypt ( GpgmeCtx c, GpgmeData passphrase,
gpgme_op_decrypt ( GpgmeCtx c,
GpgmeData in, GpgmeData out )
{
GpgmeError err = gpgme_op_decrypt_start ( c, passphrase, in, out );
GpgmeError err = gpgme_op_decrypt_start ( c, in, out );
if ( !err ) {
gpgme_wait (c, 1);
if ( c->result_type != RESULT_TYPE_DECRYPT )

View File

@ -52,6 +52,7 @@ gpgme_new (GpgmeCtx *r_ctx)
c->verbosity = 1;
c->use_armor = 1; /* fixme: reset this to 0 */
*r_ctx = c;
return 0;
}
@ -70,7 +71,6 @@ gpgme_release ( GpgmeCtx c )
_gpgme_key_release ( c->tmp_key );
gpgme_data_release ( c->notation );
/* fixme: release the key_queue */
xfree (c->prompt_1);
xfree (c);
}
@ -147,36 +147,41 @@ gpgme_set_textmode ( GpgmeCtx c, int yes )
c->use_textmode = yes;
}
/*
* The only which currently allowed is 1
*/
/**
* gpgme_set_passphrase_cb:
* @c: the context
* @cb: A callback function
* @cb_value: The value passed to the callback function
*
* This function sets a callback function to be used to pass a passphrase
* to gpg. The preferred way to handle this is by using the gpg-agent, but
* because that beast is not ready for real use, you can use this passphrase
* thing.
*
* The callback function is defined as:
* <literal>
* typedef const char *(*GpgmePassphraseCb)(void*cb_value,
* const char *desc,
* void *r_hd);
* </literal>
* and called whenever gpgme needs a passphrase. DESC will have a nice
* text, to be used to prompt for the passphrase and R_HD is just a parameter
* to be used by the callback it self. Becuase the callback returns a const
* string, the callback might want to know when it can releae resources
* assocated with that returned string; gpgme helps here by calling this
* passphrase callback with an DESC of %NULL as soon as it does not need
* the returned string anymore. The callback function might then choose
* to release resources depending on R_HD.
*
**/
void
_gpgme_set_prompt ( GpgmeCtx c, int which, const char *text )
gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb cb, void *cb_value )
{
assert ( which == 1 );
xfree (c->prompt_1); c->prompt_1 = NULL;
if (text) {
c->prompt_1 = xtrystrdup (text);
if ( !c->prompt_1 )
c->out_of_core = 1;
}
}
const char *
gpgme_get_prompt ( GpgmeCtx c, int which )
{
if ( which != 1 )
return NULL;
return c->prompt_1;
c->passphrase_cb = cb;
c->passphrase_cb_value = cb_value;
}

View File

@ -34,7 +34,7 @@ extern "C" {
* let autoconf (using the AM_PATH_GPGME macro) check that this
* header matches the installed library.
* Warning: Do not edit the next line. configure will do that for you! */
#define GPGME_VERSION "0.1.1"
#define GPGME_VERSION "0.1.2"
@ -92,6 +92,15 @@ typedef enum {
GPGME_SIG_STAT_ERROR = 5
} GpgmeSigStat;
typedef enum {
GPGME_SIG_MODE_NORMAL = 0,
GPGME_SIG_MODE_DETACH = 1,
GPGME_SIG_MODE_CLEAR = 2
} GpgmeSigMode;
typedef const char *(*GpgmePassphraseCb)(void*, const char *desc, void *r_hd);
/* Context management */
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
@ -101,6 +110,8 @@ GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang );
char *gpgme_get_notation ( GpgmeCtx c );
void gpgme_set_armor ( GpgmeCtx c, int yes );
void gpgme_set_textmode ( GpgmeCtx c, int yes );
void gpgme_set_passphrase_cb ( GpgmeCtx c,
GpgmePassphraseCb cb, void *cb_value );
@ -138,9 +149,11 @@ char *gpgme_key_get_as_xml ( GpgmeKey key );
GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
GpgmeRecipients recp,
GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c,
GpgmeData ciph, GpgmeData plain );
GpgmeError gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_sign_start ( GpgmeCtx c,
GpgmeData in, GpgmeData out,
GpgmeSigMode mode );
GpgmeError gpgme_op_verify_start ( GpgmeCtx c,
GpgmeData sig, GpgmeData text );
@ -154,9 +167,10 @@ GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key );
/* Convenience functions for normal usage */
GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_decrypt ( GpgmeCtx c, GpgmeData passphrase,
GpgmeError gpgme_op_decrypt ( GpgmeCtx c,
GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out,
GpgmeSigMode mode);
GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
GpgmeSigStat *r_status );

View File

@ -35,6 +35,7 @@ struct io_select_fd_s {
int for_read;
int for_write;
int signaled;
int frozen;
void *opaque;
};

View File

@ -25,11 +25,12 @@
/*-- gpgme.c --*/
void _gpgme_release_result ( GpgmeCtx c );
void _gpgme_set_prompt ( GpgmeCtx c, int which, const char *text );
/*-- wait.c --*/
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
int hang, volatile int *cond );
void _gpgme_freeze_fd ( int fd );
void _gpgme_thaw_fd ( int fd );
/*-- recipient.c --*/

View File

@ -28,10 +28,10 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include "syshdr.h"
#include "io.h"
@ -100,8 +100,24 @@ _gpgme_io_spawn ( const char *path, char **argv,
struct spawn_fd_item_s *fd_child_list,
struct spawn_fd_item_s *fd_parent_list )
{
static volatile int fixed_signals;
pid_t pid;
int i;
if ( !fixed_signals ) {
struct sigaction act;
sigaction( SIGPIPE, NULL, &act );
if( act.sa_handler == SIG_DFL ) {
act.sa_handler = SIG_IGN;
sigemptyset( &act.sa_mask );
act.sa_flags = 0;
sigaction( SIGPIPE, &act, NULL);
}
fixed_signals = 1;
/* fixme: This is not really MT safe */
}
pid = fork ();
if (pid == -1)
@ -134,7 +150,7 @@ _gpgme_io_spawn ( const char *path, char **argv,
}
if( !duped_stdin || !duped_stderr ) {
int fd = open ( "/dev/null", O_RDONLY );
int fd = open ( "/dev/null", O_RDWR );
if ( fd == -1 ) {
fprintf (stderr,"can't open `/dev/null': %s\n",
strerror (errno) );

View File

@ -26,9 +26,9 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include "unistd.h"
#include "gpgme.h"
#include "util.h"
@ -94,6 +94,26 @@ struct gpg_object_s {
int running;
int exit_status;
int exit_signal;
/* stuff needed for pipemode */
struct {
int used;
int active;
GpgmeData sig;
GpgmeData text;
int stream_started;
} pm;
/* stuff needed for interactive (command) mode */
struct {
int used;
int fd;
GpgmeData cb_data; /* hack to get init the above fd later */
GpgStatusCode code; /* last code */
char *keyword; /* what has been requested (malloced) */
GpgCommandHandler fnc;
void *fnc_value;
} cmd;
};
static void kill_gpg ( GpgObject gpg );
@ -109,6 +129,11 @@ static GpgmeError read_status ( GpgObject gpg );
static int gpg_colon_line_handler ( void *opaque, int pid, int fd );
static GpgmeError read_colon_line ( GpgObject gpg );
static int pipemode_cb ( void *opaque,
char *buffer, size_t length, size_t *nread );
static int command_cb ( void *opaque,
char *buffer, size_t length, size_t *nread );
GpgmeError
@ -128,6 +153,7 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
gpg->status.fd[1] = -1;
gpg->colon.fd[0] = -1;
gpg->colon.fd[1] = -1;
gpg->cmd.fd = -1;
/* allocate the read buffer for the status pipe */
gpg->status.bufsize = 1024;
@ -150,7 +176,6 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
sprintf ( buf, "%d", gpg->status.fd[1]);
_gpgme_gpg_add_arg ( gpg, buf );
}
_gpgme_gpg_add_arg ( gpg, "--batch" );
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
@ -164,6 +189,7 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
return rc;
}
void
_gpgme_gpg_release ( GpgObject gpg )
{
@ -173,6 +199,8 @@ _gpgme_gpg_release ( GpgObject gpg )
xfree (gpg->colon.buffer);
if ( gpg->argv )
free_argv (gpg->argv);
xfree (gpg->cmd.keyword);
#if 0
/* fixme: We need a way to communicate back closed fds, so that we
* don't do it a second time. One way to do it is by using a global
@ -209,7 +237,13 @@ kill_gpg ( GpgObject gpg )
#endif
}
void
_gpgme_gpg_enable_pipemode ( GpgObject gpg )
{
gpg->pm.used = 1;
assert ( !gpg->pm.sig );
assert ( !gpg->pm.text );
}
GpgmeError
_gpgme_gpg_add_arg ( GpgObject gpg, const char *arg )
@ -218,6 +252,10 @@ _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg )
assert (gpg);
assert (arg);
if (gpg->pm.active)
return 0;
a = xtrymalloc ( sizeof *a + strlen (arg) );
if ( !a ) {
gpg->arg_error = 1;
@ -239,6 +277,9 @@ _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to )
assert (gpg);
assert (data);
if (gpg->pm.active)
return 0;
a = xtrymalloc ( sizeof *a - 1 );
if ( !a ) {
gpg->arg_error = 1;
@ -259,6 +300,45 @@ _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to )
return 0;
}
GpgmeError
_gpgme_gpg_add_pm_data ( GpgObject gpg, GpgmeData data, int what )
{
GpgmeError rc=0;
assert ( gpg->pm.used );
if ( !what ) {
/* the signature */
assert ( !gpg->pm.sig );
gpg->pm.sig = data;
}
else if (what == 1) {
/* the signed data */
assert ( !gpg->pm.text );
gpg->pm.text = data;
}
else {
assert (0);
}
if ( gpg->pm.sig && gpg->pm.text ) {
if ( !gpg->pm.active ) {
/* create the callback handler and connect it to stdin */
GpgmeData tmp;
rc = gpgme_data_new_with_read_cb ( &tmp, pipemode_cb, gpg );
if (!rc )
rc = _gpgme_gpg_add_data (gpg, tmp, 0);
}
if ( !rc ) {
/* here we can reset the handler stuff */
gpg->pm.stream_started = 0;
}
}
return rc;
}
/*
* Note, that the status_handler is allowed to modifiy the args value
*/
@ -267,6 +347,9 @@ _gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc, void *fnc_value )
{
assert (gpg);
if (gpg->pm.active)
return;
gpg->status.fnc = fnc;
gpg->status.fnc_value = fnc_value;
}
@ -277,6 +360,8 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc, void *fnc_value )
{
assert (gpg);
if (gpg->pm.active)
return 0;
gpg->colon.bufsize = 1024;
gpg->colon.readpos = 0;
@ -295,6 +380,39 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
}
/*
* The Fnc will be called to get a value for one of the commands with
* a key KEY. If the Code pssed to FNC is 0, the function may release
* resources associated with the returned value from another call. To
* match such a second call to a first call, the returned value from
* the first call is passed as keyword.
*/
GpgmeError
_gpgme_gpg_set_command_handler ( GpgObject gpg,
GpgCommandHandler fnc, void *fnc_value )
{
GpgmeData tmp;
GpgmeError err;
assert (gpg);
if (gpg->pm.active)
return 0;
err = gpgme_data_new_with_read_cb ( &tmp, command_cb, gpg );
if (err)
return err;
_gpgme_gpg_add_arg ( gpg, "--command-fd" );
_gpgme_gpg_add_data (gpg, tmp, -2);
gpg->cmd.cb_data = tmp;
gpg->cmd.fnc = fnc;
gpg->cmd.fnc_value = fnc_value;
gpg->cmd.used = 1;
return 0;
}
static void
free_argv ( char **argv )
{
@ -362,6 +480,8 @@ build_argv ( GpgObject gpg )
argc++;
if (use_agent)
argc++;
if (!gpg->cmd.used)
argc++;
argv = xtrycalloc ( argc+1, sizeof *argv );
if (!argv)
@ -398,6 +518,15 @@ build_argv ( GpgObject gpg )
}
argc++;
}
if ( !gpg->cmd.used ) {
argv[argc] = xtrystrdup ( "--batch" );
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc++;
}
for ( a=gpg->arglist; a; a = a->next ) {
if ( a->data ) {
switch ( _gpgme_data_get_mode (a->data) ) {
@ -453,6 +582,13 @@ build_argv ( GpgObject gpg )
fd_data_map[datac].peer_fd = fds[0];
}
}
/* Hack to get hands on the fd later */
if ( gpg->cmd.used && gpg->cmd.cb_data == a->data ) {
assert (gpg->cmd.fd == -1);
gpg->cmd.fd = fd_data_map[datac].fd;
}
fd_data_map[datac].data = a->data;
fd_data_map[datac].dup_to = a->dup_to;
if ( a->dup_to == -1 ) {
@ -501,6 +637,9 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
if ( gpg->arg_error )
return mk_error (Out_Of_Core);
if (gpg->pm.active)
return 0;
rc = build_argv ( gpg );
if ( rc )
return rc;
@ -570,6 +709,8 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
}
gpg->pid = pid;
if (gpg->pm.used)
gpg->pm.active = 1;
/*_gpgme_register_term_handler ( closure, closure_value, pid );*/
@ -610,8 +751,11 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
}
}
/* fixme: check what data we can release here */
if ( gpg->cmd.used )
_gpgme_freeze_fd ( gpg->cmd.fd );
/* fixme: check what data we can release here */
gpg->running = 1;
return 0;
}
@ -699,7 +843,7 @@ write_cb_data ( GpgmeData dh, int fd )
return 1;
}
nwritten = _gpgme_io_write ( fd, dh->data+dh->readpos, nbytes );
nwritten = _gpgme_io_write ( fd, buffer, nbytes );
if (nwritten == -1 && errno == EAGAIN )
return 0;
if ( nwritten < 1 ) {
@ -710,6 +854,7 @@ write_cb_data ( GpgmeData dh, int fd )
}
if ( nwritten < nbytes ) {
/* ugly, ugly: It does currently only for for MEM type data */
if ( _gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten ) )
fprintf (stderr, "wite_cb_data: unread of %d bytes failed\n",
nbytes - nwritten );
@ -819,8 +964,7 @@ read_status ( GpgObject gpg )
*p = 0;
fprintf (stderr, "read_status: `%s'\n", buffer);
if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z'
&& gpg->status.fnc ) {
&& buffer[9] >= 'A' && buffer[9] <= 'Z' ) {
struct status_table_s t, *r;
char *rest;
@ -835,8 +979,30 @@ read_status ( GpgObject gpg )
r = bsearch ( &t, status_table, DIM(status_table)-1,
sizeof t, status_cmp );
if ( r ) {
gpg->status.fnc ( gpg->status.fnc_value,
r->code, rest);
if ( gpg->cmd.used
&& ( r->code == STATUS_GET_BOOL
|| r->code == STATUS_GET_LINE
|| r->code == STATUS_GET_HIDDEN )) {
gpg->cmd.code = r->code;
xfree (gpg->cmd.keyword);
gpg->cmd.keyword = xtrystrdup (rest);
if ( !gpg->cmd.keyword )
return mk_error (Out_Of_Core);
/* this should be the last thing we have received
* and the next thing will be that the command
* handler does it action */
if ( nread > 1 )
fprintf (stderr, "** ERROR, unxpected data in"
" read_status\n" );
_gpgme_thaw_fd (gpg->cmd.fd);
}
else if ( gpg->status.fnc ) {
gpg->status.fnc ( gpg->status.fnc_value,
r->code, rest);
}
}
if ( r->code == STATUS_END_STREAM ) {
/* _gpgme_freeze_fd ( ? );*/
}
}
/* To reuse the buffer for the next line we have to
@ -957,3 +1123,140 @@ read_colon_line ( GpgObject gpg )
return 0;
}
static GpgmeError
pipemode_copy (char *buffer, size_t length, size_t *nread, GpgmeData data )
{
GpgmeError err;
int nbytes;
char tmp[1000], *s, *d;
/* we can optimize this whole thing but for now we just
* return after each escape character */
if (length > 990)
length = 990;
err = gpgme_data_read ( data, tmp, length, &nbytes );
if (err)
return err;
for (s=tmp, d=buffer; nbytes; s++, nbytes--) {
*d++ = *s;
if (*s == '@' ) {
*d++ = '@';
break;
}
}
*nread = d - buffer;
return 0;
}
static int
pipemode_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
{
GpgObject gpg = opaque;
GpgmeError err;
if ( !buffer || !length || !nread )
return 0; /* those values are reserved for extensions */
*nread =0;
if ( !gpg->pm.stream_started ) {
assert (length > 4 );
strcpy (buffer, "@<@B" );
*nread = 4;
gpg->pm.stream_started = 1;
}
else if ( gpg->pm.sig ) {
err = pipemode_copy ( buffer, length, nread, gpg->pm.sig );
if ( err == GPGME_EOF ) {
gpg->pm.sig = NULL;
assert (length > 4 );
strcpy (buffer, "@t" );
*nread = 2;
}
else if (err) {
fprintf (stderr, "** pipemode_cb: copy sig failed: %s\n",
gpgme_strerror (err) );
return -1;
}
}
else if ( gpg->pm.text ) {
err = pipemode_copy ( buffer, length, nread, gpg->pm.text );
if ( err == GPGME_EOF ) {
gpg->pm.text = NULL;
assert (length > 4 );
strcpy (buffer, "@.@>" );
*nread = 4;
}
else if (err) {
fprintf (stderr, "** pipemode_cb: copy data failed: %s\n",
gpgme_strerror (err) );
return -1;
}
}
else {
return 0; /* eof */
}
return 0;
}
/*
* Here we handle --command-fd. This works closely together with
* the status handler.
*/
static int
command_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
{
GpgObject gpg = opaque;
const char *value;
int value_len;
fprintf (stderr, "** command_cb: enter\n");
assert (gpg->cmd.used);
if ( !buffer || !length || !nread )
return 0; /* those values are reserved for extensions */
*nread =0;
if ( !gpg->cmd.code ) {
fprintf (stderr, "** command_cb: no code\n");
return -1;
}
if ( !gpg->cmd.fnc ) {
fprintf (stderr, "** command_cb: no user cb\n");
return -1;
}
value = gpg->cmd.fnc ( gpg->cmd.fnc_value,
gpg->cmd.code, gpg->cmd.keyword );
if ( !value ) {
fprintf (stderr, "** command_cb: no data from user cb\n");
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
return -1;
}
value_len = strlen (value);
if ( value_len+1 > length ) {
fprintf (stderr, "** command_cb: too much data from user cb\n");
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
return -1;
}
memcpy ( buffer, value, value_len );
if ( !value_len || (value_len && value[value_len-1] != '\n') )
buffer[value_len++] = '\n';
*nread = value_len;
fprintf (stderr, "** command_cb: leave (wrote `%.*s')\n",
(int)*nread-1, buffer);
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
gpg->cmd.code = 0;
/* and sleep again until read_status will wake us up again */
_gpgme_freeze_fd ( gpg->cmd.fd );
return 0;
}

View File

@ -81,22 +81,32 @@ typedef enum {
STATUS_SESSION_KEY ,
STATUS_NOTATION_NAME ,
STATUS_NOTATION_DATA ,
STATUS_POLICY_URL
STATUS_POLICY_URL ,
STATUS_BEGIN_STREAM ,
STATUS_END_STREAM
} GpgStatusCode;
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args );
typedef void (*GpgColonLineHandler)( GpgmeCtx, char *line );
typedef const char *(*GpgCommandHandler)(void*, GpgStatusCode code,
const char *keyword);
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
void _gpgme_gpg_release ( GpgObject gpg );
void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
GpgmeError _gpgme_gpg_add_pm_data ( GpgObject gpg, GpgmeData data, int what );
void _gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_command_handler ( GpgObject gpg,
GpgCommandHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_spawn ( GpgObject gpg, void *opaque );

View File

@ -32,6 +32,7 @@
struct sign_result_s {
int no_passphrase;
int okay;
void *last_pw_handle;
};
@ -84,10 +85,48 @@ sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
}
}
static const char *
command_handler ( void *opaque, GpgStatusCode code, const char *key )
{
GpgmeCtx c = opaque;
if ( c->result_type == RESULT_TYPE_NONE ) {
assert ( !c->result.sign );
c->result.sign = xtrycalloc ( 1, sizeof *c->result.sign );
if ( !c->result.sign ) {
c->out_of_core = 1;
return NULL;
}
c->result_type = RESULT_TYPE_SIGN;
}
if ( !code ) {
/* We have been called for cleanup */
if ( c->passphrase_cb ) {
/* Fixme: take the key in account */
c->passphrase_cb (c->passphrase_cb_value, 0,
&c->result.sign->last_pw_handle );
}
return NULL;
}
if ( !key || !c->passphrase_cb )
return NULL;
if ( code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter") ) {
return c->passphrase_cb (c->passphrase_cb_value,
"Please enter your Friedrich Willem!",
&c->result.sign->last_pw_handle );
}
return NULL;
}
GpgmeError
gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out )
gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out,
GpgmeSigMode mode )
{
int rc = 0;
int i;
@ -98,23 +137,39 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out )
_gpgme_release_result (c);
c->out_of_core = 0;
/* do some checks */
assert ( !c->gpg );
if ( mode != GPGME_SIG_MODE_NORMAL
&& mode != GPGME_SIG_MODE_DETACH
&& mode != GPGME_SIG_MODE_CLEAR )
return mk_error (Invalid_Value);
/* create a process object */
_gpgme_gpg_release (c->gpg);
c->gpg = NULL;
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, sign_status_handler, c );
if (c->passphrase_cb) {
rc = _gpgme_gpg_set_command_handler ( c->gpg, command_handler, c );
if (rc)
goto leave;
}
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--sign" );
_gpgme_gpg_add_arg ( c->gpg, "--detach" );
if ( c->use_armor )
_gpgme_gpg_add_arg ( c->gpg, "--armor" );
if ( c->use_textmode )
_gpgme_gpg_add_arg ( c->gpg, "--textmode" );
if ( mode == GPGME_SIG_MODE_CLEAR ) {
_gpgme_gpg_add_arg ( c->gpg, "--clearsign" );
}
else {
_gpgme_gpg_add_arg ( c->gpg, "--sign" );
if ( mode == GPGME_SIG_MODE_DETACH )
_gpgme_gpg_add_arg ( c->gpg, "--detach" );
if ( c->use_armor )
_gpgme_gpg_add_arg ( c->gpg, "--armor" );
if ( c->use_textmode )
_gpgme_gpg_add_arg ( c->gpg, "--textmode" );
}
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
@ -151,17 +206,26 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out )
* @c: The context
* @in: Data to be signed
* @out: Detached signature
* @mode: Signature creation mode
*
* Create a detached signature for @in and write it to @out.
* The data will be signed using either the default key or the ones
* defined through @c.
* The defined modes for signature create are:
* <literal>
* GPGME_SIG_MODE_NORMAL (or 0)
* GPGME_SIG_MODE_DETACH
* GPGME_SIG_MODE_CLEAR
* </literal>
* Note that the settings done by gpgme_set_armor() and gpgme_set_textmode()
* are ignore for @mode GPGME_SIG_MODE_CLEAR.
*
* Return value: 0 on success or an error code.
**/
GpgmeError
gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out )
gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode )
{
GpgmeError err = gpgme_op_sign_start ( c, in, out );
GpgmeError err = gpgme_op_sign_start ( c, in, out, mode );
if ( !err ) {
gpgme_wait (c, 1);
if ( c->result_type != RESULT_TYPE_SIGN )

View File

@ -15,12 +15,14 @@ static struct status_table_s status_table[] =
{ "BAD_PASSPHRASE", STATUS_BAD_PASSPHRASE },
{ "BEGIN_DECRYPTION", STATUS_BEGIN_DECRYPTION },
{ "BEGIN_ENCRYPTION", STATUS_BEGIN_ENCRYPTION },
{ "BEGIN_STREAM", STATUS_BEGIN_STREAM },
{ "DECRYPTION_FAILED", STATUS_DECRYPTION_FAILED },
{ "DECRYPTION_OKAY", STATUS_DECRYPTION_OKAY },
{ "DELETE_PROBLEM", STATUS_DELETE_PROBLEM },
{ "ENC_TO", STATUS_ENC_TO },
{ "END_DECRYPTION", STATUS_END_DECRYPTION },
{ "END_ENCRYPTION", STATUS_END_ENCRYPTION },
{ "END_STREAM", STATUS_END_STREAM },
{ "ENTER", STATUS_ENTER },
{ "ERRMDC", STATUS_ERRMDC },
{ "ERRSIG", STATUS_ERRSIG },

View File

@ -124,6 +124,9 @@ verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
add_notation ( ctx, code, args );
break;
case STATUS_END_STREAM:
break;
default:
/* ignore all other codes */
fprintf (stderr, "verify_status: code=%d not handled\n", code );
@ -138,29 +141,30 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
{
int rc = 0;
int i;
int pipemode = 0 /*!!text*/; /* use pipemode for detached sigs */
fail_on_pending_request( c );
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
/* create a process object.
* To optimize this, we should reuse an existing one and
* run gpg in the new --pipemode (I started with this but it is
* not yet finished) */
if ( c->gpg ) {
_gpgme_gpg_release ( c->gpg );
if ( !pipemode ) {
_gpgme_gpg_release ( c->gpg );
c->gpg = NULL;
}
rc = _gpgme_gpg_new ( &c->gpg );
if ( !c->gpg )
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
if (pipemode)
_gpgme_gpg_enable_pipemode ( c->gpg );
_gpgme_gpg_set_status_handler ( c->gpg, verify_status_handler, c );
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--verify" );
_gpgme_gpg_add_arg ( c->gpg, pipemode?"--pipemode" : "--verify" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
@ -178,10 +182,16 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
_gpgme_data_set_mode (text, GPGME_DATA_MODE_OUT );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--" );
_gpgme_gpg_add_data ( c->gpg, sig, -1 );
if (text) {
_gpgme_gpg_add_arg ( c->gpg, "-" );
_gpgme_gpg_add_data ( c->gpg, text, 0 );
if (pipemode) {
_gpgme_gpg_add_pm_data ( c->gpg, sig, 0 );
_gpgme_gpg_add_pm_data ( c->gpg, text, 1 );
}
else {
_gpgme_gpg_add_data ( c->gpg, sig, -1 );
if (text) {
_gpgme_gpg_add_arg ( c->gpg, "-" );
_gpgme_gpg_add_data ( c->gpg, text, 0 );
}
}
/* and kick off the process */
@ -214,6 +224,7 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
* missing key
* GPGME_SIG_STAT_NOSIG: This is not a signature
* GPGME_SIG_STAT_ERROR: Due to some other error the check could not be done.
* FIXME: What do we return if only some o the signatures ae valid?
*
* Return value: 0 on success or an errorcode if something not related to
* the signature itself did go wrong.

View File

@ -28,10 +28,10 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <windows.h>
#include "syshdr.h"
#include "util.h"
#include "io.h"
@ -209,6 +209,7 @@ _gpgme_io_spawn ( const char *path, char **argv,
int duped_stdin = 0;
int duped_stderr = 0;
HANDLE hnul = INVALID_HANDLE_VALUE;
int debug_me = !!getenv ("GPGME_DEBUG");
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
@ -220,7 +221,8 @@ _gpgme_io_spawn ( const char *path, char **argv,
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = debug_me? SW_SHOW : SW_HIDE;
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
@ -268,7 +270,7 @@ _gpgme_io_spawn ( const char *path, char **argv,
}
/* We normally don't want all the normal output */
if ( !duped_stderr ) {
if (!getenv ("GPGME_DEBUG") ) {
if (!debug_me) {
si.hStdError = hnul;
DEBUG_SELECT ((stderr,"** using %d for stderr\n", (int)hnul ));
}
@ -340,7 +342,7 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
*r_status = 0;
*r_signal = 0;
code = WaitForSingleObject ( proc, hang? INFINITE : NULL );
code = WaitForSingleObject ( proc, hang? INFINITE : 0 );
switch (code) {
case WAIT_FAILED:
fprintf (stderr, "** WFSO pid=%d failed: %d\n",
@ -565,8 +567,9 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
}
}
if ( !once_more && !count ) {
/* once more but after relinquishing our timeslot */
once_more = 1;
Sleep (300);
Sleep (0);
goto restart;
}

View File

@ -24,9 +24,8 @@
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "syshdr.h"
#include "util.h"
#include "context.h"
@ -236,7 +235,8 @@ do_select ( void )
return 0; /* error or timeout */
for (i=0; i < fd_table_size /*&& n*/; i++ ) {
if ( fd_table[i].fd != -1 && fd_table[i].signaled ) {
if ( fd_table[i].fd != -1 && fd_table[i].signaled
&& !fd_table[i].frozen ) {
q = fd_table[i].opaque;
assert (n);
n--;
@ -261,7 +261,7 @@ do_select ( void )
* called by rungpg.c to register something for select()
*/
GpgmeError
_gpgme_register_pipe_handler( void *opaque,
_gpgme_register_pipe_handler ( void *opaque,
int (*handler)(void*,int,int),
void *handler_value,
int pid, int fd, int inbound )
@ -292,6 +292,7 @@ _gpgme_register_pipe_handler( void *opaque,
fd_table[i].for_read = inbound;
fd_table[i].for_write = !inbound;
fd_table[i].signaled = 0;
fd_table[i].frozen = 0;
fd_table[i].opaque = q;
unlock_table ();
return 0;
@ -318,6 +319,38 @@ _gpgme_register_pipe_handler( void *opaque,
}
void
_gpgme_freeze_fd ( int fd )
{
int i;
lock_table ();
for (i=0; i < fd_table_size; i++ ) {
if ( fd_table[i].fd == fd ) {
fd_table[i].frozen = 1;
fprintf (stderr, "** FD %d frozen\n", fd );
break;
}
}
unlock_table ();
}
void
_gpgme_thaw_fd ( int fd )
{
int i;
lock_table ();
for (i=0; i < fd_table_size; i++ ) {
if ( fd_table[i].fd == fd ) {
fd_table[i].frozen = 0;
fprintf (stderr, "** FD %d thawed\n", fd );
break;
}
}
unlock_table ();
}

View File

@ -22,7 +22,7 @@ all-local: ./pubring.gpg ./secring.gpg
-gpg --homedir . --import $(srcdir)/pubdemo.asc
./secring.gpg: ./Alpha/Secret.gpg
-gpg --homedir . --import Alpha/Secret.gpg Zulu/Secret.gpg
-gpg --homedir . --allow-secret-key-import --import Alpha/Secret.gpg Zulu/Secret.gpg
./Alpha/Secret.gpg: secdemo.asc
srcdir=$(srcdir) $(srcdir)/mkdemodirs

View File

@ -57,28 +57,23 @@ print_data ( GpgmeData dh )
}
static int
passphrase_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
static const char *
passphrase_cb ( void *opaque, const char *desc, void *r_hd )
{
struct passphrase_cb_info_s *info = opaque;
const char *desc;
const char *pass;
assert (info);
assert (info->c);
if ( !buffer || !length || !nread )
return 0; /* those values are reserved for extensions */
if ( info->did_it )
return -1; /* eof */
if ( !desc ) {
/* cleanup by looking at *r_hd */
desc = gpgme_get_prompt (info->c, 1);
if (desc)
fprintf (stderr, "Request passphrase for '%s'\n", desc );
if ( length < 3 )
return -1; /* FIXME - sending an EOF here is wrong */
memcpy (buffer, "abc", 3 );
*nread = 3;
info->did_it = 1;
return 0;
return NULL;
}
pass = "abc";
fprintf (stderr, "%% requesting passphrase for `%s': ", desc );
fprintf (stderr, "sending `%s'\n", pass );
return pass;
}
@ -111,10 +106,10 @@ main (int argc, char **argv )
do {
err = gpgme_new (&ctx);
fail_if_err (err);
if ( 0 && !getenv("GPG_AGENT_INFO") ) {
if ( !getenv("GPG_AGENT_INFO") ) {
memset ( &info, 0, sizeof info );
info.c = ctx;
gpgme_data_new_with_read_cb ( &pwdata, passphrase_cb, &info );
gpgme_set_passphrase_cb ( ctx, passphrase_cb, &info );
}
err = gpgme_data_new_from_file ( &in, cipher_1_asc, 1 );
@ -123,7 +118,7 @@ main (int argc, char **argv )
err = gpgme_data_new ( &out );
fail_if_err (err);
err = gpgme_op_decrypt (ctx, pwdata, in, out );
err = gpgme_op_decrypt (ctx, in, out );
fail_if_err (err);
fflush (NULL);

View File

@ -47,6 +47,24 @@ print_data ( GpgmeData dh )
fail_if_err (err);
}
static const char *
passphrase_cb ( void *opaque, const char *desc, void *r_hd )
{
const char *pass;
if ( !desc ) {
/* cleanup by looking at *r_hd */
return NULL;
}
pass = "abc";
fprintf (stderr, "%% requesting passphrase for `%s': ", desc );
fprintf (stderr, "sending `%s'\n", pass );
return pass;
}
int
@ -59,25 +77,55 @@ main (int argc, char **argv )
do {
err = gpgme_new (&ctx);
fail_if_err (err);
if ( !getenv("GPG_AGENT_INFO") ) {
gpgme_set_passphrase_cb ( ctx, passphrase_cb, NULL );
}
gpgme_set_textmode (ctx, 1);
gpgme_set_armor (ctx, 1);
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
fail_if_err (err);
/* first a normal signature */
err = gpgme_data_new ( &out );
fail_if_err (err);
gpgme_set_textmode (ctx, 1);
gpgme_set_armor (ctx, 1);
err = gpgme_op_sign (ctx, in, out );
err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (in);
gpgme_data_release (out);
gpgme_data_rewind (in);
/* now a detached signature */
err = gpgme_data_new ( &out );
fail_if_err (err);
err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_DETACH );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (out);
gpgme_data_rewind (in);
/* And finally a cleartext signature */
err = gpgme_data_new ( &out );
fail_if_err (err);
err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_CLEAR );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (out);
gpgme_data_rewind (in);
/* ready */
gpgme_data_release (in);
gpgme_release (ctx);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );

View File

@ -35,7 +35,7 @@ static const char test_sig1[] =
"ZgIAn0204PBR7yxSdQx6CFxugstNqmRv\n"
"=yku6\n"
"-----END PGP SIGNATURE-----\n"
#elif 0
#elif 0
"-----BEGIN PGP SIGNATURE-----\n"
"Version: GnuPG v1.0.4-2 (GNU/Linux)\n"
"Comment: For info see http://www.gnupg.org\n"
@ -108,14 +108,19 @@ main (int argc, char **argv )
err = gpgme_data_new_from_mem ( &text,
test_text1, strlen (test_text1), 0 );
fail_if_err (err);
#if 1
err = gpgme_data_new_from_mem ( &sig,
test_sig1, strlen (test_sig1), 0 );
#else
err = gpgme_data_new_from_file ( &sig, "xx1", 1 );
#endif
fail_if_err (err);
puts ("checking a valid message:\n");
err = gpgme_op_verify (ctx, sig, text, &status );
print_sig_stat ( status );
fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) )
printf ("---Begin Notation---\n%s---End Notation---\n", nota );