2 * Copyright 2011 Hans Leidekker for CodeWeavers
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.
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.
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
26 #include "wine/unicode.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(xolehlp
);
31 /* Resource manager start */
34 IResourceManager IResourceManager_iface
;
38 static inline ResourceManager
*impl_from_IResourceManager(IResourceManager
*iface
)
40 return CONTAINING_RECORD(iface
, ResourceManager
, IResourceManager_iface
);
43 static HRESULT WINAPI
ResourceManager_QueryInterface(IResourceManager
*iface
, REFIID iid
,
46 ResourceManager
*This
= impl_from_IResourceManager(iface
);
47 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
49 if (!ppv
) return E_INVALIDARG
;
51 if (IsEqualIID(&IID_IUnknown
, iid
) ||
52 IsEqualIID(&IID_IResourceManager
, iid
))
54 *ppv
= &This
->IResourceManager_iface
;
58 FIXME("(%s): not implemented\n", debugstr_guid(iid
));
63 IUnknown_AddRef((IUnknown
*)*ppv
);
67 static ULONG WINAPI
ResourceManager_AddRef(IResourceManager
*iface
)
69 ResourceManager
*This
= impl_from_IResourceManager(iface
);
70 ULONG ref
= InterlockedIncrement(&This
->ref
);
72 TRACE("(%p) refcount=%u\n", iface
, ref
);
77 static ULONG WINAPI
ResourceManager_Release(IResourceManager
*iface
)
79 ResourceManager
*This
= impl_from_IResourceManager(iface
);
80 ULONG ref
= InterlockedDecrement(&This
->ref
);
82 TRACE("(%p) refcount=%u\n", iface
, ref
);
86 HeapFree(GetProcessHeap(), 0, This
);
91 static HRESULT WINAPI
ResourceManager_Enlist(IResourceManager
*iface
,
92 ITransaction
*pTransaction
,ITransactionResourceAsync
*pRes
,XACTUOW
*pUOW
,
93 LONG
*pisoLevel
,ITransactionEnlistmentAsync
**ppEnlist
)
95 FIXME("(%p, %p, %p, %p, %p, %p): stub\n", iface
, pTransaction
,pRes
,pUOW
,
99 static HRESULT WINAPI
ResourceManager_Reenlist(IResourceManager
*iface
,
100 byte
*pPrepInfo
,ULONG cbPrepInfo
,DWORD lTimeout
,XACTSTAT
*pXactStat
)
102 FIXME("(%p, %p, %u, %u, %p): stub\n", iface
, pPrepInfo
, cbPrepInfo
, lTimeout
, pXactStat
);
105 static HRESULT WINAPI
ResourceManager_ReenlistmentComplete(IResourceManager
*iface
)
107 FIXME("(%p): stub\n", iface
);
110 static HRESULT WINAPI
ResourceManager_GetDistributedTransactionManager(IResourceManager
*iface
,
111 REFIID iid
,void **ppvObject
)
113 FIXME("(%p, %s, %p): stub\n", iface
, debugstr_guid(iid
), ppvObject
);
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
127 static HRESULT
ResourceManager_Create(REFIID riid
, void **ppv
)
129 ResourceManager
*This
;
132 if (!ppv
) return E_INVALIDARG
;
134 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ResourceManager
));
135 if (!This
) return E_OUTOFMEMORY
;
137 This
->IResourceManager_iface
.lpVtbl
= &ResourceManager_Vtbl
;
140 ret
= IResourceManager_QueryInterface(&This
->IResourceManager_iface
, riid
, ppv
);
141 IResourceManager_Release(&This
->IResourceManager_iface
);
146 /* Resource manager end */
148 /* Transaction options start */
151 ITransactionOptions ITransactionOptions_iface
;
154 } TransactionOptions
;
156 static inline TransactionOptions
*impl_from_ITransactionOptions(ITransactionOptions
*iface
)
158 return CONTAINING_RECORD(iface
, TransactionOptions
, ITransactionOptions_iface
);
161 static HRESULT WINAPI
TransactionOptions_QueryInterface(ITransactionOptions
*iface
, REFIID iid
,
164 TransactionOptions
*This
= impl_from_ITransactionOptions(iface
);
165 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
167 if (!ppv
) return E_INVALIDARG
;
169 if (IsEqualIID(&IID_IUnknown
, iid
) ||
170 IsEqualIID(&IID_ITransactionOptions
, iid
))
172 *ppv
= &This
->ITransactionOptions_iface
;
176 FIXME("(%s): not implemented\n", debugstr_guid(iid
));
178 return E_NOINTERFACE
;
181 IUnknown_AddRef((IUnknown
*)*ppv
);
185 static ULONG WINAPI
TransactionOptions_AddRef(ITransactionOptions
*iface
)
187 TransactionOptions
*This
= impl_from_ITransactionOptions(iface
);
188 ULONG ref
= InterlockedIncrement(&This
->ref
);
190 TRACE("(%p) refcount=%u\n", iface
, ref
);
195 static ULONG WINAPI
TransactionOptions_Release(ITransactionOptions
*iface
)
197 TransactionOptions
*This
= impl_from_ITransactionOptions(iface
);
198 ULONG ref
= InterlockedDecrement(&This
->ref
);
200 TRACE("(%p) refcount=%u\n", iface
, ref
);
204 HeapFree(GetProcessHeap(), 0, This
);
209 static HRESULT WINAPI
TransactionOptions_SetOptions(ITransactionOptions
*iface
,
212 TransactionOptions
*This
= impl_from_ITransactionOptions(iface
);
214 if (!pOptions
) return E_INVALIDARG
;
215 TRACE("(%p, %u, %s)\n", iface
, pOptions
->ulTimeout
, debugstr_a(pOptions
->szDescription
));
216 This
->opts
= *pOptions
;
219 static HRESULT WINAPI
TransactionOptions_GetOptions(ITransactionOptions
*iface
,
222 TransactionOptions
*This
= impl_from_ITransactionOptions(iface
);
224 TRACE("(%p, %p)\n", iface
, pOptions
);
225 if (!pOptions
) return E_INVALIDARG
;
226 *pOptions
= This
->opts
;
230 static const ITransactionOptionsVtbl TransactionOptions_Vtbl
= {
231 TransactionOptions_QueryInterface
,
232 TransactionOptions_AddRef
,
233 TransactionOptions_Release
,
234 TransactionOptions_SetOptions
,
235 TransactionOptions_GetOptions
238 static HRESULT
TransactionOptions_Create(ITransactionOptions
**ppv
)
240 TransactionOptions
*This
;
242 if (!ppv
) return E_INVALIDARG
;
244 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionOptions
));
245 if (!This
) return E_OUTOFMEMORY
;
247 This
->ITransactionOptions_iface
.lpVtbl
= &TransactionOptions_Vtbl
;
250 *ppv
= &This
->ITransactionOptions_iface
;
255 /* Transaction options end */
257 /* DTC Proxy Core Object start */
260 ITransactionDispenser ITransactionDispenser_iface
;
262 IResourceManagerFactory2 IResourceManagerFactory2_iface
;
263 ITransactionImportWhereabouts ITransactionImportWhereabouts_iface
;
264 ITransactionImport ITransactionImport_iface
;
265 } TransactionManager
;
267 static inline TransactionManager
*impl_from_ITransactionDispenser(ITransactionDispenser
*iface
)
269 return CONTAINING_RECORD(iface
, TransactionManager
, ITransactionDispenser_iface
);
272 static HRESULT WINAPI
TransactionDispenser_QueryInterface(ITransactionDispenser
*iface
, REFIID iid
,
275 TransactionManager
*This
= impl_from_ITransactionDispenser(iface
);
276 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
278 if (!ppv
) return E_INVALIDARG
;
280 if (IsEqualIID(&IID_IUnknown
, iid
) ||
281 IsEqualIID(&IID_ITransactionDispenser
, iid
))
283 *ppv
= &This
->ITransactionDispenser_iface
;
285 else if (IsEqualIID(&IID_IResourceManagerFactory
, iid
) ||
286 IsEqualIID(&IID_IResourceManagerFactory2
, iid
))
288 *ppv
= &This
->IResourceManagerFactory2_iface
;
290 else if (IsEqualIID(&IID_ITransactionImportWhereabouts
, iid
))
292 *ppv
= &This
->ITransactionImportWhereabouts_iface
;
294 else if (IsEqualIID(&IID_ITransactionImport
, iid
))
296 *ppv
= &This
->ITransactionImport_iface
;
300 FIXME("(%s): not implemented\n", debugstr_guid(iid
));
302 return E_NOINTERFACE
;
305 IUnknown_AddRef((IUnknown
*)*ppv
);
309 static ULONG WINAPI
TransactionDispenser_AddRef(ITransactionDispenser
*iface
)
311 TransactionManager
*This
= impl_from_ITransactionDispenser(iface
);
312 ULONG ref
= InterlockedIncrement(&This
->ref
);
314 TRACE("(%p) refcount=%u\n", iface
, ref
);
319 static ULONG WINAPI
TransactionDispenser_Release(ITransactionDispenser
*iface
)
321 TransactionManager
*This
= impl_from_ITransactionDispenser(iface
);
322 ULONG ref
= InterlockedDecrement(&This
->ref
);
324 TRACE("(%p) refcount=%u\n", iface
, ref
);
328 HeapFree(GetProcessHeap(), 0, This
);
334 static HRESULT WINAPI
TransactionDispenser_GetOptionsObject(ITransactionDispenser
*iface
,
335 ITransactionOptions
**ppOptions
)
337 TRACE("(%p, %p)\n", iface
, ppOptions
);
339 if (!ppOptions
) return E_INVALIDARG
;
340 return TransactionOptions_Create(ppOptions
);
342 static HRESULT WINAPI
TransactionDispenser_BeginTransaction(ITransactionDispenser
*iface
,
346 ITransactionOptions
*pOptions
,
347 ITransaction
**ppTransaction
)
349 FIXME("(%p, %p, %08x, %08x, %p, %p): stub\n", iface
, punkOuter
,
350 isoLevel
, isoFlags
, pOptions
, ppTransaction
);
352 if (!ppTransaction
) return E_INVALIDARG
;
353 *ppTransaction
= NULL
;
354 if (punkOuter
) return CLASS_E_NOAGGREGATION
;
357 static const ITransactionDispenserVtbl TransactionDispenser_Vtbl
= {
358 TransactionDispenser_QueryInterface
,
359 TransactionDispenser_AddRef
,
360 TransactionDispenser_Release
,
361 TransactionDispenser_GetOptionsObject
,
362 TransactionDispenser_BeginTransaction
365 static inline TransactionManager
*impl_from_IResourceManagerFactory2(IResourceManagerFactory2
*iface
)
367 return CONTAINING_RECORD(iface
, TransactionManager
, IResourceManagerFactory2_iface
);
370 static HRESULT WINAPI
ResourceManagerFactory2_QueryInterface(IResourceManagerFactory2
*iface
, REFIID iid
,
373 TransactionManager
*This
= impl_from_IResourceManagerFactory2(iface
);
374 return TransactionDispenser_QueryInterface(&This
->ITransactionDispenser_iface
, iid
, ppv
);
377 static ULONG WINAPI
ResourceManagerFactory2_AddRef(IResourceManagerFactory2
*iface
)
379 TransactionManager
*This
= impl_from_IResourceManagerFactory2(iface
);
380 return TransactionDispenser_AddRef(&This
->ITransactionDispenser_iface
);
383 static ULONG WINAPI
ResourceManagerFactory2_Release(IResourceManagerFactory2
*iface
)
385 TransactionManager
*This
= impl_from_IResourceManagerFactory2(iface
);
386 return TransactionDispenser_Release(&This
->ITransactionDispenser_iface
);
388 static HRESULT WINAPI
ResourceManagerFactory2_Create(IResourceManagerFactory2
*iface
,
389 GUID
*pguidRM
, CHAR
*pszRMName
, IResourceManagerSink
*pIResMgrSink
, IResourceManager
**ppResMgr
)
391 FIXME("(%p, %s, %s, %p, %p): semi-stub\n", iface
, debugstr_guid(pguidRM
),
392 debugstr_a(pszRMName
), pIResMgrSink
, ppResMgr
);
393 return ResourceManager_Create(&IID_IResourceManager
, (void**)ppResMgr
);
395 static HRESULT WINAPI
ResourceManagerFactory2_CreateEx(IResourceManagerFactory2
*iface
,
396 GUID
*pguidRM
, CHAR
*pszRMName
, IResourceManagerSink
*pIResMgrSink
, REFIID riidRequested
, void **ppResMgr
)
398 FIXME("(%p, %s, %s, %p, %s, %p): semi-stub\n", iface
, debugstr_guid(pguidRM
),
399 debugstr_a(pszRMName
), pIResMgrSink
, debugstr_guid(riidRequested
), ppResMgr
);
401 return ResourceManager_Create(riidRequested
, ppResMgr
);
403 static const IResourceManagerFactory2Vtbl ResourceManagerFactory2_Vtbl
= {
404 ResourceManagerFactory2_QueryInterface
,
405 ResourceManagerFactory2_AddRef
,
406 ResourceManagerFactory2_Release
,
407 ResourceManagerFactory2_Create
,
408 ResourceManagerFactory2_CreateEx
411 static inline TransactionManager
*impl_from_ITransactionImportWhereabouts(ITransactionImportWhereabouts
*iface
)
413 return CONTAINING_RECORD(iface
, TransactionManager
, ITransactionImportWhereabouts_iface
);
416 static HRESULT WINAPI
TransactionImportWhereabouts_QueryInterface(ITransactionImportWhereabouts
*iface
, REFIID iid
,
419 TransactionManager
*This
= impl_from_ITransactionImportWhereabouts(iface
);
420 return TransactionDispenser_QueryInterface(&This
->ITransactionDispenser_iface
, iid
, ppv
);
423 static ULONG WINAPI
TransactionImportWhereabouts_AddRef(ITransactionImportWhereabouts
*iface
)
425 TransactionManager
*This
= impl_from_ITransactionImportWhereabouts(iface
);
426 return TransactionDispenser_AddRef(&This
->ITransactionDispenser_iface
);
429 static ULONG WINAPI
TransactionImportWhereabouts_Release(ITransactionImportWhereabouts
*iface
)
431 TransactionManager
*This
= impl_from_ITransactionImportWhereabouts(iface
);
432 return TransactionDispenser_Release(&This
->ITransactionDispenser_iface
);
434 static HRESULT WINAPI
TransactionImportWhereabouts_GetWhereaboutsSize(ITransactionImportWhereabouts
*iface
,
435 ULONG
*pcbWhereabouts
)
437 FIXME("(%p, %p): stub returning fake value\n", iface
, pcbWhereabouts
);
439 if (!pcbWhereabouts
) return E_INVALIDARG
;
443 static HRESULT WINAPI
TransactionImportWhereabouts_GetWhereabouts(ITransactionImportWhereabouts
*iface
,
444 ULONG cbWhereabouts
, BYTE
*rgbWhereabouts
,ULONG
*pcbUsed
)
446 FIXME("(%p, %u, %p, %p): stub returning fake value\n", iface
, cbWhereabouts
, rgbWhereabouts
, pcbUsed
);
448 if (!rgbWhereabouts
|| !pcbUsed
) return E_INVALIDARG
;
453 static const ITransactionImportWhereaboutsVtbl TransactionImportWhereabouts_Vtbl
= {
454 TransactionImportWhereabouts_QueryInterface
,
455 TransactionImportWhereabouts_AddRef
,
456 TransactionImportWhereabouts_Release
,
457 TransactionImportWhereabouts_GetWhereaboutsSize
,
458 TransactionImportWhereabouts_GetWhereabouts
461 static inline TransactionManager
*impl_from_ITransactionImport(ITransactionImport
*iface
)
463 return CONTAINING_RECORD(iface
, TransactionManager
, ITransactionImport_iface
);
466 static HRESULT WINAPI
TransactionImport_QueryInterface(ITransactionImport
*iface
, REFIID iid
,
469 TransactionManager
*This
= impl_from_ITransactionImport(iface
);
470 return TransactionDispenser_QueryInterface(&This
->ITransactionDispenser_iface
, iid
, ppv
);
473 static ULONG WINAPI
TransactionImport_AddRef(ITransactionImport
*iface
)
475 TransactionManager
*This
= impl_from_ITransactionImport(iface
);
476 return TransactionDispenser_AddRef(&This
->ITransactionDispenser_iface
);
479 static ULONG WINAPI
TransactionImport_Release(ITransactionImport
*iface
)
481 TransactionManager
*This
= impl_from_ITransactionImport(iface
);
482 return TransactionDispenser_Release(&This
->ITransactionDispenser_iface
);
484 static HRESULT WINAPI
TransactionImport_Import(ITransactionImport
*iface
,
485 ULONG cbTransactionCookie
, byte
*rgbTransactionCookie
, IID
*piid
, void **ppvTransaction
)
487 FIXME("(%p, %u, %p, %s, %p): stub\n", iface
, cbTransactionCookie
, rgbTransactionCookie
, debugstr_guid(piid
), ppvTransaction
);
489 if (!rgbTransactionCookie
|| !piid
|| !ppvTransaction
) return E_INVALIDARG
;
492 static const ITransactionImportVtbl TransactionImport_Vtbl
= {
493 TransactionImport_QueryInterface
,
494 TransactionImport_AddRef
,
495 TransactionImport_Release
,
496 TransactionImport_Import
499 static HRESULT
TransactionManager_Create(REFIID riid
, void **ppv
)
501 TransactionManager
*This
;
504 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(TransactionManager
));
505 if (!This
) return E_OUTOFMEMORY
;
507 This
->ITransactionDispenser_iface
.lpVtbl
= &TransactionDispenser_Vtbl
;
508 This
->IResourceManagerFactory2_iface
.lpVtbl
= &ResourceManagerFactory2_Vtbl
;
509 This
->ITransactionImportWhereabouts_iface
.lpVtbl
= &TransactionImportWhereabouts_Vtbl
;
510 This
->ITransactionImport_iface
.lpVtbl
= &TransactionImport_Vtbl
;
513 ret
= ITransactionDispenser_QueryInterface(&This
->ITransactionDispenser_iface
, riid
, ppv
);
514 ITransactionDispenser_Release(&This
->ITransactionDispenser_iface
);
518 /* DTC Proxy Core Object end */
520 BOOL WINAPI
DllMain( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
522 TRACE("%p, %u, %p\n", hinst
, reason
, reserved
);
526 case DLL_WINE_PREATTACH
:
527 return FALSE
; /* prefer native version */
528 case DLL_PROCESS_ATTACH
:
529 DisableThreadLibraryCalls( hinst
);
535 static BOOL
is_local_machineA( const CHAR
*server
)
537 static const CHAR dot
[] = ".";
538 CHAR buffer
[MAX_COMPUTERNAME_LENGTH
+ 1];
539 DWORD len
= sizeof(buffer
) / sizeof(buffer
[0]);
541 if (!server
|| !strcmp( server
, dot
)) return TRUE
;
542 if (GetComputerNameA( buffer
, &len
) && !lstrcmpiA( server
, buffer
)) return TRUE
;
545 static BOOL
is_local_machineW( const WCHAR
*server
)
547 static const WCHAR dotW
[] = {'.',0};
548 WCHAR buffer
[MAX_COMPUTERNAME_LENGTH
+ 1];
549 DWORD len
= sizeof(buffer
) / sizeof(buffer
[0]);
551 if (!server
|| !strcmpW( server
, dotW
)) return TRUE
;
552 if (GetComputerNameW( buffer
, &len
) && !strcmpiW( server
, buffer
)) return TRUE
;
556 HRESULT CDECL
DtcGetTransactionManager(char *host
, char *tm_name
, REFIID riid
,
557 DWORD dwReserved1
, WORD wcbReserved2
, void *pvReserved2
, void **ppv
)
559 TRACE("(%s, %s, %s, %d, %d, %p, %p)\n", debugstr_a(host
), debugstr_a(tm_name
),
560 debugstr_guid(riid
), dwReserved1
, wcbReserved2
, pvReserved2
, ppv
);
562 if (!is_local_machineA(host
))
564 FIXME("remote computer not supported\n");
567 return TransactionManager_Create(riid
, ppv
);
570 HRESULT CDECL
DtcGetTransactionManagerExA(CHAR
*host
, CHAR
*tm_name
, REFIID riid
,
571 DWORD options
, void *config
, void **ppv
)
573 TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_a(host
), debugstr_a(tm_name
),
574 debugstr_guid(riid
), options
, config
, ppv
);
576 if (!is_local_machineA(host
))
578 FIXME("remote computer not supported\n");
581 return TransactionManager_Create(riid
, ppv
);
584 HRESULT CDECL
DtcGetTransactionManagerExW(WCHAR
*host
, WCHAR
*tm_name
, REFIID riid
,
585 DWORD options
, void *config
, void **ppv
)
587 TRACE("(%s, %s, %s, %d, %p, %p)\n", debugstr_w(host
), debugstr_w(tm_name
),
588 debugstr_guid(riid
), options
, config
, ppv
);
590 if (!is_local_machineW(host
))
592 FIXME("remote computer not supported\n");
595 return TransactionManager_Create(riid
, ppv
);