api-ms-win-core-comm-l1-1-0: Add dll.
[wine.git] / dlls / opcservices / uri.c
blobe461ebaa5870a2db07aa1019c0cd2f9ea434ec87
1 /*
2 * Copyright 2018 Nikolay Sivov 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
19 #define COBJMACROS
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
25 #include "wine/debug.h"
26 #include "wine/unicode.h"
28 #include "opc_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(msopc);
32 static inline struct opc_uri *impl_from_IOpcPartUri(IOpcPartUri *iface)
34 return CONTAINING_RECORD(iface, struct opc_uri, IOpcPartUri_iface);
37 static HRESULT opc_source_uri_create(struct opc_uri *uri, IOpcUri **out);
39 static HRESULT WINAPI opc_uri_QueryInterface(IOpcPartUri *iface, REFIID iid, void **out)
41 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
43 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
45 if ((uri->is_part_uri && IsEqualIID(iid, &IID_IOpcPartUri)) ||
46 IsEqualIID(iid, &IID_IOpcUri) ||
47 IsEqualIID(iid, &IID_IUri) ||
48 IsEqualIID(iid, &IID_IUnknown))
50 *out = iface;
51 IOpcPartUri_AddRef(iface);
52 return S_OK;
55 WARN("Unsupported interface %s.\n", debugstr_guid(iid));
56 return E_NOINTERFACE;
59 static ULONG WINAPI opc_uri_AddRef(IOpcPartUri *iface)
61 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
62 ULONG refcount = InterlockedIncrement(&uri->refcount);
64 TRACE("%p increasing refcount to %u.\n", iface, refcount);
66 return refcount;
69 static ULONG WINAPI opc_uri_Release(IOpcPartUri *iface)
71 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
72 ULONG refcount = InterlockedDecrement(&uri->refcount);
74 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
76 if (!refcount)
78 if (uri->rels_part_uri)
79 IUri_Release(uri->rels_part_uri);
80 if (uri->source_uri)
81 IOpcPartUri_Release(&uri->source_uri->IOpcPartUri_iface);
82 IUri_Release(uri->uri);
83 heap_free(uri);
86 return refcount;
89 static HRESULT WINAPI opc_uri_GetPropertyBSTR(IOpcPartUri *iface, Uri_PROPERTY property,
90 BSTR *value, DWORD flags)
92 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
94 TRACE("iface %p, property %d, value %p, flags %#x.\n", iface, property, value, flags);
96 return IUri_GetPropertyBSTR(uri->uri, property, value, flags);
99 static HRESULT WINAPI opc_uri_GetPropertyLength(IOpcPartUri *iface, Uri_PROPERTY property,
100 DWORD *length, DWORD flags)
102 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
104 TRACE("iface %p, property %d, length %p, flags %#x.\n", iface, property, length, flags);
106 return IUri_GetPropertyLength(uri->uri, property, length, flags);
109 static HRESULT WINAPI opc_uri_GetPropertyDWORD(IOpcPartUri *iface, Uri_PROPERTY property,
110 DWORD *value, DWORD flags)
112 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
114 TRACE("iface %p, property %d, value %p, flags %#x.\n", iface, property, value, flags);
116 return IUri_GetPropertyDWORD(uri->uri, property, value, flags);
119 static HRESULT WINAPI opc_uri_HasProperty(IOpcPartUri *iface, Uri_PROPERTY property,
120 BOOL *has_property)
122 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
124 TRACE("iface %p, property %d, has_property %p.\n", iface, property, has_property);
126 return IUri_HasProperty(uri->uri, property, has_property);
129 static HRESULT WINAPI opc_uri_GetAbsoluteUri(IOpcPartUri *iface, BSTR *value)
131 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
133 TRACE("iface %p, value %p.\n", iface, value);
135 return IUri_GetAbsoluteUri(uri->uri, value);
138 static HRESULT WINAPI opc_uri_GetAuthority(IOpcPartUri *iface, BSTR *value)
140 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
142 TRACE("iface %p, value %p.\n", iface, value);
144 return IUri_GetAuthority(uri->uri, value);
147 static HRESULT WINAPI opc_uri_GetDisplayUri(IOpcPartUri *iface, BSTR *value)
149 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
151 TRACE("iface %p, value %p.\n", iface, value);
153 return IUri_GetDisplayUri(uri->uri, value);
156 static HRESULT WINAPI opc_uri_GetDomain(IOpcPartUri *iface, BSTR *value)
158 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
160 TRACE("iface %p, value %p.\n", iface, value);
162 return IUri_GetDomain(uri->uri, value);
165 static HRESULT WINAPI opc_uri_GetExtension(IOpcPartUri *iface, BSTR *value)
167 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
169 TRACE("iface %p, value %p.\n", iface, value);
171 return IUri_GetExtension(uri->uri, value);
174 static HRESULT WINAPI opc_uri_GetFragment(IOpcPartUri *iface, BSTR *value)
176 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
178 TRACE("iface %p, value %p.\n", iface, value);
180 return IUri_GetFragment(uri->uri, value);
183 static HRESULT WINAPI opc_uri_GetHost(IOpcPartUri *iface, BSTR *value)
185 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
187 TRACE("iface %p, value %p.\n", iface, value);
189 return IUri_GetHost(uri->uri, value);
192 static HRESULT WINAPI opc_uri_GetPassword(IOpcPartUri *iface, BSTR *value)
194 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
196 TRACE("iface %p, value %p.\n", iface, value);
198 return IUri_GetPassword(uri->uri, value);
201 static HRESULT WINAPI opc_uri_GetPath(IOpcPartUri *iface, BSTR *value)
203 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
205 TRACE("iface %p, value %p.\n", iface, value);
207 return IUri_GetPath(uri->uri, value);
210 static HRESULT WINAPI opc_uri_GetPathAndQuery(IOpcPartUri *iface, BSTR *value)
212 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
214 TRACE("iface %p, value %p.\n", iface, value);
216 return IUri_GetPathAndQuery(uri->uri, value);
219 static HRESULT WINAPI opc_uri_GetQuery(IOpcPartUri *iface, BSTR *value)
221 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
223 TRACE("iface %p, value %p.\n", iface, value);
225 return IUri_GetQuery(uri->uri, value);
228 static HRESULT WINAPI opc_uri_GetRawUri(IOpcPartUri *iface, BSTR *value)
230 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
232 TRACE("iface %p, value %p.\n", iface, value);
234 return IUri_GetRawUri(uri->uri, value);
237 static HRESULT WINAPI opc_uri_GetSchemeName(IOpcPartUri *iface, BSTR *value)
239 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
241 TRACE("iface %p, value %p.\n", iface, value);
243 return IUri_GetSchemeName(uri->uri, value);
246 static HRESULT WINAPI opc_uri_GetUserInfo(IOpcPartUri *iface, BSTR *value)
248 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
250 TRACE("iface %p, value %p.\n", iface, value);
252 return IUri_GetUserInfo(uri->uri, value);
255 static HRESULT WINAPI opc_uri_GetUserName(IOpcPartUri *iface, BSTR *value)
257 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
259 TRACE("iface %p, value %p.\n", iface, value);
261 return IUri_GetUserName(uri->uri, value);
264 static HRESULT WINAPI opc_uri_GetHostType(IOpcPartUri *iface, DWORD *value)
266 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
268 TRACE("iface %p, value %p.\n", iface, value);
270 return IUri_GetHostType(uri->uri, value);
273 static HRESULT WINAPI opc_uri_GetPort(IOpcPartUri *iface, DWORD *value)
275 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
277 TRACE("iface %p, value %p.\n", iface, value);
279 return IUri_GetPort(uri->uri, value);
282 static HRESULT WINAPI opc_uri_GetScheme(IOpcPartUri *iface, DWORD *value)
284 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
286 TRACE("iface %p, value %p.\n", iface, value);
288 return IUri_GetScheme(uri->uri, value);
291 static HRESULT WINAPI opc_uri_GetZone(IOpcPartUri *iface, DWORD *value)
293 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
295 TRACE("iface %p, value %p.\n", iface, value);
297 return IUri_GetZone(uri->uri, value);
300 static HRESULT WINAPI opc_uri_GetProperties(IOpcPartUri *iface, DWORD *flags)
302 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
304 TRACE("iface %p, flags %p.\n", iface, flags);
306 return IUri_GetProperties(uri->uri, flags);
309 static HRESULT WINAPI opc_uri_IsEqual(IOpcPartUri *iface, IUri *comparand, BOOL *is_equal)
311 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
313 TRACE("iface %p, comparand %p, is_equal %p.\n", iface, comparand, is_equal);
315 return IUri_IsEqual(uri->uri, comparand, is_equal);
318 static HRESULT WINAPI opc_uri_GetRelationshipsPartUri(IOpcPartUri *iface, IOpcPartUri **part_uri)
320 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
322 TRACE("iface %p, part_uri %p.\n", iface, part_uri);
324 if (!part_uri)
325 return E_POINTER;
327 if (!uri->rels_part_uri)
329 *part_uri = NULL;
330 return OPC_E_NONCONFORMING_URI;
333 return opc_part_uri_create(uri->rels_part_uri, uri, part_uri);
336 static HRESULT WINAPI opc_uri_GetRelativeUri(IOpcPartUri *iface, IOpcPartUri *part_uri,
337 IUri **relative_uri)
339 FIXME("iface %p, part_uri %p, relative_uri %p stub!\n", iface, part_uri, relative_uri);
341 return E_NOTIMPL;
344 static HRESULT WINAPI opc_uri_CombinePartUri(IOpcPartUri *iface, IUri *relative_uri, IOpcPartUri **combined)
346 FIXME("iface %p, relative_uri %p, combined %p stub!\n", iface, relative_uri, combined);
348 return E_NOTIMPL;
351 static HRESULT WINAPI opc_uri_ComparePartUri(IOpcPartUri *iface, IOpcPartUri *part_uri,
352 INT32 *result)
354 FIXME("iface %p, part_uri %p, result %p stub!\n", iface, part_uri, result);
356 return E_NOTIMPL;
359 static HRESULT WINAPI opc_uri_GetSourceUri(IOpcPartUri *iface, IOpcUri **source_uri)
361 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
363 TRACE("iface %p, source_uri %p.\n", iface, source_uri);
365 return opc_source_uri_create(uri, source_uri);
368 static HRESULT WINAPI opc_uri_IsRelationshipsPartUri(IOpcPartUri *iface, BOOL *result)
370 struct opc_uri *uri = impl_from_IOpcPartUri(iface);
372 TRACE("iface %p, result %p.\n", iface, result);
374 if (!result)
375 return E_POINTER;
377 *result = !uri->rels_part_uri;
379 return S_OK;
382 static const IOpcPartUriVtbl opc_part_uri_vtbl =
384 opc_uri_QueryInterface,
385 opc_uri_AddRef,
386 opc_uri_Release,
387 opc_uri_GetPropertyBSTR,
388 opc_uri_GetPropertyLength,
389 opc_uri_GetPropertyDWORD,
390 opc_uri_HasProperty,
391 opc_uri_GetAbsoluteUri,
392 opc_uri_GetAuthority,
393 opc_uri_GetDisplayUri,
394 opc_uri_GetDomain,
395 opc_uri_GetExtension,
396 opc_uri_GetFragment,
397 opc_uri_GetHost,
398 opc_uri_GetPassword,
399 opc_uri_GetPath,
400 opc_uri_GetPathAndQuery,
401 opc_uri_GetQuery,
402 opc_uri_GetRawUri,
403 opc_uri_GetSchemeName,
404 opc_uri_GetUserInfo,
405 opc_uri_GetUserName,
406 opc_uri_GetHostType,
407 opc_uri_GetPort,
408 opc_uri_GetScheme,
409 opc_uri_GetZone,
410 opc_uri_GetProperties,
411 opc_uri_IsEqual,
412 opc_uri_GetRelationshipsPartUri,
413 opc_uri_GetRelativeUri,
414 opc_uri_CombinePartUri,
415 opc_uri_ComparePartUri,
416 opc_uri_GetSourceUri,
417 opc_uri_IsRelationshipsPartUri,
420 static IUri *opc_part_uri_get_rels_uri(IUri *uri)
422 static const WCHAR relsdirW[] = {'/','_','r','e','l','s',0};
423 static const WCHAR relsextW[] = {'.','r','e','l','s',0};
424 WCHAR *start = NULL, *end, *ret;
425 IUri *rels_uri;
426 HRESULT hr;
427 DWORD len;
428 BSTR path;
430 if (FAILED(IUri_GetPath(uri, &path)))
431 return NULL;
433 if (FAILED(IUri_GetPropertyLength(uri, Uri_PROPERTY_PATH, &len, 0)))
435 SysFreeString(path);
436 return NULL;
439 end = strrchrW(path, '/');
440 if (end && end >= path + ARRAY_SIZE(relsdirW) - 1)
441 start = end - ARRAY_SIZE(relsdirW) + 1;
442 if (!start)
443 start = end;
445 /* Test if it's already relationships uri. */
446 if (len > ARRAY_SIZE(relsextW))
448 if (!strcmpW(path + len - ARRAY_SIZE(relsextW) + 1, relsextW))
450 if (start && !memcmp(start, relsdirW, ARRAY_SIZE(relsdirW) - sizeof(WCHAR)))
452 SysFreeString(path);
453 return NULL;
458 ret = heap_alloc((len + ARRAY_SIZE(relsextW) + ARRAY_SIZE(relsdirW)) * sizeof(WCHAR));
459 if (!ret)
461 SysFreeString(path);
462 return NULL;
464 ret[0] = 0;
466 if (start != path)
468 memcpy(ret, path, (start - path) * sizeof(WCHAR));
469 ret[start - path] = 0;
472 strcatW(ret, relsdirW);
473 strcatW(ret, end);
474 strcatW(ret, relsextW);
476 if (FAILED(hr = CreateUri(ret, Uri_CREATE_ALLOW_RELATIVE, 0, &rels_uri)))
477 WARN("Failed to create rels uri, hr %#x.\n", hr);
478 heap_free(ret);
480 return rels_uri;
483 static HRESULT opc_part_uri_init(struct opc_uri *object, struct opc_uri *source_uri, BOOL is_part_uri, IUri *uri)
485 object->IOpcPartUri_iface.lpVtbl = &opc_part_uri_vtbl;
486 object->refcount = 1;
487 object->is_part_uri = is_part_uri;
488 object->uri = uri;
489 IUri_AddRef(object->uri);
490 object->rels_part_uri = opc_part_uri_get_rels_uri(object->uri);
491 object->source_uri = source_uri;
492 if (object->source_uri)
493 IOpcPartUri_AddRef(&object->source_uri->IOpcPartUri_iface);
495 return S_OK;
498 static HRESULT opc_source_uri_create(struct opc_uri *uri, IOpcUri **out)
500 struct opc_uri *obj;
501 HRESULT hr;
503 if (!out)
504 return E_POINTER;
506 *out = NULL;
508 if (!uri->source_uri)
509 return OPC_E_RELATIONSHIP_URI_REQUIRED;
511 if (!(obj = heap_alloc_zero(sizeof(*obj))))
512 return E_OUTOFMEMORY;
514 if (FAILED(hr = opc_part_uri_init(obj, NULL, uri->source_uri->is_part_uri, uri->source_uri->uri)))
516 WARN("Failed to init part uri, hr %#x.\n", hr);
517 heap_free(obj);
518 return hr;
521 *out = (IOpcUri *)&obj->IOpcPartUri_iface;
523 TRACE("Created source uri %p.\n", *out);
525 return S_OK;
528 HRESULT opc_part_uri_create(IUri *uri, struct opc_uri *source_uri, IOpcPartUri **out)
530 struct opc_uri *obj;
531 HRESULT hr;
533 if (!(obj = heap_alloc_zero(sizeof(*obj))))
534 return E_OUTOFMEMORY;
536 if (FAILED(hr = opc_part_uri_init(obj, source_uri, TRUE, uri)))
538 WARN("Failed to init part uri, hr %#x.\n", hr);
539 heap_free(obj);
540 return hr;
543 *out = &obj->IOpcPartUri_iface;
544 TRACE("Created part uri %p.\n", *out);
545 return S_OK;
548 HRESULT opc_root_uri_create(IOpcUri **out)
550 static const WCHAR rootW[] = {'/',0};
551 struct opc_uri *obj;
552 HRESULT hr;
553 IUri *uri;
555 *out = NULL;
557 if (!(obj = heap_alloc_zero(sizeof(*obj))))
558 return E_OUTOFMEMORY;
560 if (FAILED(hr = CreateUri(rootW, Uri_CREATE_ALLOW_RELATIVE, 0, &uri)))
562 WARN("Failed to create rels uri, hr %#x.\n", hr);
563 heap_free(obj);
564 return hr;
567 hr = opc_part_uri_init(obj, NULL, FALSE, uri);
568 IUri_Release(uri);
569 if (FAILED(hr))
571 WARN("Failed to init uri, hr %#x.\n", hr);
572 heap_free(uri);
573 return hr;
576 *out = (IOpcUri *)&obj->IOpcPartUri_iface;
577 TRACE("Created part uri %p.\n", *out);
578 return S_OK;