1 // IArchive.h
2 
3 #ifndef __IARCHIVE_H
4 #define __IARCHIVE_H
5 
6 #include "../IProgress.h"
7 #include "../IStream.h"
8 #include "../PropID.h"
9 
10 #define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
11 #define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
12 
13 namespace NFileTimeType
14 {
15   enum EEnum
16   {
17     kWindows,
18     kUnix,
19     kDOS
20   };
21 }
22 
23 namespace NArchive
24 {
25   enum
26   {
27     kName = 0,
28     kClassID,
29     kExtension,
30     kAddExtension,
31     kUpdate,
32     kKeepName,
33     kStartSignature,
34     kFinishSignature,
35     kAssociate
36   };
37 
38   namespace NExtract
39   {
40     namespace NAskMode
41     {
42       enum
43       {
44         kExtract = 0,
45         kTest,
46         kSkip
47       };
48     }
49     namespace NOperationResult
50     {
51       enum
52       {
53         kOK = 0,
54         kUnSupportedMethod,
55         kDataError,
56         kCRCError
57       };
58     }
59   }
60   namespace NUpdate
61   {
62     namespace NOperationResult
63     {
64       enum
65       {
66         kOK = 0,
67         kError
68       };
69     }
70   }
71 }
72 
73 #define INTERFACE_IArchiveOpenCallback(x) \
74   STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \
75   STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \
76 
77 ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
78 {
79   INTERFACE_IArchiveOpenCallback(PURE);
80 };
81 
82 
83 #define INTERFACE_IArchiveExtractCallback(x) \
84   INTERFACE_IProgress(x) \
85   STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,  Int32 askExtractMode) x; \
86   STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
87   STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \
88 
89 ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
90 {
91   INTERFACE_IArchiveExtractCallback(PURE)
92 };
93 
94 
95 #define INTERFACE_IArchiveOpenVolumeCallback(x) \
96   STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \
97   STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \
98 
99 ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
100 {
101   INTERFACE_IArchiveOpenVolumeCallback(PURE);
102 };
103 
104 
105 ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
106 {
107   STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
108 };
109 
110 
111 ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
112 {
113   STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
114 };
115 
116 
117 /*
118 IInArchive::Extract:
119   indices must be sorted
120   numItems = 0xFFFFFFFF means "all files"
121   testMode != 0 means "test files without writing to outStream"
122 */
123 
124 #define INTERFACE_IInArchive(x) \
125   STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
126   STDMETHOD(Close)() x; \
127   STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
128   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
129   STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
130   STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
131   STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
132   STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
133   STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
134   STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
135 
136 ARCHIVE_INTERFACE(IInArchive, 0x60)
137 {
138   INTERFACE_IInArchive(PURE)
139 };
140 
141 ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
142 {
143   STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
144 };
145 
146 #define INTERFACE_IArchiveUpdateCallback(x) \
147   INTERFACE_IProgress(x); \
148   STDMETHOD(GetUpdateItemInfo)(UInt32 index,  \
149       Int32 *newData, /*1 - new data, 0 - old data */ \
150       Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \
151       UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \
152       )  x; \
153   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
154   STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
155   STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
156 
157 ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
158 {
159   INTERFACE_IArchiveUpdateCallback(PURE);
160 };
161 
162 #define INTERFACE_IArchiveUpdateCallback2(x) \
163   INTERFACE_IArchiveUpdateCallback(x) \
164   STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \
165   STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \
166 
167 ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
168 {
169   INTERFACE_IArchiveUpdateCallback2(PURE);
170 };
171 
172 
173 #define INTERFACE_IOutArchive(x) \
174   STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
175   STDMETHOD(GetFileTimeType)(UInt32 *type) x;
176 
177 ARCHIVE_INTERFACE(IOutArchive, 0xA0)
178 {
179   INTERFACE_IOutArchive(PURE)
180 };
181 
182 
183 ARCHIVE_INTERFACE(ISetProperties, 0x03)
184 {
185   STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
186 };
187 
188 
189 #define IMP_IInArchive_GetProp(k) \
190   (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
191     { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
192     const STATPROPSTG &srcItem = k[index]; \
193     *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
194 
195 #define IMP_IInArchive_GetProp_WITH_NAME(k) \
196   (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
197     { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
198     const STATPROPSTG &srcItem = k[index]; \
199     *propID = srcItem.propid; *varType = srcItem.vt; \
200     if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
201 
202 #define IMP_IInArchive_Props \
203   STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
204     { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
205   STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
206 
207 #define IMP_IInArchive_Props_WITH_NAME \
208   STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
209     { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
210   STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
211 
212 
213 #define IMP_IInArchive_ArcProps \
214   STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
215     { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
216   STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
217 
218 #define IMP_IInArchive_ArcProps_WITH_NAME \
219   STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
220     { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
221   STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
222 
223 #define IMP_IInArchive_ArcProps_NO_Table \
224   STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
225     { *numProperties = 0; return S_OK; } \
226   STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
227     { return E_NOTIMPL; } \
228 
229 #define IMP_IInArchive_ArcProps_NO \
230   IMP_IInArchive_ArcProps_NO_Table \
231   STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
232     { value->vt = VT_EMPTY; return S_OK; }
233 
234 #endif
235