xref: /reactos/dll/win32/xolehlp/xolehlp.c (revision 95deef46)
1 /*
2  * Copyright 2011 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include <stdarg.h>
20 #define COBJMACROS
21 #include "windef.h"
22 #include "winbase.h"
23 #include "transact.h"
24 #include "initguid.h"
25 #include "txdtc.h"
26 #include "wine/unicode.h"
27 #include "wine/debug.h"
28 
29 WINE_DEFAULT_DEBUG_CHANNEL(xolehlp);
30 
31 /* Resource manager start */
32 
33 typedef struct {
34     IResourceManager IResourceManager_iface;
35     LONG ref;
36 } ResourceManager;
37 
impl_from_IResourceManager(IResourceManager * iface)38 static inline ResourceManager *impl_from_IResourceManager(IResourceManager *iface)
39 {
40     return CONTAINING_RECORD(iface, ResourceManager, IResourceManager_iface);
41 }
42 
ResourceManager_QueryInterface(IResourceManager * iface,REFIID iid,void ** ppv)43 static HRESULT WINAPI ResourceManager_QueryInterface(IResourceManager *iface, REFIID iid,
44     void **ppv)
45 {
46     ResourceManager *This = impl_from_IResourceManager(iface);
47     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
48 
49     if (!ppv) return E_INVALIDARG;
50 
51     if (IsEqualIID(&IID_IUnknown, iid) ||
52         IsEqualIID(&IID_IResourceManager, iid))
53     {
54         *ppv = &This->IResourceManager_iface;
55     }
56     else
57     {
58         FIXME("(%s): not implemented\n", debugstr_guid(iid));
59         *ppv = NULL;
60         return E_NOINTERFACE;
61     }
62 
63     IUnknown_AddRef((IUnknown*)*ppv);
64     return S_OK;
65 }
66 
ResourceManager_AddRef(IResourceManager * iface)67 static ULONG WINAPI ResourceManager_AddRef(IResourceManager *iface)
68 {
69     ResourceManager *This = impl_from_IResourceManager(iface);
70     ULONG ref = InterlockedIncrement(&This->ref);
71 
72     TRACE("(%p) refcount=%u\n", iface, ref);
73 
74     return ref;
75 }
76 
ResourceManager_Release(IResourceManager * iface)77 static ULONG WINAPI ResourceManager_Release(IResourceManager *iface)
78 {
79     ResourceManager *This = impl_from_IResourceManager(iface);
80     ULONG ref = InterlockedDecrement(&This->ref);
81 
82     TRACE("(%p) refcount=%u\n", iface, ref);
83 
84     if (ref == 0)
85     {
86         HeapFree(GetProcessHeap(), 0, This);
87     }
88 
89     return ref;
90 }
ResourceManager_Enlist(IResourceManager * iface,ITransaction * pTransaction,ITransactionResourceAsync * pRes,XACTUOW * pUOW,LONG * pisoLevel,ITransactionEnlistmentAsync ** ppEnlist)91 static HRESULT WINAPI ResourceManager_Enlist(IResourceManager *iface,
92 	ITransaction *pTransaction,ITransactionResourceAsync *pRes,XACTUOW *pUOW,
93 	LONG *pisoLevel,ITransactionEnlistmentAsync **ppEnlist)
94 {
95     FIXME("(%p, %p, %p, %p, %p, %p): stub\n", iface, pTransaction,pRes,pUOW,
96         pisoLevel,ppEnlist);
97     return E_NOTIMPL;
98 }
ResourceManager_Reenlist(IResourceManager * iface,byte * pPrepInfo,ULONG cbPrepInfo,DWORD lTimeout,XACTSTAT * pXactStat)99 static HRESULT WINAPI ResourceManager_Reenlist(IResourceManager *iface,
100         byte *pPrepInfo,ULONG cbPrepInfo,DWORD lTimeout,XACTSTAT *pXactStat)
101 {
102     FIXME("(%p, %p, %u, %u, %p): stub\n", iface, pPrepInfo, cbPrepInfo, lTimeout, pXactStat);
103     return E_NOTIMPL;
104 }
ResourceManager_ReenlistmentComplete(IResourceManager * iface)105 static HRESULT WINAPI ResourceManager_ReenlistmentComplete(IResourceManager *iface)
106 {
107     FIXME("(%p): stub\n", iface);
108     return S_OK;
109 }
ResourceManager_GetDistributedTransactionManager(IResourceManager * iface,REFIID iid,void ** ppvObject)110 static HRESULT WINAPI ResourceManager_GetDistributedTransactionManager(IResourceManager *iface,
111         REFIID iid,void **ppvObject)
112 {
113     FIXME("(%p, %s, %p): stub\n", iface, debugstr_guid(iid), ppvObject);
114     return E_NOTIMPL;
115 }
116 
117 static const IResourceManagerVtbl ResourceManager_Vtbl = {
118     ResourceManager_QueryInterface,
119     ResourceManager_AddRef,
120     ResourceManager_Release,
121     ResourceManager_Enlist,
122     ResourceManager_Reenlist,
123     ResourceManager_ReenlistmentComplete,
124     ResourceManager_GetDistributedTransactionManager
125 };
126 
ResourceManager_Create(REFIID riid,void ** ppv)127 static HRESULT ResourceManager_Create(REFIID riid, void **ppv)
128 {
129     ResourceManager *This;
130     HRESULT ret;
131 
132     if (!ppv) return E_INVALIDARG;
133 
134     This = HeapAlloc(GetProcessHeap(), 0, sizeof(ResourceManager));
135     if (!This) return E_OUTOFMEMORY;
136 
137     This->IResourceManager_iface.lpVtbl = &ResourceManager_Vtbl;
138     This->ref = 1;
139 
140     ret = IResourceManager_QueryInterface(&This->IResourceManager_iface, riid, ppv);
141     IResourceManager_Release(&This->IResourceManager_iface);
142 
143     return ret;
144 }
145 
146 /* Resource manager end */
147 
148 /* Transaction options start */
149 
150 typedef struct {
151     ITransactionOptions ITransactionOptions_iface;
152     LONG ref;
153     XACTOPT opts;
154 } TransactionOptions;
155 
impl_from_ITransactionOptions(ITransactionOptions * iface)156 static inline TransactionOptions *impl_from_ITransactionOptions(ITransactionOptions *iface)
157 {
158     return CONTAINING_RECORD(iface, TransactionOptions, ITransactionOptions_iface);
159 }
160 
TransactionOptions_QueryInterface(ITransactionOptions * iface,REFIID iid,void ** ppv)161 static HRESULT WINAPI TransactionOptions_QueryInterface(ITransactionOptions *iface, REFIID iid,
162     void **ppv)
163 {
164     TransactionOptions *This = impl_from_ITransactionOptions(iface);
165     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
166 
167     if (!ppv) return E_INVALIDARG;
168 
169     if (IsEqualIID(&IID_IUnknown, iid) ||
170         IsEqualIID(&IID_ITransactionOptions, iid))
171     {
172         *ppv = &This->ITransactionOptions_iface;
173     }
174     else
175     {
176         FIXME("(%s): not implemented\n", debugstr_guid(iid));
177         *ppv = NULL;
178         return E_NOINTERFACE;
179     }
180 
181     IUnknown_AddRef((IUnknown*)*ppv);
182     return S_OK;
183 }
184 
TransactionOptions_AddRef(ITransactionOptions * iface)185 static ULONG WINAPI TransactionOptions_AddRef(ITransactionOptions *iface)
186 {
187     TransactionOptions *This = impl_from_ITransactionOptions(iface);
188     ULONG ref = InterlockedIncrement(&This->ref);
189 
190     TRACE("(%p) refcount=%u\n", iface, ref);
191 
192     return ref;
193 }
194 
TransactionOptions_Release(ITransactionOptions * iface)195 static ULONG WINAPI TransactionOptions_Release(ITransactionOptions *iface)
196 {
197     TransactionOptions *This = impl_from_ITransactionOptions(iface);
198     ULONG ref = InterlockedDecrement(&This->ref);
199 
200     TRACE("(%p) refcount=%u\n", iface, ref);
201 
202     if (ref == 0)
203     {
204         HeapFree(GetProcessHeap(), 0, This);
205     }
206 
207     return ref;
208 }
TransactionOptions_SetOptions(ITransactionOptions * iface,XACTOPT * pOptions)209 static HRESULT WINAPI TransactionOptions_SetOptions(ITransactionOptions *iface,
210     XACTOPT *pOptions)
211 {
212     TransactionOptions *This = impl_from_ITransactionOptions(iface);
213 
214     if (!pOptions) return E_INVALIDARG;
215     TRACE("(%p, %u, %s)\n", iface, pOptions->ulTimeout, debugstr_a(pOptions->szDescription));
216     This->opts = *pOptions;
217     return S_OK;
218 }
TransactionOptions_GetOptions(ITransactionOptions * iface,XACTOPT * pOptions)219 static HRESULT WINAPI TransactionOptions_GetOptions(ITransactionOptions *iface,
220     XACTOPT *pOptions)
221 {
222     TransactionOptions *This = impl_from_ITransactionOptions(iface);
223 
224     TRACE("(%p, %p)\n", iface, pOptions);
225     if (!pOptions) return E_INVALIDARG;
226     *pOptions = This->opts;
227     return S_OK;
228 }
229 
230 static const ITransactionOptionsVtbl TransactionOptions_Vtbl = {
231     TransactionOptions_QueryInterface,
232     TransactionOptions_AddRef,
233     TransactionOptions_Release,
234     TransactionOptions_SetOptions,
235     TransactionOptions_GetOptions
236 };
237 
TransactionOptions_Create(ITransactionOptions ** ppv)238 static HRESULT TransactionOptions_Create(ITransactionOptions **ppv)
239 {
240     TransactionOptions *This;
241 
242     if (!ppv) return E_INVALIDARG;
243 
244     This = HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionOptions));
245     if (!This) return E_OUTOFMEMORY;
246 
247     This->ITransactionOptions_iface.lpVtbl = &TransactionOptions_Vtbl;
248     This->ref = 1;
249 
250     *ppv = &This->ITransactionOptions_iface;
251 
252     return S_OK;
253 }
254 
255 /* Transaction options end */
256 
257 /* Transaction start */
258 
259 typedef struct {
260     ITransaction ITransaction_iface;
261     LONG ref;
262     XACTTRANSINFO info;
263 } Transaction;
264 
impl_from_ITransaction(ITransaction * iface)265 static inline Transaction *impl_from_ITransaction(ITransaction *iface)
266 {
267     return CONTAINING_RECORD(iface, Transaction, ITransaction_iface);
268 }
269 
Transaction_QueryInterface(ITransaction * iface,REFIID iid,void ** ppv)270 static HRESULT WINAPI Transaction_QueryInterface(ITransaction *iface, REFIID iid,
271     void **ppv)
272 {
273     Transaction *This = impl_from_ITransaction(iface);
274     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
275 
276     if (!ppv) return E_INVALIDARG;
277 
278     if (IsEqualIID(&IID_IUnknown, iid) ||
279         IsEqualIID(&IID_ITransaction, iid))
280     {
281         *ppv = &This->ITransaction_iface;
282     }
283     else
284     {
285         FIXME("(%s): not implemented\n", debugstr_guid(iid));
286         *ppv = NULL;
287         return E_NOINTERFACE;
288     }
289 
290     IUnknown_AddRef((IUnknown*)*ppv);
291     return S_OK;
292 }
293 
Transaction_AddRef(ITransaction * iface)294 static ULONG WINAPI Transaction_AddRef(ITransaction *iface)
295 {
296     Transaction *This = impl_from_ITransaction(iface);
297     ULONG ref = InterlockedIncrement(&This->ref);
298 
299     TRACE("(%p) refcount=%u\n", iface, ref);
300 
301     return ref;
302 }
303 
Transaction_Release(ITransaction * iface)304 static ULONG WINAPI Transaction_Release(ITransaction *iface)
305 {
306     Transaction *This = impl_from_ITransaction(iface);
307     ULONG ref = InterlockedDecrement(&This->ref);
308 
309     TRACE("(%p) refcount=%u\n", iface, ref);
310 
311     if (ref == 0)
312     {
313         HeapFree(GetProcessHeap(), 0, This);
314     }
315 
316     return ref;
317 }
Transaction_Commit(ITransaction * iface,BOOL fRetaining,DWORD grfTC,DWORD grfRM)318 static HRESULT WINAPI Transaction_Commit(ITransaction *iface,
319     BOOL fRetaining, DWORD grfTC, DWORD grfRM)
320 {
321     FIXME("(%p, %d, %08x, %08x): stub\n", iface, fRetaining, grfTC, grfRM);
322     return E_NOTIMPL;
323 }
Transaction_Abort(ITransaction * iface,BOID * pboidReason,BOOL fRetaining,BOOL fAsync)324 static HRESULT WINAPI Transaction_Abort(ITransaction *iface,
325     BOID *pboidReason, BOOL fRetaining, BOOL fAsync)
326 {
327     FIXME("(%p, %p, %d, %d): stub\n", iface, pboidReason, fRetaining, fAsync);
328     return E_NOTIMPL;
329 }
Transaction_GetTransactionInfo(ITransaction * iface,XACTTRANSINFO * pinfo)330 static HRESULT WINAPI Transaction_GetTransactionInfo(ITransaction *iface,
331     XACTTRANSINFO *pinfo)
332 {
333     Transaction *This = impl_from_ITransaction(iface);
334     TRACE("(%p, %p)\n", iface, pinfo);
335     if (!pinfo) return E_INVALIDARG;
336     *pinfo = This->info;
337     return S_OK;
338 }
339 
340 static const ITransactionVtbl Transaction_Vtbl = {
341     Transaction_QueryInterface,
342     Transaction_AddRef,
343     Transaction_Release,
344     Transaction_Commit,
345     Transaction_Abort,
346     Transaction_GetTransactionInfo
347 };
348 
Transaction_Create(ISOLEVEL isoLevel,ULONG isoFlags,ITransactionOptions * pOptions,ITransaction ** ppv)349 static HRESULT Transaction_Create(ISOLEVEL isoLevel, ULONG isoFlags,
350         ITransactionOptions *pOptions, ITransaction **ppv)
351 {
352     Transaction *This;
353 
354     if (!ppv) return E_INVALIDARG;
355 
356     This = HeapAlloc(GetProcessHeap(), 0, sizeof(Transaction));
357     if (!This) return E_OUTOFMEMORY;
358     ZeroMemory(&This->info, sizeof(This->info));
359 
360     This->ITransaction_iface.lpVtbl = &Transaction_Vtbl;
361     This->ref = 1;
362     This->info.isoLevel = isoLevel;
363     This->info.isoFlags = isoFlags;
364 
365     *ppv = &This->ITransaction_iface;
366 
367     return S_OK;
368 }
369 
370 /* Transaction end */
371 
372 /* DTC Proxy Core Object start */
373 
374 typedef struct {
375     ITransactionDispenser ITransactionDispenser_iface;
376     LONG ref;
377     IResourceManagerFactory2 IResourceManagerFactory2_iface;
378     ITransactionImportWhereabouts ITransactionImportWhereabouts_iface;
379     ITransactionImport ITransactionImport_iface;
380 } TransactionManager;
381 
impl_from_ITransactionDispenser(ITransactionDispenser * iface)382 static inline TransactionManager *impl_from_ITransactionDispenser(ITransactionDispenser *iface)
383 {
384     return CONTAINING_RECORD(iface, TransactionManager, ITransactionDispenser_iface);
385 }
386 
TransactionDispenser_QueryInterface(ITransactionDispenser * iface,REFIID iid,void ** ppv)387 static HRESULT WINAPI TransactionDispenser_QueryInterface(ITransactionDispenser *iface, REFIID iid,
388     void **ppv)
389 {
390     TransactionManager *This = impl_from_ITransactionDispenser(iface);
391     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
392 
393     if (!ppv) return E_INVALIDARG;
394 
395     if (IsEqualIID(&IID_IUnknown, iid) ||
396         IsEqualIID(&IID_ITransactionDispenser, iid))
397     {
398         *ppv = &This->ITransactionDispenser_iface;
399     }
400     else if (IsEqualIID(&IID_IResourceManagerFactory, iid) ||
401         IsEqualIID(&IID_IResourceManagerFactory2, iid))
402     {
403         *ppv = &This->IResourceManagerFactory2_iface;
404     }
405     else if (IsEqualIID(&IID_ITransactionImportWhereabouts, iid))
406     {
407         *ppv = &This->ITransactionImportWhereabouts_iface;
408     }
409     else if (IsEqualIID(&IID_ITransactionImport, iid))
410     {
411         *ppv = &This->ITransactionImport_iface;
412     }
413     else
414     {
415         FIXME("(%s): not implemented\n", debugstr_guid(iid));
416         *ppv = NULL;
417         return E_NOINTERFACE;
418     }
419 
420     IUnknown_AddRef((IUnknown*)*ppv);
421     return S_OK;
422 }
423 
TransactionDispenser_AddRef(ITransactionDispenser * iface)424 static ULONG WINAPI TransactionDispenser_AddRef(ITransactionDispenser *iface)
425 {
426     TransactionManager *This = impl_from_ITransactionDispenser(iface);
427     ULONG ref = InterlockedIncrement(&This->ref);
428 
429     TRACE("(%p) refcount=%u\n", iface, ref);
430 
431     return ref;
432 }
433 
TransactionDispenser_Release(ITransactionDispenser * iface)434 static ULONG WINAPI TransactionDispenser_Release(ITransactionDispenser *iface)
435 {
436     TransactionManager *This = impl_from_ITransactionDispenser(iface);
437     ULONG ref = InterlockedDecrement(&This->ref);
438 
439     TRACE("(%p) refcount=%u\n", iface, ref);
440 
441     if (ref == 0)
442     {
443         HeapFree(GetProcessHeap(), 0, This);
444     }
445 
446     return ref;
447 }
448 
TransactionDispenser_GetOptionsObject(ITransactionDispenser * iface,ITransactionOptions ** ppOptions)449 static HRESULT WINAPI TransactionDispenser_GetOptionsObject(ITransactionDispenser *iface,
450         ITransactionOptions **ppOptions)
451 {
452     TRACE("(%p, %p)\n", iface, ppOptions);
453 
454     if (!ppOptions) return E_INVALIDARG;
455     return TransactionOptions_Create(ppOptions);
456 }
TransactionDispenser_BeginTransaction(ITransactionDispenser * iface,IUnknown * punkOuter,ISOLEVEL isoLevel,ULONG isoFlags,ITransactionOptions * pOptions,ITransaction ** ppTransaction)457 static HRESULT WINAPI TransactionDispenser_BeginTransaction(ITransactionDispenser *iface,
458         IUnknown *punkOuter,
459         ISOLEVEL isoLevel,
460         ULONG isoFlags,
461         ITransactionOptions *pOptions,
462         ITransaction **ppTransaction)
463 {
464     FIXME("(%p, %p, %08x, %08x, %p, %p): semi-stub\n", iface, punkOuter,
465         isoLevel, isoFlags, pOptions, ppTransaction);
466 
467     if (!ppTransaction) return E_INVALIDARG;
468     if (punkOuter) return CLASS_E_NOAGGREGATION;
469     return Transaction_Create(isoLevel, isoFlags, pOptions, ppTransaction);
470 }
471 static const ITransactionDispenserVtbl TransactionDispenser_Vtbl = {
472     TransactionDispenser_QueryInterface,
473     TransactionDispenser_AddRef,
474     TransactionDispenser_Release,
475     TransactionDispenser_GetOptionsObject,
476     TransactionDispenser_BeginTransaction
477 };
478 
impl_from_IResourceManagerFactory2(IResourceManagerFactory2 * iface)479 static inline TransactionManager *impl_from_IResourceManagerFactory2(IResourceManagerFactory2 *iface)
480 {
481     return CONTAINING_RECORD(iface, TransactionManager, IResourceManagerFactory2_iface);
482 }
483 
ResourceManagerFactory2_QueryInterface(IResourceManagerFactory2 * iface,REFIID iid,void ** ppv)484 static HRESULT WINAPI ResourceManagerFactory2_QueryInterface(IResourceManagerFactory2 *iface, REFIID iid,
485     void **ppv)
486 {
487     TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
488     return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
489 }
490 
ResourceManagerFactory2_AddRef(IResourceManagerFactory2 * iface)491 static ULONG WINAPI ResourceManagerFactory2_AddRef(IResourceManagerFactory2 *iface)
492 {
493     TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
494     return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
495 }
496 
ResourceManagerFactory2_Release(IResourceManagerFactory2 * iface)497 static ULONG WINAPI ResourceManagerFactory2_Release(IResourceManagerFactory2 *iface)
498 {
499     TransactionManager *This = impl_from_IResourceManagerFactory2(iface);
500     return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
501 }
ResourceManagerFactory2_Create(IResourceManagerFactory2 * iface,GUID * pguidRM,CHAR * pszRMName,IResourceManagerSink * pIResMgrSink,IResourceManager ** ppResMgr)502 static HRESULT WINAPI ResourceManagerFactory2_Create(IResourceManagerFactory2 *iface,
503         GUID *pguidRM, CHAR *pszRMName, IResourceManagerSink *pIResMgrSink, IResourceManager **ppResMgr)
504 {
505     FIXME("(%p, %s, %s, %p, %p): semi-stub\n", iface, debugstr_guid(pguidRM),
506         debugstr_a(pszRMName), pIResMgrSink, ppResMgr);
507     return ResourceManager_Create(&IID_IResourceManager, (void**)ppResMgr);
508 }
ResourceManagerFactory2_CreateEx(IResourceManagerFactory2 * iface,GUID * pguidRM,CHAR * pszRMName,IResourceManagerSink * pIResMgrSink,REFIID riidRequested,void ** ppResMgr)509 static HRESULT WINAPI ResourceManagerFactory2_CreateEx(IResourceManagerFactory2 *iface,
510         GUID *pguidRM, CHAR *pszRMName, IResourceManagerSink *pIResMgrSink, REFIID riidRequested, void **ppResMgr)
511 {
512     FIXME("(%p, %s, %s, %p, %s, %p): semi-stub\n", iface, debugstr_guid(pguidRM),
513         debugstr_a(pszRMName), pIResMgrSink, debugstr_guid(riidRequested), ppResMgr);
514 
515     return ResourceManager_Create(riidRequested, ppResMgr);
516 }
517 static const IResourceManagerFactory2Vtbl ResourceManagerFactory2_Vtbl = {
518     ResourceManagerFactory2_QueryInterface,
519     ResourceManagerFactory2_AddRef,
520     ResourceManagerFactory2_Release,
521     ResourceManagerFactory2_Create,
522     ResourceManagerFactory2_CreateEx
523 };
524 
impl_from_ITransactionImportWhereabouts(ITransactionImportWhereabouts * iface)525 static inline TransactionManager *impl_from_ITransactionImportWhereabouts(ITransactionImportWhereabouts *iface)
526 {
527     return CONTAINING_RECORD(iface, TransactionManager, ITransactionImportWhereabouts_iface);
528 }
529 
TransactionImportWhereabouts_QueryInterface(ITransactionImportWhereabouts * iface,REFIID iid,void ** ppv)530 static HRESULT WINAPI TransactionImportWhereabouts_QueryInterface(ITransactionImportWhereabouts *iface, REFIID iid,
531     void **ppv)
532 {
533     TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
534     return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
535 }
536 
TransactionImportWhereabouts_AddRef(ITransactionImportWhereabouts * iface)537 static ULONG WINAPI TransactionImportWhereabouts_AddRef(ITransactionImportWhereabouts *iface)
538 {
539     TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
540     return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
541 }
542 
TransactionImportWhereabouts_Release(ITransactionImportWhereabouts * iface)543 static ULONG WINAPI TransactionImportWhereabouts_Release(ITransactionImportWhereabouts *iface)
544 {
545     TransactionManager *This = impl_from_ITransactionImportWhereabouts(iface);
546     return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
547 }
TransactionImportWhereabouts_GetWhereaboutsSize(ITransactionImportWhereabouts * iface,ULONG * pcbWhereabouts)548 static HRESULT WINAPI TransactionImportWhereabouts_GetWhereaboutsSize(ITransactionImportWhereabouts *iface,
549         ULONG *pcbWhereabouts)
550 {
551     FIXME("(%p, %p): stub returning fake value\n", iface, pcbWhereabouts);
552 
553     if (!pcbWhereabouts) return E_INVALIDARG;
554     *pcbWhereabouts = 1;
555     return S_OK;
556 }
TransactionImportWhereabouts_GetWhereabouts(ITransactionImportWhereabouts * iface,ULONG cbWhereabouts,BYTE * rgbWhereabouts,ULONG * pcbUsed)557 static HRESULT WINAPI TransactionImportWhereabouts_GetWhereabouts(ITransactionImportWhereabouts *iface,
558         ULONG cbWhereabouts, BYTE *rgbWhereabouts,ULONG *pcbUsed)
559 {
560     FIXME("(%p, %u, %p, %p): stub returning fake value\n", iface, cbWhereabouts, rgbWhereabouts, pcbUsed);
561 
562     if (!rgbWhereabouts || !pcbUsed) return E_INVALIDARG;
563     *rgbWhereabouts = 0;
564     *pcbUsed = 1;
565     return S_OK;
566 }
567 static const ITransactionImportWhereaboutsVtbl TransactionImportWhereabouts_Vtbl = {
568     TransactionImportWhereabouts_QueryInterface,
569     TransactionImportWhereabouts_AddRef,
570     TransactionImportWhereabouts_Release,
571     TransactionImportWhereabouts_GetWhereaboutsSize,
572     TransactionImportWhereabouts_GetWhereabouts
573 };
574 
impl_from_ITransactionImport(ITransactionImport * iface)575 static inline TransactionManager *impl_from_ITransactionImport(ITransactionImport *iface)
576 {
577     return CONTAINING_RECORD(iface, TransactionManager, ITransactionImport_iface);
578 }
579 
TransactionImport_QueryInterface(ITransactionImport * iface,REFIID iid,void ** ppv)580 static HRESULT WINAPI TransactionImport_QueryInterface(ITransactionImport *iface, REFIID iid,
581     void **ppv)
582 {
583     TransactionManager *This = impl_from_ITransactionImport(iface);
584     return TransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, iid, ppv);
585 }
586 
TransactionImport_AddRef(ITransactionImport * iface)587 static ULONG WINAPI TransactionImport_AddRef(ITransactionImport *iface)
588 {
589     TransactionManager *This = impl_from_ITransactionImport(iface);
590     return TransactionDispenser_AddRef(&This->ITransactionDispenser_iface);
591 }
592 
TransactionImport_Release(ITransactionImport * iface)593 static ULONG WINAPI TransactionImport_Release(ITransactionImport *iface)
594 {
595     TransactionManager *This = impl_from_ITransactionImport(iface);
596     return TransactionDispenser_Release(&This->ITransactionDispenser_iface);
597 }
TransactionImport_Import(ITransactionImport * iface,ULONG cbTransactionCookie,byte * rgbTransactionCookie,IID * piid,void ** ppvTransaction)598 static HRESULT WINAPI TransactionImport_Import(ITransactionImport *iface,
599     ULONG cbTransactionCookie, byte *rgbTransactionCookie, IID *piid, void **ppvTransaction)
600 {
601     FIXME("(%p, %u, %p, %s, %p): stub\n", iface, cbTransactionCookie, rgbTransactionCookie, debugstr_guid(piid), ppvTransaction);
602 
603     if (!rgbTransactionCookie || !piid || !ppvTransaction) return E_INVALIDARG;
604     return E_NOTIMPL;
605 }
606 static const ITransactionImportVtbl TransactionImport_Vtbl = {
607     TransactionImport_QueryInterface,
608     TransactionImport_AddRef,
609     TransactionImport_Release,
610     TransactionImport_Import
611 };
612 
TransactionManager_Create(REFIID riid,void ** ppv)613 static HRESULT TransactionManager_Create(REFIID riid, void **ppv)
614 {
615     TransactionManager *This;
616     HRESULT ret;
617 
618     This = HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionManager));
619     if (!This) return E_OUTOFMEMORY;
620 
621     This->ITransactionDispenser_iface.lpVtbl = &TransactionDispenser_Vtbl;
622     This->IResourceManagerFactory2_iface.lpVtbl = &ResourceManagerFactory2_Vtbl;
623     This->ITransactionImportWhereabouts_iface.lpVtbl = &TransactionImportWhereabouts_Vtbl;
624     This->ITransactionImport_iface.lpVtbl = &TransactionImport_Vtbl;
625     This->ref = 1;
626 
627     ret = ITransactionDispenser_QueryInterface(&This->ITransactionDispenser_iface, riid, ppv);
628     ITransactionDispenser_Release(&This->ITransactionDispenser_iface);
629 
630     return ret;
631 }
632 /* DTC Proxy Core Object end */
633 
DllMain(HINSTANCE hinst,DWORD reason,LPVOID reserved)634 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
635 {
636     TRACE("%p, %u, %p\n", hinst, reason, reserved);
637 
638     switch (reason)
639     {
640         case DLL_WINE_PREATTACH:
641             return FALSE;    /* prefer native version */
642         case DLL_PROCESS_ATTACH:
643             DisableThreadLibraryCalls( hinst );
644             break;
645     }
646     return TRUE;
647 }
648 
is_local_machineA(const CHAR * server)649 static BOOL is_local_machineA( const CHAR *server )
650 {
651     static const CHAR dot[] = ".";
652     CHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
653     DWORD len = ARRAY_SIZE( buffer );
654 
655     if (!server || !strcmp( server, dot )) return TRUE;
656     if (GetComputerNameA( buffer, &len ) && !lstrcmpiA( server, buffer )) return TRUE;
657     return FALSE;
658 }
is_local_machineW(const WCHAR * server)659 static BOOL is_local_machineW( const WCHAR *server )
660 {
661     static const WCHAR dotW[] = {'.',0};
662     WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1];
663     DWORD len = ARRAY_SIZE( buffer );
664 
665     if (!server || !strcmpW( server, dotW )) return TRUE;
666     if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE;
667     return FALSE;
668 }
669 
DtcGetTransactionManager(char * host,char * tm_name,REFIID riid,DWORD dwReserved1,WORD wcbReserved2,void * pvReserved2,void ** ppv)670 HRESULT CDECL DtcGetTransactionManager(char *host, char *tm_name, REFIID riid,
671         DWORD dwReserved1, WORD wcbReserved2, void *pvReserved2, void **ppv)
672 {
673     TRACE("(%s, %s, %s, %d, %d, %p, %p)\n", debugstr_a(host), debugstr_a(tm_name),
674           debugstr_guid(riid), dwReserved1, wcbReserved2, pvReserved2, ppv);
675 
676     if (!is_local_machineA(host))
677     {
678         FIXME("remote computer not supported\n");
679         return E_NOTIMPL;
680     }
681     return TransactionManager_Create(riid, ppv);
682 }
683 
DtcGetTransactionManagerExA(CHAR * host,CHAR * tm_name,REFIID riid,DWORD options,void * config,void ** ppv)684 HRESULT CDECL DtcGetTransactionManagerExA(CHAR *host, CHAR *tm_name, REFIID riid,
685         DWORD options, void *config, void **ppv)
686 {
687     TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_a(host), debugstr_a(tm_name),
688           debugstr_guid(riid), options, config, ppv);
689 
690     if (!is_local_machineA(host))
691     {
692         FIXME("remote computer not supported\n");
693         return E_NOTIMPL;
694     }
695     return TransactionManager_Create(riid, ppv);
696 }
697 
DtcGetTransactionManagerExW(WCHAR * host,WCHAR * tm_name,REFIID riid,DWORD options,void * config,void ** ppv)698 HRESULT CDECL DtcGetTransactionManagerExW(WCHAR *host, WCHAR *tm_name, REFIID riid,
699         DWORD options, void *config, void **ppv)
700 {
701     TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_w(host), debugstr_w(tm_name),
702             debugstr_guid(riid), options, config, ppv);
703 
704     if (!is_local_machineW(host))
705     {
706         FIXME("remote computer not supported\n");
707         return E_NOTIMPL;
708     }
709     return TransactionManager_Create(riid, ppv);
710 }
711