setupapi: Improve parameter validation for SetupCreateDiskSpaceListA/W.
[wine] / dlls / d3d8 / buffer.c
1 /*
2  * Copyright 2005 Oliver Stieber
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 "config.h"
20 #include "d3d8_private.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
23
24 static HRESULT WINAPI d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8 *iface, REFIID riid, void **object)
25 {
26     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
27
28     if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)
29             || IsEqualGUID(riid, &IID_IDirect3DResource8)
30             || IsEqualGUID(riid, &IID_IUnknown))
31     {
32         IUnknown_AddRef(iface);
33         *object = iface;
34         return S_OK;
35     }
36
37     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
38
39     *object = NULL;
40     return E_NOINTERFACE;
41 }
42
43 static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface)
44 {
45     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
46     ULONG refcount = InterlockedIncrement(&buffer->ref);
47
48     TRACE("%p increasing refcount to %u.\n", iface, refcount);
49
50     if (refcount == 1)
51     {
52         IDirect3DDevice8_AddRef(buffer->parentDevice);
53         wined3d_mutex_lock();
54         IWineD3DBuffer_AddRef(buffer->wineD3DVertexBuffer);
55         wined3d_mutex_unlock();
56     }
57
58     return refcount;
59 }
60
61 static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
62 {
63     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
64     ULONG refcount = InterlockedDecrement(&buffer->ref);
65
66     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
67
68     if (!refcount)
69     {
70         IDirect3DDevice8 *device = buffer->parentDevice;
71
72         wined3d_mutex_lock();
73         IWineD3DBuffer_Release(buffer->wineD3DVertexBuffer);
74         wined3d_mutex_unlock();
75
76         /* Release the device last, as it may cause the device to be destroyed. */
77         IDirect3DDevice8_Release(device);
78     }
79
80     return refcount;
81 }
82
83 static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface, IDirect3DDevice8 **device)
84 {
85     TRACE("iface %p, device %p.\n", iface, device);
86
87     *device = (IDirect3DDevice8 *)((IDirect3DVertexBuffer8Impl *)iface)->parentDevice;
88     IDirect3DDevice8_AddRef(*device);
89
90     TRACE("Returning device %p.\n", *device);
91
92     return D3D_OK;
93 }
94
95 static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
96         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
97 {
98     HRESULT hr;
99
100     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
101             iface, debugstr_guid(guid), data, data_size, flags);
102
103     wined3d_mutex_lock();
104     hr = IWineD3DBuffer_SetPrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
105             guid, data, data_size, flags);
106     wined3d_mutex_unlock();
107
108     return hr;
109 }
110
111 static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
112         REFGUID guid, void *data, DWORD *data_size)
113 {
114     HRESULT hr;
115
116     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
117             iface, debugstr_guid(guid), data, data_size);
118
119     wined3d_mutex_lock();
120     hr = IWineD3DBuffer_GetPrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
121             guid, data, data_size);
122     wined3d_mutex_unlock();
123
124     return hr;
125 }
126
127 static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
128 {
129     HRESULT hr;
130
131     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
132
133     wined3d_mutex_lock();
134     hr = IWineD3DBuffer_FreePrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer, guid);
135     wined3d_mutex_unlock();
136
137     return hr;
138 }
139
140 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
141 {
142     DWORD previous;
143
144     TRACE("iface %p, priority %u.\n", iface, priority);
145
146     wined3d_mutex_lock();
147     previous = IWineD3DBuffer_SetPriority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer, priority);
148     wined3d_mutex_unlock();
149
150     return previous;
151 }
152
153 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
154 {
155     DWORD priority;
156
157     TRACE("iface %p.\n", iface);
158
159     wined3d_mutex_lock();
160     priority = IWineD3DBuffer_GetPriority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
161     wined3d_mutex_unlock();
162
163     return priority;
164 }
165
166 static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
167 {
168     TRACE("iface %p.\n", iface);
169
170     wined3d_mutex_lock();
171     IWineD3DBuffer_PreLoad(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
172     wined3d_mutex_unlock();
173 }
174
175 static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
176 {
177     TRACE("iface %p.\n", iface);
178
179     return D3DRTYPE_VERTEXBUFFER;
180 }
181
182 static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface,
183         UINT offset, UINT size, BYTE **data, DWORD flags)
184 {
185     HRESULT hr;
186
187     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
188             iface, offset, size, data, flags);
189
190     wined3d_mutex_lock();
191     hr = IWineD3DBuffer_Map(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
192             offset, size, data, flags);
193     wined3d_mutex_unlock();
194
195     return hr;
196 }
197
198 static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
199 {
200     HRESULT hr;
201
202     TRACE("iface %p.\n", iface);
203
204     wined3d_mutex_lock();
205     hr = IWineD3DBuffer_Unmap(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
206     wined3d_mutex_unlock();
207
208     return hr;
209 }
210
211 static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface, D3DVERTEXBUFFER_DESC *desc)
212 {
213     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
214     WINED3DBUFFER_DESC wined3d_desc;
215     HRESULT hr;
216
217     TRACE("iface %p, desc %p.\n", iface, desc);
218
219     wined3d_mutex_lock();
220     hr = IWineD3DBuffer_GetDesc(buffer->wineD3DVertexBuffer, &wined3d_desc);
221     wined3d_mutex_unlock();
222
223     if (SUCCEEDED(hr))
224     {
225         desc->Type = D3DRTYPE_VERTEXBUFFER;
226         desc->Usage = wined3d_desc.Usage;
227         desc->Pool = wined3d_desc.Pool;
228         desc->Size = wined3d_desc.Size;
229         desc->FVF = buffer->fvf;
230         desc->Format = D3DFMT_VERTEXDATA;
231     }
232
233     return hr;
234 }
235
236 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
237 {
238     /* IUnknown */
239     d3d8_vertexbuffer_QueryInterface,
240     d3d8_vertexbuffer_AddRef,
241     d3d8_vertexbuffer_Release,
242     /* IDirect3DResource8 */
243     d3d8_vertexbuffer_GetDevice,
244     d3d8_vertexbuffer_SetPrivateData,
245     d3d8_vertexbuffer_GetPrivateData,
246     d3d8_vertexbuffer_FreePrivateData,
247     d3d8_vertexbuffer_SetPriority,
248     d3d8_vertexbuffer_GetPriority,
249     d3d8_vertexbuffer_PreLoad,
250     d3d8_vertexbuffer_GetType,
251     /* IDirect3DVertexBuffer8 */
252     d3d8_vertexbuffer_Lock,
253     d3d8_vertexbuffer_Unlock,
254     d3d8_vertexbuffer_GetDesc,
255 };
256
257 static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
258 {
259     HeapFree(GetProcessHeap(), 0, parent);
260 }
261
262 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
263 {
264     d3d8_vertexbuffer_wined3d_object_destroyed,
265 };
266
267 HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
268         UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
269 {
270     HRESULT hr;
271
272     buffer->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
273     buffer->ref = 1;
274     buffer->fvf = fvf;
275
276     wined3d_mutex_lock();
277     hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
278             (WINED3DPOOL)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
279     wined3d_mutex_unlock();
280     if (FAILED(hr))
281     {
282         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
283         return hr;
284     }
285
286     buffer->parentDevice = (IDirect3DDevice8 *)device;
287     IUnknown_AddRef(buffer->parentDevice);
288
289     return D3D_OK;
290 }
291
292 static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
293 {
294     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
295
296     if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
297             || IsEqualGUID(riid, &IID_IDirect3DResource8)
298             || IsEqualGUID(riid, &IID_IUnknown))
299     {
300         IUnknown_AddRef(iface);
301         *object = iface;
302         return S_OK;
303     }
304
305     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
306
307     *object = NULL;
308     return E_NOINTERFACE;
309 }
310
311 static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
312 {
313     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
314     ULONG refcount = InterlockedIncrement(&buffer->ref);
315
316     TRACE("%p increasing refcount to %u.\n", iface, refcount);
317
318     if (refcount == 1)
319     {
320         IDirect3DDevice8_AddRef(buffer->parentDevice);
321         wined3d_mutex_lock();
322         IWineD3DBuffer_AddRef(buffer->wineD3DIndexBuffer);
323         wined3d_mutex_unlock();
324     }
325
326     return refcount;
327 }
328
329 static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
330 {
331     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
332     ULONG refcount = InterlockedDecrement(&buffer->ref);
333
334     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
335
336     if (!refcount)
337     {
338         IDirect3DDevice8 *device = buffer->parentDevice;
339
340         wined3d_mutex_lock();
341         IWineD3DBuffer_Release(buffer->wineD3DIndexBuffer);
342         wined3d_mutex_unlock();
343
344         /* Release the device last, as it may cause the device to be destroyed. */
345         IDirect3DDevice8_Release(device);
346     }
347
348     return refcount;
349 }
350
351 static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface, IDirect3DDevice8 **device)
352 {
353     TRACE("iface %p, device %p.\n", iface, device);
354
355     *device = (IDirect3DDevice8 *)((IDirect3DIndexBuffer8Impl *)iface)->parentDevice;
356     IDirect3DDevice8_AddRef(*device);
357
358     TRACE("Returning device %p.\n", *device);
359
360     return D3D_OK;
361 }
362
363 static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
364         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
365 {
366     HRESULT hr;
367
368     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
369             iface, debugstr_guid(guid), data, data_size, flags);
370
371     wined3d_mutex_lock();
372     hr = IWineD3DBuffer_SetPrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
373             guid, data, data_size, flags);
374     wined3d_mutex_unlock();
375
376     return hr;
377 }
378
379 static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
380         REFGUID guid, void *data, DWORD *data_size)
381 {
382     HRESULT hr;
383
384     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
385             iface, debugstr_guid(guid), data, data_size);
386
387     wined3d_mutex_lock();
388     hr = IWineD3DBuffer_GetPrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
389             guid, data, data_size);
390     wined3d_mutex_unlock();
391
392     return hr;
393 }
394
395 static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
396 {
397     HRESULT hr;
398
399     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
400
401     wined3d_mutex_lock();
402     hr = IWineD3DBuffer_FreePrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer, guid);
403     wined3d_mutex_unlock();
404
405     return hr;
406 }
407
408 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
409 {
410     DWORD previous;
411
412     TRACE("iface %p, priority %u.\n", iface, priority);
413
414     wined3d_mutex_lock();
415     previous = IWineD3DBuffer_SetPriority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer, priority);
416     wined3d_mutex_unlock();
417
418     return previous;
419 }
420
421 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
422 {
423     DWORD priority;
424
425     TRACE("iface %p.\n", iface);
426
427     wined3d_mutex_lock();
428     priority = IWineD3DBuffer_GetPriority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
429     wined3d_mutex_unlock();
430
431     return priority;
432 }
433
434 static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
435 {
436     TRACE("iface %p.\n", iface);
437
438     wined3d_mutex_lock();
439     IWineD3DBuffer_PreLoad(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
440     wined3d_mutex_unlock();
441 }
442
443 static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
444 {
445     TRACE("iface %p.\n", iface);
446
447     return D3DRTYPE_INDEXBUFFER;
448 }
449
450 static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface,
451         UINT offset, UINT size, BYTE **data, DWORD flags)
452 {
453     HRESULT hr;
454
455     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
456             iface, offset, size, data, flags);
457
458     wined3d_mutex_lock();
459     hr = IWineD3DBuffer_Map(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
460             offset, size, data, flags);
461     wined3d_mutex_unlock();
462
463     return hr;
464 }
465
466 static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
467 {
468     HRESULT hr;
469
470     TRACE("iface %p.\n", iface);
471
472     wined3d_mutex_lock();
473     hr = IWineD3DBuffer_Unmap(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
474     wined3d_mutex_unlock();
475
476     return hr;
477 }
478
479 static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface, D3DINDEXBUFFER_DESC *desc)
480 {
481     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
482     HRESULT hr;
483     WINED3DBUFFER_DESC wined3d_desc;
484
485     TRACE("iface %p, desc %p.\n", iface, desc);
486
487     wined3d_mutex_lock();
488     hr = IWineD3DBuffer_GetDesc(buffer->wineD3DIndexBuffer, &wined3d_desc);
489     wined3d_mutex_unlock();
490
491     if (SUCCEEDED(hr))
492     {
493         desc->Format = d3dformat_from_wined3dformat(buffer->format);
494         desc->Type = D3DRTYPE_INDEXBUFFER;
495         desc->Usage = wined3d_desc.Usage;
496         desc->Pool = wined3d_desc.Pool;
497         desc->Size = wined3d_desc.Size;
498     }
499
500     return hr;
501 }
502
503 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
504 {
505     /* IUnknown */
506     d3d8_indexbuffer_QueryInterface,
507     d3d8_indexbuffer_AddRef,
508     d3d8_indexbuffer_Release,
509     /* IDirect3DResource8 */
510     d3d8_indexbuffer_GetDevice,
511     d3d8_indexbuffer_SetPrivateData,
512     d3d8_indexbuffer_GetPrivateData,
513     d3d8_indexbuffer_FreePrivateData,
514     d3d8_indexbuffer_SetPriority,
515     d3d8_indexbuffer_GetPriority,
516     d3d8_indexbuffer_PreLoad,
517     d3d8_indexbuffer_GetType,
518     /* IDirect3DIndexBuffer8 */
519     d3d8_indexbuffer_Lock,
520     d3d8_indexbuffer_Unlock,
521     d3d8_indexbuffer_GetDesc,
522 };
523
524 static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
525 {
526     HeapFree(GetProcessHeap(), 0, parent);
527 }
528
529 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
530 {
531     d3d8_indexbuffer_wined3d_object_destroyed,
532 };
533
534 HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
535         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
536 {
537     HRESULT hr;
538
539     buffer->lpVtbl = &d3d8_indexbuffer_vtbl;
540     buffer->ref = 1;
541     buffer->format = wined3dformat_from_d3dformat(format);
542
543     wined3d_mutex_lock();
544     hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
545             (WINED3DPOOL)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wineD3DIndexBuffer);
546     wined3d_mutex_unlock();
547     if (FAILED(hr))
548     {
549         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
550         return hr;
551     }
552
553     buffer->parentDevice = (IDirect3DDevice8 *)device;
554     IUnknown_AddRef(buffer->parentDevice);
555
556     return D3D_OK;
557 }