wined3d: Simplify wined3d_cs_emit_clear() slightly.
[wine.git] / dlls / opcservices / factory.c
blobee155b3e714ef04103feb28f0ae1afca14d59ca2
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 "initguid.h"
26 #include "ole2.h"
27 #include "rpcproxy.h"
28 #include "msopc.h"
29 #include "xmllite.h"
31 #include "wine/debug.h"
33 #include "opc_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(msopc);
37 struct opc_filestream
39 IStream IStream_iface;
40 LONG refcount;
42 HANDLE hfile;
45 static inline struct opc_filestream *impl_from_IStream(IStream *iface)
47 return CONTAINING_RECORD(iface, struct opc_filestream, IStream_iface);
50 static HRESULT WINAPI opc_filestream_QueryInterface(IStream *iface, REFIID iid, void **out)
52 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
54 if (IsEqualIID(iid, &IID_IStream) ||
55 IsEqualIID(iid, &IID_ISequentialStream) ||
56 IsEqualIID(iid, &IID_IUnknown))
58 *out = iface;
59 IStream_AddRef(iface);
60 return S_OK;
63 *out = NULL;
64 WARN("Unsupported interface %s.\n", debugstr_guid(iid));
65 return E_NOINTERFACE;
68 static ULONG WINAPI opc_filestream_AddRef(IStream *iface)
70 struct opc_filestream *stream = impl_from_IStream(iface);
71 ULONG refcount = InterlockedIncrement(&stream->refcount);
73 TRACE("%p increasing refcount to %u.\n", iface, refcount);
75 return refcount;
78 static ULONG WINAPI opc_filestream_Release(IStream *iface)
80 struct opc_filestream *stream = impl_from_IStream(iface);
81 ULONG refcount = InterlockedDecrement(&stream->refcount);
83 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
85 if (!refcount)
87 CloseHandle(stream->hfile);
88 heap_free(stream);
91 return refcount;
94 static HRESULT WINAPI opc_filestream_Read(IStream *iface, void *buff, ULONG size, ULONG *num_read)
96 struct opc_filestream *stream = impl_from_IStream(iface);
97 DWORD read = 0;
99 TRACE("iface %p, buff %p, size %u, num_read %p.\n", iface, buff, size, num_read);
101 if (!num_read)
102 num_read = &read;
104 *num_read = 0;
105 if (!ReadFile(stream->hfile, buff, size, num_read, NULL))
107 WARN("Failed to read file, error %d.\n", GetLastError());
108 return HRESULT_FROM_WIN32(GetLastError());
111 return *num_read == size ? S_OK : S_FALSE;
114 static HRESULT WINAPI opc_filestream_Write(IStream *iface, const void *data, ULONG size, ULONG *num_written)
116 struct opc_filestream *stream = impl_from_IStream(iface);
117 DWORD written = 0;
119 TRACE("iface %p, data %p, size %u, num_written %p.\n", iface, data, size, num_written);
121 if (!num_written)
122 num_written = &written;
124 *num_written = 0;
125 if (!WriteFile(stream->hfile, data, size, num_written, NULL))
127 WARN("Failed to write to file, error %d.\n", GetLastError());
128 return HRESULT_FROM_WIN32(GetLastError());
131 return S_OK;
134 static HRESULT WINAPI opc_filestream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *newpos)
136 struct opc_filestream *stream = impl_from_IStream(iface);
138 TRACE("iface %p, move %s, origin %d, newpos %p.\n", iface, wine_dbgstr_longlong(move.QuadPart), origin, newpos);
140 if (!SetFilePointerEx(stream->hfile, move, (LARGE_INTEGER *)newpos, origin))
141 return HRESULT_FROM_WIN32(GetLastError());
143 return S_OK;
146 static HRESULT WINAPI opc_filestream_SetSize(IStream *iface, ULARGE_INTEGER size)
148 FIXME("iface %p, size %s stub!\n", iface, wine_dbgstr_longlong(size.QuadPart));
150 return E_NOTIMPL;
153 static HRESULT WINAPI opc_filestream_CopyTo(IStream *iface, IStream *dest, ULARGE_INTEGER size,
154 ULARGE_INTEGER *num_read, ULARGE_INTEGER *written)
156 FIXME("iface %p, dest %p, size %s, num_read %p, written %p stub!\n", iface, dest,
157 wine_dbgstr_longlong(size.QuadPart), num_read, written);
159 return E_NOTIMPL;
162 static HRESULT WINAPI opc_filestream_Commit(IStream *iface, DWORD flags)
164 FIXME("iface %p, flags %#x stub!\n", iface, flags);
166 return E_NOTIMPL;
169 static HRESULT WINAPI opc_filestream_Revert(IStream *iface)
171 FIXME("iface %p stub!\n", iface);
173 return E_NOTIMPL;
176 static HRESULT WINAPI opc_filestream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
177 ULARGE_INTEGER size, DWORD lock_type)
179 FIXME("iface %p, offset %s, size %s, lock_type %d stub!\n", iface, wine_dbgstr_longlong(offset.QuadPart),
180 wine_dbgstr_longlong(size.QuadPart), lock_type);
182 return E_NOTIMPL;
185 static HRESULT WINAPI opc_filestream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size,
186 DWORD lock_type)
188 FIXME("iface %p, offset %s, size %s, lock_type %d stub!\n", iface, wine_dbgstr_longlong(offset.QuadPart),
189 wine_dbgstr_longlong(size.QuadPart), lock_type);
191 return E_NOTIMPL;
194 static HRESULT WINAPI opc_filestream_Stat(IStream *iface, STATSTG *statstg, DWORD flag)
196 struct opc_filestream *stream = impl_from_IStream(iface);
197 BY_HANDLE_FILE_INFORMATION fi;
199 TRACE("iface %p, statstg %p, flag %d.\n", iface, statstg, flag);
201 if (!statstg)
202 return E_POINTER;
204 memset(&fi, 0, sizeof(fi));
205 GetFileInformationByHandle(stream->hfile, &fi);
207 memset(statstg, 0, sizeof(*statstg));
208 statstg->type = STGTY_STREAM;
209 statstg->cbSize.u.LowPart = fi.nFileSizeLow;
210 statstg->cbSize.u.HighPart = fi.nFileSizeHigh;
211 statstg->mtime = fi.ftLastWriteTime;
212 statstg->ctime = fi.ftCreationTime;
213 statstg->atime = fi.ftLastAccessTime;
215 return S_OK;
218 static HRESULT WINAPI opc_filestream_Clone(IStream *iface, IStream **result)
220 FIXME("iface %p, result %p stub!\n", iface, result);
222 return E_NOTIMPL;
225 static const IStreamVtbl opc_filestream_vtbl =
227 opc_filestream_QueryInterface,
228 opc_filestream_AddRef,
229 opc_filestream_Release,
230 opc_filestream_Read,
231 opc_filestream_Write,
232 opc_filestream_Seek,
233 opc_filestream_SetSize,
234 opc_filestream_CopyTo,
235 opc_filestream_Commit,
236 opc_filestream_Revert,
237 opc_filestream_LockRegion,
238 opc_filestream_UnlockRegion,
239 opc_filestream_Stat,
240 opc_filestream_Clone,
243 static HRESULT opc_filestream_create(const WCHAR *filename, OPC_STREAM_IO_MODE io_mode, SECURITY_ATTRIBUTES *sa,
244 DWORD flags, IStream **out)
246 struct opc_filestream *stream;
247 DWORD access, creation;
249 if (!filename || !out)
250 return E_POINTER;
252 switch (io_mode)
254 case OPC_STREAM_IO_READ:
255 access = GENERIC_READ;
256 creation = OPEN_EXISTING;
257 break;
258 case OPC_STREAM_IO_WRITE:
259 access = GENERIC_WRITE;
260 creation = CREATE_ALWAYS;
261 break;
262 default:
263 return E_INVALIDARG;
266 if (!(stream = heap_alloc_zero(sizeof(*stream))))
267 return E_OUTOFMEMORY;
269 stream->hfile = CreateFileW(filename, access, 0, sa, creation, flags, NULL);
270 if (stream->hfile == INVALID_HANDLE_VALUE)
272 HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
273 heap_free(stream);
274 return hr;
277 stream->IStream_iface.lpVtbl = &opc_filestream_vtbl;
278 stream->refcount = 1;
280 *out = &stream->IStream_iface;
281 TRACE("Created file stream %p.\n", *out);
282 return S_OK;
285 static HRESULT WINAPI opc_factory_QueryInterface(IOpcFactory *iface, REFIID iid, void **out)
287 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
289 if (IsEqualIID(iid, &IID_IOpcFactory) ||
290 IsEqualIID(iid, &IID_IUnknown))
292 *out = iface;
293 IOpcFactory_AddRef(iface);
294 return S_OK;
297 WARN("Unsupported interface %s.\n", debugstr_guid(iid));
298 return E_NOINTERFACE;
301 static ULONG WINAPI opc_factory_AddRef(IOpcFactory *iface)
303 return 2;
306 static ULONG WINAPI opc_factory_Release(IOpcFactory *iface)
308 return 1;
311 static HRESULT WINAPI opc_factory_CreatePackageRootUri(IOpcFactory *iface, IOpcUri **uri)
313 TRACE("iface %p, uri %p.\n", iface, uri);
315 if (!uri)
316 return E_POINTER;
318 return opc_root_uri_create(uri);
321 static HRESULT WINAPI opc_factory_CreatePartUri(IOpcFactory *iface, LPCWSTR uri, IOpcPartUri **out)
323 static const WCHAR rootW[] = {'/',0};
324 IUri *part_uri, *root_uri, *combined;
325 HRESULT hr;
327 TRACE("iface %p, uri %s, out %p.\n", iface, debugstr_w(uri), out);
329 if (!out)
330 return E_POINTER;
332 *out = NULL;
334 if (FAILED(hr = CreateUri(uri, Uri_CREATE_ALLOW_RELATIVE, 0, &part_uri)))
336 WARN("Failed to create uri, hr %#x.\n", hr);
337 return hr;
340 if (FAILED(hr = CreateUri(rootW, Uri_CREATE_ALLOW_RELATIVE, 0, &root_uri)))
342 WARN("Failed to create root uri, hr %#x.\n", hr);
343 IUri_Release(part_uri);
344 return hr;
347 hr = CoInternetCombineIUri(root_uri, part_uri, 0, &combined, 0);
348 IUri_Release(root_uri);
349 IUri_Release(part_uri);
350 if (FAILED(hr))
352 WARN("Failed to combine URIs, hr %#x.\n", hr);
353 return hr;
356 hr = opc_part_uri_create(combined, NULL, out);
357 IUri_Release(combined);
358 return hr;
361 static HRESULT WINAPI opc_factory_CreateStreamOnFile(IOpcFactory *iface, LPCWSTR filename,
362 OPC_STREAM_IO_MODE io_mode, SECURITY_ATTRIBUTES *sa, DWORD flags, IStream **stream)
364 TRACE("iface %p, filename %s, io_mode %d, sa %p, flags %#x, stream %p.\n", iface, debugstr_w(filename),
365 io_mode, sa, flags, stream);
367 return opc_filestream_create(filename, io_mode, sa, flags, stream);
370 static HRESULT WINAPI opc_factory_CreatePackage(IOpcFactory *iface, IOpcPackage **package)
372 TRACE("iface %p, package %p.\n", iface, package);
374 return opc_package_create(iface, package);
377 static HRESULT WINAPI opc_factory_ReadPackageFromStream(IOpcFactory *iface, IStream *stream,
378 OPC_READ_FLAGS flags, IOpcPackage **package)
380 FIXME("iface %p, stream %p, flags %#x, package %p stub!\n", iface, stream, flags, package);
382 return E_NOTIMPL;
385 static HRESULT WINAPI opc_factory_WritePackageToStream(IOpcFactory *iface, IOpcPackage *package, OPC_WRITE_FLAGS flags,
386 IStream *stream)
388 TRACE("iface %p, package %p, flags %#x, stream %p.\n", iface, package, flags, stream);
390 if (!package || !stream)
391 return E_POINTER;
393 return opc_package_write(package, flags, stream);
396 static HRESULT WINAPI opc_factory_CreateDigitalSignatureManager(IOpcFactory *iface, IOpcPackage *package,
397 IOpcDigitalSignatureManager **signature_manager)
399 FIXME("iface %p, package %p, signature_manager %p stub!\n", iface, package, signature_manager);
401 return E_NOTIMPL;
404 static const IOpcFactoryVtbl opc_factory_vtbl =
406 opc_factory_QueryInterface,
407 opc_factory_AddRef,
408 opc_factory_Release,
409 opc_factory_CreatePackageRootUri,
410 opc_factory_CreatePartUri,
411 opc_factory_CreateStreamOnFile,
412 opc_factory_CreatePackage,
413 opc_factory_ReadPackageFromStream,
414 opc_factory_WritePackageToStream,
415 opc_factory_CreateDigitalSignatureManager,
418 static IOpcFactory opc_factory = { &opc_factory_vtbl };
420 static HRESULT WINAPI opc_class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
422 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
424 if (IsEqualGUID(iid, &IID_IClassFactory) ||
425 IsEqualGUID(iid, &IID_IUnknown))
427 IClassFactory_AddRef(iface);
428 *out = iface;
429 return S_OK;
432 *out = NULL;
433 WARN("Unsupported interface %s.\n", debugstr_guid(iid));
434 return E_NOINTERFACE;
437 static ULONG WINAPI opc_class_factory_AddRef(IClassFactory *iface)
439 return 2;
442 static ULONG WINAPI opc_class_factory_Release(IClassFactory *iface)
444 return 1;
447 static HRESULT WINAPI opc_class_factory_CreateInstance(IClassFactory *iface,
448 IUnknown *outer, REFIID iid, void **out)
450 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
452 if (outer)
453 return CLASS_E_NOAGGREGATION;
455 return IOpcFactory_QueryInterface(&opc_factory, iid, out);
458 static HRESULT WINAPI opc_class_factory_LockServer(IClassFactory *iface, BOOL dolock)
460 FIXME("iface %p, dolock %d stub!\n", iface, dolock);
461 return S_OK;
464 static const struct IClassFactoryVtbl opc_class_factory_vtbl =
466 opc_class_factory_QueryInterface,
467 opc_class_factory_AddRef,
468 opc_class_factory_Release,
469 opc_class_factory_CreateInstance,
470 opc_class_factory_LockServer
473 static IClassFactory opc_class_factory = { &opc_class_factory_vtbl };
475 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
477 TRACE("clsid %s, iid %s, out %p\n", debugstr_guid(clsid), debugstr_guid(iid), out);
479 if (IsEqualCLSID(clsid, &CLSID_OpcFactory))
480 return IClassFactory_QueryInterface(&opc_class_factory, iid, out);
482 WARN("Unsupported class %s.\n", debugstr_guid(clsid));
483 return E_NOTIMPL;
486 HRESULT WINAPI DllCanUnloadNow(void)
488 return S_FALSE;
491 static HINSTANCE OPC_hInstance;
493 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, void *reserved)
495 OPC_hInstance = hInstDLL;
497 switch (reason)
499 case DLL_PROCESS_ATTACH:
500 DisableThreadLibraryCalls(hInstDLL);
501 break;
503 return TRUE;
506 HRESULT WINAPI DllRegisterServer(void)
508 return __wine_register_resources( OPC_hInstance );
511 HRESULT WINAPI DllUnregisterServer(void)
513 return __wine_unregister_resources( OPC_hInstance );