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