ReactOS 0.4.17-dev-934-g091855f
loader.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2003-2004 Rok Mandeljc
3 *
4 * This program 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 program 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 program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include "dmloader_private.h"
20
22
24{
25 L"/usr/share/sounds/sf2/default-GM.sf2",
26 L"/usr/share/soundfonts/default.sf2",
27};
28
30{
31 UINT i;
32
33 for (i = 0; i < ARRAY_SIZE(system_default_gm_paths); i++)
34 {
35 swprintf(path, max_len, L"\\??\\unix%s", system_default_gm_paths[i]);
37 }
38
40 {
41 WARN("Using system %s for the default collection\n", debugstr_w(path));
42 return S_OK;
43 }
44
45 ERR("Unable to find system path, default collection will not be available\n");
47}
48
49static const GUID *classes[] = {
50 &GUID_DirectMusicAllTypes, /* Keep as first */
51 &CLSID_DirectMusicAudioPathConfig,
52 &CLSID_DirectMusicBand,
53 &CLSID_DirectMusicContainer,
54 &CLSID_DirectMusicCollection,
55 &CLSID_DirectMusicChordMap,
56 &CLSID_DirectMusicSegment,
57 &CLSID_DirectMusicScript,
58 &CLSID_DirectMusicSong,
59 &CLSID_DirectMusicStyle,
60 &CLSID_DirectMusicGraph,
61 &CLSID_DirectSoundWave
62};
63
64/* cache/alias entry */
65struct cache_entry {
66 struct list entry;
68 IDirectMusicObject *pObject;
69};
70
71struct loader
72{
73 IDirectMusicLoader8 IDirectMusicLoader8_iface;
76 unsigned int cache_class;
77 struct list cache;
78};
79
80static inline struct loader *impl_from_IDirectMusicLoader8(IDirectMusicLoader8 *iface)
81{
83}
84
85static int index_from_class(REFCLSID class)
86{
87 int i;
88
89 for (i = 0; i < ARRAY_SIZE(classes); i++)
90 if (IsEqualGUID(class, classes[i]))
91 return i;
92
93 return -1;
94}
95
96static inline BOOL is_cache_enabled(struct loader *This, REFCLSID class)
97{
98 return !!(This->cache_class & 1 << index_from_class(class));
99}
100
101static void get_search_path(struct loader *This, REFGUID class, WCHAR *path)
102{
103 int index = index_from_class(class);
104
105 if (index < 0 || !This->search_paths[index])
106 index = 0; /* Default to GUID_DirectMusicAllTypes */
107
108 if (This->search_paths[index])
109 lstrcpynW(path, This->search_paths[index], MAX_PATH);
110 else
111 path[0] = 0;
112}
113
115{
116 if (TRACE_ON(dmloader))
118
119 /* copy field by field */
120 if (pSrc->dwValidData & DMUS_OBJ_CLASS) pDst->guidClass = pSrc->guidClass;
121 if (pSrc->dwValidData & DMUS_OBJ_OBJECT) pDst->guidObject = pSrc->guidObject;
122 if (pSrc->dwValidData & DMUS_OBJ_DATE) pDst->ftDate = pSrc->ftDate;
123 if (pSrc->dwValidData & DMUS_OBJ_VERSION) pDst->vVersion = pSrc->vVersion;
124 if (pSrc->dwValidData & DMUS_OBJ_NAME) lstrcpyW (pDst->wszName, pSrc->wszName);
127 if (pSrc->dwValidData & DMUS_OBJ_STREAM) IStream_Clone (pSrc->pStream, &pDst->pStream);
128 if (pSrc->dwValidData & DMUS_OBJ_MEMORY) {
129 pDst->pbMemData = pSrc->pbMemData;
130 pDst->llMemLength = pSrc->llMemLength;
131 }
132 /* set flags */
133 pDst->dwValidData |= pSrc->dwValidData;
134 return S_OK;
135}
136
137static HRESULT WINAPI loader_QueryInterface(IDirectMusicLoader8 *iface, REFIID riid, void **ppobj)
138{
140
141 TRACE("(%p, %s, %p)\n",This, debugstr_dmguid(riid), ppobj);
142 if (IsEqualIID (riid, &IID_IUnknown) ||
143 IsEqualIID (riid, &IID_IDirectMusicLoader) ||
144 IsEqualIID (riid, &IID_IDirectMusicLoader8)) {
146 *ppobj = This;
147 return S_OK;
148 }
149
150 WARN(": not found\n");
151 return E_NOINTERFACE;
152}
153
154static ULONG WINAPI loader_AddRef(IDirectMusicLoader8 *iface)
155{
158
159 TRACE("(%p)->(): new ref = %lu\n", iface, ref);
160
161 return ref;
162}
163
164static ULONG WINAPI loader_Release(IDirectMusicLoader8 *iface)
165{
168
169 TRACE("(%p)->(): new ref = %lu\n", iface, ref);
170
171 if (!ref) {
172 unsigned int i;
173
174 IDirectMusicLoader8_ClearCache(iface, &GUID_DirectMusicAllTypes);
175 for (i = 0; i < ARRAY_SIZE(classes); i++)
176 free(This->search_paths[i]);
177 free(This);
178 }
179
180 return ref;
181}
182
184{
185 struct cache_entry *existing;
186
187 /*
188 * The Object is looked up in the following order.
189 * 1. DMUS_OBJ_OBJECT
190 * 2. DMUS_OBJ_STREAM
191 * 3. DMUS_OBJ_MEMORY
192 * 4. DMUS_OBJ_FILENAME and DMUS_OBJ_FULLPATH
193 * 5. DMUS_OBJ_NAME and DMUS_OBJ_CATEGORY
194 * 6. DMUS_OBJ_NAME
195 * 7. DMUS_OBJ_FILENAME
196 */
197
198 if (desc->dwValidData & DMUS_OBJ_OBJECT) {
199 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
200 if (existing->Desc.dwValidData & DMUS_OBJ_OBJECT &&
201 IsEqualGUID(&desc->guidObject, &existing->Desc.guidObject) ) {
202 TRACE("Found by DMUS_OBJ_OBJECT\n");
203 return existing;
204 }
205 }
206 }
207
208 if (desc->dwValidData & DMUS_OBJ_STREAM)
209 FIXME("Finding DMUS_OBJ_STREAM cached objects currently not supported.\n");
210
211 if (desc->dwValidData & DMUS_OBJ_MEMORY) {
212 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
213 if (existing->Desc.dwValidData & DMUS_OBJ_MEMORY &&
214 desc->llMemLength == existing->Desc.llMemLength &&
215 (desc->pbMemData == existing->Desc.pbMemData ||
216 !memcmp(desc->pbMemData, existing->Desc.pbMemData, desc->llMemLength)) ) {
217 TRACE("Found by DMUS_OBJ_MEMORY (%d)\n",
218 desc->pbMemData == existing->Desc.pbMemData);
219 return existing;
220 }
221 }
222 }
223
224 if ((desc->dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) ==
226 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
227 if ((existing->Desc.dwValidData & (DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH)) ==
229 !wcsncmp(desc->wszFileName, existing->Desc.wszFileName, DMUS_MAX_FILENAME)) {
230 TRACE("Found by DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH\n");
231 return existing;
232 }
233 }
234 }
235
236 if ((desc->dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) ==
238 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
239 if ((existing->Desc.dwValidData & (DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY)) ==
241 !wcsncmp(desc->wszName, existing->Desc.wszName, DMUS_MAX_NAME) &&
242 !wcsncmp(desc->wszCategory, existing->Desc.wszCategory, DMUS_MAX_CATEGORY)) {
243 TRACE("Found by DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY\n");
244 return existing;
245 }
246 }
247 }
248
249 if ((desc->dwValidData & DMUS_OBJ_NAME) == DMUS_OBJ_NAME) {
250 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
251 if ((existing->Desc.dwValidData & DMUS_OBJ_NAME) == DMUS_OBJ_NAME &&
252 !wcsncmp(desc->wszName, existing->Desc.wszName, DMUS_MAX_NAME)) {
253 TRACE("Found by DMUS_OBJ_NAME\n");
254 return existing;
255 }
256 }
257 }
258
259 if ((desc->dwValidData & DMUS_OBJ_FILENAME) == DMUS_OBJ_FILENAME) {
260 LIST_FOR_EACH_ENTRY(existing, &This->cache, struct cache_entry, entry) {
261 if (((existing->Desc.dwValidData & DMUS_OBJ_FILENAME) == DMUS_OBJ_FILENAME) &&
262 !wcsncmp(desc->wszFileName, existing->Desc.wszFileName, DMUS_MAX_FILENAME)) {
263 TRACE("Found by DMUS_OBJ_FILENAME\n");
264 return existing;
265 }
266 }
267 }
268
269 return NULL;
270}
271
272static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDESC *pDesc, REFIID riid, void **ppv)
273{
274 static const DWORD source_flags = DMUS_OBJ_STREAM | DMUS_OBJ_FILENAME | DMUS_OBJ_URL;
277 HRESULT ret = S_OK; /* used at the end of function, to determine whether everything went OK */
278 struct cache_entry *pExistingEntry, *pObjectEntry = NULL;
279 LPSTREAM pStream;
280 IPersistStream* pPersistStream = NULL;
281
283 DMUS_OBJECTDESC GotDesc;
284 BOOL bCache;
286 HRESULT hr;
287
288 TRACE("(%p)->(%p, %s, %p)\n", This, pDesc, debugstr_dmguid(riid), ppv);
289
290 if (TRACE_ON(dmloader))
292
293 /* sometimes it happens that guidClass is missing... which is a BadThingTM */
294 if (!(pDesc->dwValidData & DMUS_OBJ_CLASS)) {
295 ERR(": guidClass not valid but needed\n");
296 *ppv = NULL;
298 }
299
300 /* Iterate through the list of objects we know about; these are either loaded
301 * (GetObject, LoadObjectFromFile) or set via SetObject; */
302 TRACE(": looking if we have object in the cache or if it can be found via alias\n");
303 pExistingEntry = find_cache_object(This, pDesc);
304 if (pExistingEntry) {
305 if (pExistingEntry->Desc.dwValidData & DMUS_OBJ_LOADED) {
306 TRACE(": already loaded\n");
307 return IDirectMusicObject_QueryInterface(pExistingEntry->pObject, riid, ppv);
308 }
309
310 TRACE(": not loaded yet\n");
311 pObjectEntry = pExistingEntry;
312 }
313
314 /* basically, if we found alias, we use its descriptor to load...
315 else we use info we were given */
316 if (pObjectEntry) {
317 TRACE(": found alias entry for requested object... using stored info\n");
318 /* I think in certain cases it can happen that entry's descriptor lacks info about
319 where to load from (e.g.: if we loaded from stream and then released object
320 from cache; then only its CLSID, GUID and perhaps name are left); so just
321 overwrite whatever info the entry has (since it ought to be 100% correct) */
322 DMUSIC_CopyDescriptor (pDesc, &pObjectEntry->Desc);
323 /*pDesc = &pObjectEntry->Desc; */ /* FIXME: is this OK? */
324 } else {
325 TRACE(": no cache/alias entry found for requested object\n");
326 }
327
328 if (pDesc->dwValidData & DMUS_OBJ_URL)
329 {
330 TRACE(": loading from URLs not supported yet\n");
332 }
333 else if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
334 {
336
337 if (pDesc->dwValidData & DMUS_OBJ_FULLPATH)
339 else
340 {
341 WCHAR *p;
344 if (p > file_name && p[-1] != '\\') *p++ = '\\';
345 lstrcpyW(p, pDesc->wszFileName);
346 }
347
348 TRACE(": loading from file (%s)\n", debugstr_w(file_name));
349 if (FAILED(hr = file_stream_create(file_name, &pStream))) return hr;
350 }
351 else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
352 /* load object from resource */
353 TRACE(": loading from resource\n");
354 /* create stream and associate it with given resource */
356 if (FAILED(result)) {
357 ERR(": could not create resource stream\n");
358 return result;
359 }
361 if (FAILED(result))
362 {
363 ERR(": could not attach stream to resource\n");
364 IStream_Release (pStream);
365 return result;
366 }
367 }
368 else if (pDesc->dwValidData & DMUS_OBJ_STREAM)
369 {
370 pStream = pDesc->pStream;
371 IStream_AddRef(pStream);
372 }
373 else
374 {
375 FIXME(": unknown/unsupported way of loading\n");
377 }
378
379 if (FAILED(hr = loader_stream_create((IDirectMusicLoader *)iface, pStream, &loader_stream)))
380 return hr;
381 IStream_Release(pStream);
382 pStream = loader_stream;
383
384 /* create object */
385 result = CoCreateInstance (&pDesc->guidClass, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject, (LPVOID*)&pObject);
386 if (FAILED(result)) {
387 IStream_Release(pStream);
388 ERR(": could not create object\n");
389 return result;
390 }
391 /* acquire PersistStream interface */
393 if (FAILED(result)) {
394 IStream_Release(pStream);
396 ERR("failed to Query\n");
397 return result;
398 }
399 /* load */
400 result = IPersistStream_Load (pPersistStream, pStream);
401 if (result != S_OK) {
402 IStream_Release(pStream);
403 IPersistStream_Release(pPersistStream);
405 WARN(": failed to (completely) load object (%#lx)\n", result);
406 return result;
407 }
408 /* get descriptor */
409 DM_STRUCT_INIT(&GotDesc);
411 /* set filename (if we loaded via filename) */
412 if (pDesc->dwValidData & DMUS_OBJ_FILENAME) {
414 lstrcpyW (GotDesc.wszFileName, pDesc->wszFileName);
415 }
416 if (FAILED(result)) {
417 IStream_Release(pStream);
418 IPersistStream_Release(pPersistStream);
420 ERR(": failed to get descriptor\n");
421 return result;
422 }
423 /* release all loading related stuff */
424 IStream_Release (pStream);
425 IPersistStream_Release (pPersistStream);
426
427 /* add object to cache/overwrite existing info (if cache is enabled) */
428 bCache = is_cache_enabled(This, &pDesc->guidClass);
429 if (!bCache) TRACE(": caching disabled\n");
430 else if ((pDesc->dwValidData & source_flags) == DMUS_OBJ_STREAM)
431 {
432 FIXME("Skipping cache for DMUS_OBJ_STREAM object\n");
433 bCache = FALSE;
434 }
435 else
436 {
437 if (!pObjectEntry)
438 {
439 pObjectEntry = calloc(1, sizeof(*pObjectEntry));
440 DM_STRUCT_INIT(&pObjectEntry->Desc);
441 DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc);
442 pObjectEntry->pObject = pObject;
443 list_add_head(&This->cache, &pObjectEntry->entry);
444 }
445 else
446 {
447 DMUSIC_CopyDescriptor (&pObjectEntry->Desc, &GotDesc);
448 pObjectEntry->pObject = pObject;
449 }
450 TRACE(": filled in cache entry\n");
451 }
452
454 if (!bCache) IDirectMusicObject_Release (pObject); /* since loader's reference is not needed */
455 /* if there was trouble with loading, and if no other error occurred,
456 we should return DMUS_S_PARTIALLOAD; else, error is returned */
457 if (result == S_OK)
458 return ret;
459 else
460 return result;
461}
462
463static HRESULT WINAPI loader_SetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDESC *pDesc)
464{
466 LPSTREAM pStream;
468 DMUS_OBJECTDESC Desc;
469 struct cache_entry *pObjectEntry, *pNewEntry;
471 HRESULT hr;
472
473 TRACE("(%p)->(%p)\n", This, pDesc);
474
475 if (TRACE_ON(dmloader))
477
478 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
479 {
481
482 if (pDesc->dwValidData & DMUS_OBJ_FULLPATH)
484 else
485 {
486 WCHAR *p;
489 if (p > file_name && p[-1] != '\\') *p++ = '\\';
490 lstrcpyW(p, pDesc->wszFileName);
491 }
492
493 if (!wcsicmp(file_name, L"C:\\windows\\system32\\drivers\\gm.dls")
495 {
497 if (FAILED(hr)) return hr;
498 }
499
500 if (FAILED(hr = file_stream_create(file_name, &pStream))) return hr;
501 }
502 else if (pDesc->dwValidData & DMUS_OBJ_STREAM)
503 {
504 pStream = pDesc->pStream;
505 IStream_AddRef(pStream);
506 }
507 else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
508 /* create stream */
510 if (FAILED(hr)) {
511 ERR(": could not create resource stream\n");
513 }
514 /* attach stream */
516 if (FAILED(hr))
517 {
518 ERR(": could not attach stream to resource\n");
519 IStream_Release (pStream);
521 }
522 }
523 else {
524 ERR(": no way to get additional info\n");
526 }
527
528 if (FAILED(hr = loader_stream_create((IDirectMusicLoader *)iface, pStream, &loader_stream)))
529 return hr;
530 IStream_Release(pStream);
531 pStream = loader_stream;
532
533 /* create object */
534 hr = CoCreateInstance (&pDesc->guidClass, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject, (LPVOID*)&pObject);
535 if (FAILED(hr)) {
536 IStream_Release(pStream);
537 ERR("Object creation of %s failed %#lx\n", debugstr_guid(&pDesc->guidClass),hr);
539 }
540
543 IStream_Release(pStream);
545 ERR(": couldn't parse descriptor\n");
547 }
548
549 /* copy elements from parsed descriptor into input descriptor; this sets new info, overwriting if necessary,
550 but leaves info that's provided by input and not available from stream */
551 DMUSIC_CopyDescriptor (pDesc, &Desc);
552
553 /* release everything */
555 IStream_Release (pStream);
556
557 /* sometimes it happens that twisted programs call SetObject for same object twice...
558 in such cases, native loader returns S_OK and does nothing... a sound plan */
559 LIST_FOR_EACH_ENTRY(pObjectEntry, &This->cache, struct cache_entry, entry) {
560 if (!memcmp (&pObjectEntry->Desc, pDesc, sizeof(DMUS_OBJECTDESC))) {
561 TRACE(": exactly same entry already exists\n");
562 return S_OK;
563 }
564 }
565
566 /* add new entry */
567 TRACE(": adding alias entry with following info:\n");
568 if (TRACE_ON(dmloader))
570 pNewEntry = calloc(1, sizeof(*pNewEntry));
571 /* use this function instead of pure memcpy due to streams (memcpy just copies pointer),
572 which is basically used further by app that called SetDescriptor... better safety than exception */
573 DMUSIC_CopyDescriptor (&pNewEntry->Desc, pDesc);
574 list_add_head(&This->cache, &pNewEntry->entry);
575
576 return S_OK;
577}
578
579static HRESULT WINAPI loader_SetSearchDirectory(IDirectMusicLoader8 *iface,
580 REFGUID class, WCHAR *path, BOOL clear)
581{
583 int index = index_from_class(class);
584 DWORD attr;
585
586 TRACE("(%p, %s, %s, %d)\n", This, debugstr_dmguid(class), debugstr_w(path), clear);
587
588 if (!path)
589 return E_POINTER;
590
591 if (path[0]) {
595 }
596
597 if (clear)
598 FIXME("clear flag ignored\n");
599
600 /* Ignore invalid GUIDs */
601 if (index < 0)
602 return S_OK;
603
604 if (!This->search_paths[index])
605 This->search_paths[index] = malloc(MAX_PATH);
606 else if (!wcsncmp(This->search_paths[index], path, MAX_PATH))
607 return S_FALSE;
608
609 lstrcpynW(This->search_paths[index], path, MAX_PATH);
610
611 return S_OK;
612}
613
614static HRESULT WINAPI loader_ScanDirectory(IDirectMusicLoader8 *iface, REFGUID rguidClass, WCHAR *pwzFileExtension, WCHAR *pwzScanFileName)
615{
618 HANDLE hSearch;
619 WCHAR wszSearchString[MAX_PATH];
620 WCHAR *p;
622 TRACE("(%p, %s, %s, %s)\n", This, debugstr_dmguid(rguidClass), debugstr_w(pwzFileExtension),
623 debugstr_w(pwzScanFileName));
624 if (index_from_class(rguidClass) <= 0) {
625 ERR(": rguidClass invalid CLSID\n");
626 return REGDB_E_CLASSNOTREG;
627 }
628
629 if (!pwzFileExtension)
630 return S_FALSE;
631
632 /* get search path for given class */
633 get_search_path(This, rguidClass, wszSearchString);
634
635 p = wszSearchString + lstrlenW(wszSearchString);
636 if (p > wszSearchString && p[-1] != '\\') *p++ = '\\';
637 *p++ = '*'; /* any file */
638 if (lstrcmpW (pwzFileExtension, L"*"))
639 *p++ = '.'; /* if we have actual extension, put a dot */
640 lstrcpyW (p, pwzFileExtension);
641
642 TRACE(": search string: %s\n", debugstr_w(wszSearchString));
643
644 hSearch = FindFirstFileW (wszSearchString, &FileData);
645 if (hSearch == INVALID_HANDLE_VALUE) {
646 TRACE(": no files found\n");
647 return S_FALSE;
648 }
649
650 do {
651 DMUS_OBJECTDESC Desc;
652 DM_STRUCT_INIT(&Desc);
654 Desc.guidClass = *rguidClass;
655 lstrcpyW (Desc.wszFileName, FileData.cFileName);
656 FileTimeToLocalFileTime (&FileData.ftCreationTime, &Desc.ftDate);
657 IDirectMusicLoader8_SetObject (iface, &Desc);
658
659 if (!FindNextFileW (hSearch, &FileData)) {
661 TRACE(": search completed\n");
662 result = S_OK;
663 } else {
664 ERR(": could not get next file\n");
665 result = E_FAIL;
666 }
667 FindClose (hSearch);
668 return result;
669 }
670 } while (1);
671}
672
673static HRESULT WINAPI loader_CacheObject(IDirectMusicLoader8 *iface,
674 IDirectMusicObject *object)
675{
678 struct cache_entry *entry;
679
680 TRACE("(%p, %p)\n", This, object);
681
684
685 /* Iterate through the list and check if we have an alias (without object), corresponding
686 to the descriptor of the input object */
688 if (entry) {
689 if ((entry->Desc.dwValidData & DMUS_OBJ_LOADED) && entry->pObject) {
690 TRACE("Object already loaded.\n");
691 return S_FALSE;
692 }
693
694 entry->Desc.dwValidData |= DMUS_OBJ_LOADED;
695 entry->pObject = object;
697 return S_OK;
698 }
699
701}
702
703static HRESULT WINAPI loader_ReleaseObject(IDirectMusicLoader8 *iface,
704 IDirectMusicObject *object)
705{
708 struct cache_entry *entry;
709
710 TRACE("(%p, %p)\n", This, object);
711
712 if (!object)
713 return E_POINTER;
714
717
718 TRACE("Looking for the object in cache\n");
720 if (entry) {
722
723 if (entry->pObject && entry->Desc.dwValidData & DMUS_OBJ_LOADED) {
725 entry->pObject = NULL;
726 entry->Desc.dwValidData &= ~DMUS_OBJ_LOADED;
727 return S_OK;
728 }
729 }
730
731 return S_FALSE;
732}
733
734static HRESULT WINAPI loader_ClearCache(IDirectMusicLoader8 *iface, REFGUID class)
735{
737 struct cache_entry *obj, *obj2;
738
739 TRACE("(%p, %s)\n", This, debugstr_dmguid(class));
740
741 LIST_FOR_EACH_ENTRY_SAFE(obj, obj2, &This->cache, struct cache_entry, entry) {
742 if ((IsEqualGUID(class, &GUID_DirectMusicAllTypes) || IsEqualGUID(class, &obj->Desc.guidClass)) &&
743 (obj->Desc.dwValidData & DMUS_OBJ_LOADED)) {
744 /* basically, wrap to ReleaseObject for each object found */
745 IDirectMusicLoader8_ReleaseObject(iface, obj->pObject);
746 list_remove(&obj->entry);
747 free(obj);
748 }
749 }
750
751 return S_OK;
752}
753
754static HRESULT WINAPI loader_EnableCache(IDirectMusicLoader8 *iface, REFGUID class,
755 BOOL enable)
756{
759
760 TRACE("(%p, %s, %d)\n", This, debugstr_dmguid(class), enable);
761
762 current = is_cache_enabled(This, class);
763
764 if (IsEqualGUID(class, &GUID_DirectMusicAllTypes))
765 This->cache_class = enable ? ~0 : 0;
766 else {
767 int idx = index_from_class(class);
768 if (idx == -1) return S_FALSE;
769 if (enable)
770 This->cache_class |= 1 << idx;
771 else
772 This->cache_class &= ~(1 << idx);
773 }
774
775 if (!enable)
776 IDirectMusicLoader8_ClearCache(iface, class);
777
778 if (current == enable)
779 return S_FALSE;
780
781 return S_OK;
782}
783
784static HRESULT WINAPI loader_EnumObject(IDirectMusicLoader8 *iface, REFGUID rguidClass, DWORD dwIndex, DMUS_OBJECTDESC *pDesc)
785{
787 DWORD dwCount = 0;
788 struct cache_entry *pObjectEntry;
789 TRACE("(%p, %s, %ld, %p)\n", This, debugstr_dmguid(rguidClass), dwIndex, pDesc);
790
791 DM_STRUCT_INIT(pDesc);
792
793 LIST_FOR_EACH_ENTRY(pObjectEntry, &This->cache, struct cache_entry, entry) {
794 if (IsEqualGUID (rguidClass, &GUID_DirectMusicAllTypes) || IsEqualGUID (rguidClass, &pObjectEntry->Desc.guidClass)) {
795 if (dwCount == dwIndex) {
796 *pDesc = pObjectEntry->Desc;
797 /* we aren't supposed to reveal this info */
799 pDesc->pbMemData = NULL;
800 pDesc->llMemLength = 0;
801 pDesc->pStream = NULL;
802 return S_OK;
803 }
804 dwCount++;
805 }
806 }
807
808 TRACE(": not found\n");
809 return S_FALSE;
810}
811
812static void WINAPI loader_CollectGarbage(IDirectMusicLoader8 *iface)
813{
814 FIXME("(%p)->(): stub\n", iface);
815}
816
817static HRESULT WINAPI loader_ReleaseObjectByUnknown(IDirectMusicLoader8 *iface, IUnknown *pObject)
818{
821 LPDIRECTMUSICOBJECT pObjectInterface;
822
823 TRACE("(%p, %p)\n", This, pObject);
824
825 if (IsBadReadPtr (pObject, sizeof(*pObject))) {
826 ERR(": pObject bad write pointer\n");
827 return E_POINTER;
828 }
829 /* we simply get IDirectMusicObject interface */
830 result = IUnknown_QueryInterface (pObject, &IID_IDirectMusicObject, (LPVOID*)&pObjectInterface);
831 if (FAILED(result)) return result;
832 /* and release it in old-fashioned way */
833 result = IDirectMusicLoader8_ReleaseObject (iface, pObjectInterface);
834 IDirectMusicObject_Release (pObjectInterface);
835
836 return result;
837}
838
839static HRESULT WINAPI loader_LoadObjectFromFile(IDirectMusicLoader8 *iface, REFGUID rguidClassID, REFIID iidInterfaceID, WCHAR *pwzFilePath, void **ppObject)
840{
842 DMUS_OBJECTDESC ObjDesc;
843 WCHAR wszLoaderSearchPath[MAX_PATH];
844
845 TRACE("(%p, %s, %s, %s, %p): wrapping to loader_GetObject\n", This, debugstr_dmguid(rguidClassID), debugstr_dmguid(iidInterfaceID), debugstr_w(pwzFilePath), ppObject);
846
847 DM_STRUCT_INIT(&ObjDesc);
848 ObjDesc.dwValidData = DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH | DMUS_OBJ_CLASS; /* I believe I've read somewhere in MSDN that this function requires either full path or relative path */
849 ObjDesc.guidClass = *rguidClassID;
850 /* OK, MSDN says that search order is the following:
851 - current directory (DONE)
852 - windows search path (FIXME: how do I get that?)
853 - loader's search path (DONE)
854 */
855 get_search_path(This, rguidClassID, wszLoaderSearchPath);
856 /* search in current directory */
857 if (!SearchPathW(NULL, pwzFilePath, NULL, ARRAY_SIZE(ObjDesc.wszFileName), ObjDesc.wszFileName, NULL) &&
858 /* search in loader's search path */
859 !SearchPathW(wszLoaderSearchPath, pwzFilePath, NULL, ARRAY_SIZE(ObjDesc.wszFileName), ObjDesc.wszFileName, NULL)) {
860 /* cannot find file */
861 TRACE(": cannot find file\n");
863 }
864
865 TRACE(": full file path = %s\n", debugstr_w (ObjDesc.wszFileName));
866
867 return IDirectMusicLoader_GetObject(iface, &ObjDesc, iidInterfaceID, ppObject);
868}
869
870static const IDirectMusicLoader8Vtbl loader_vtbl =
871{
887};
888
890{
891 DWORD ret;
892 HKEY hkey;
893
894 if (!(ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\DirectMusic" , 0, KEY_READ, &hkey)))
895 {
896 DWORD type, size = max_len * sizeof(WCHAR);
897 ret = RegQueryValueExW(hkey, L"GMFilePath", NULL, &type, (BYTE *)path, &size);
898 RegCloseKey(hkey);
899
901 }
902
903 if (!ret) WARN("Failed to find %s, using system fallbacks\n", debugstr_w(path));
904 else WARN("Failed to open GMFilePath registry key, using system fallbacks\n");
905
906 return get_system_default_gm_path(path, max_len);
907}
908
909/* for ClassFactory */
910HRESULT create_dmloader(REFIID lpcGUID, void **ppobj)
911{
912 struct loader *obj;
913 DMUS_OBJECTDESC Desc;
914 HRESULT hr;
915
916 TRACE("(%s, %p)\n", debugstr_dmguid(lpcGUID), ppobj);
917
918 *ppobj = NULL;
919 if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
920 obj->IDirectMusicLoader8_iface.lpVtbl = &loader_vtbl;
921 obj->ref = 1;
922 list_init(&obj->cache);
923 /* Caching is enabled by default for all classes */
924 obj->cache_class = ~0;
925
926 /* set default DLS collection (via SetObject... so that loading via DMUS_OBJ_OBJECT is possible) */
927 DM_STRUCT_INIT(&Desc);
929 Desc.guidClass = CLSID_DirectMusicCollection;
930 Desc.guidObject = GUID_DefaultGMCollection;
932 hr = IDirectMusicLoader_SetObject(&obj->IDirectMusicLoader8_iface, &Desc);
933 if (FAILED(hr)) WARN("Failed to load the default collection, hr %#lx\n", hr);
934
935 hr = IDirectMusicLoader_QueryInterface(&obj->IDirectMusicLoader8_iface, lpcGUID, ppobj);
936 IDirectMusicLoader_Release(&obj->IDirectMusicLoader8_iface);
937 return hr;
938}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
static FILEDATA FileData[MAX_FDS]
Definition: fs.c:51
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define DM_STRUCT_INIT(x)
Definition: debug.h:30
static HRESULT WINAPI loader_CacheObject(IDirectMusicLoader8 *iface, IDirectMusicObject *object)
Definition: loader.c:673
static HRESULT WINAPI loader_EnableCache(IDirectMusicLoader8 *iface, REFGUID class, BOOL enable)
Definition: loader.c:754
static HRESULT WINAPI loader_ClearCache(IDirectMusicLoader8 *iface, REFGUID class)
Definition: loader.c:734
static const IDirectMusicLoader8Vtbl loader_vtbl
Definition: loader.c:870
static const GUID * classes[]
Definition: loader.c:49
static HRESULT WINAPI loader_ScanDirectory(IDirectMusicLoader8 *iface, REFGUID rguidClass, WCHAR *pwzFileExtension, WCHAR *pwzScanFileName)
Definition: loader.c:614
static HRESULT get_system_default_gm_path(WCHAR *path, UINT max_len)
Definition: loader.c:29
HRESULT create_dmloader(REFIID lpcGUID, void **ppobj)
Definition: loader.c:910
static HRESULT WINAPI loader_ReleaseObject(IDirectMusicLoader8 *iface, IDirectMusicObject *object)
Definition: loader.c:703
static HRESULT get_default_gm_path(WCHAR *path, DWORD max_len)
Definition: loader.c:889
static struct loader * impl_from_IDirectMusicLoader8(IDirectMusicLoader8 *iface)
Definition: loader.c:80
static HRESULT WINAPI loader_ReleaseObjectByUnknown(IDirectMusicLoader8 *iface, IUnknown *pObject)
Definition: loader.c:817
static void get_search_path(struct loader *This, REFGUID class, WCHAR *path)
Definition: loader.c:101
static HRESULT WINAPI loader_LoadObjectFromFile(IDirectMusicLoader8 *iface, REFGUID rguidClassID, REFIID iidInterfaceID, WCHAR *pwzFilePath, void **ppObject)
Definition: loader.c:839
static void WINAPI loader_CollectGarbage(IDirectMusicLoader8 *iface)
Definition: loader.c:812
static int index_from_class(REFCLSID class)
Definition: loader.c:85
static HRESULT WINAPI loader_SetSearchDirectory(IDirectMusicLoader8 *iface, REFGUID class, WCHAR *path, BOOL clear)
Definition: loader.c:579
static const WCHAR * system_default_gm_paths[]
Definition: loader.c:23
static ULONG WINAPI loader_Release(IDirectMusicLoader8 *iface)
Definition: loader.c:164
static ULONG WINAPI loader_AddRef(IDirectMusicLoader8 *iface)
Definition: loader.c:154
static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDESC *pDesc, REFIID riid, void **ppv)
Definition: loader.c:272
static HRESULT DMUSIC_CopyDescriptor(DMUS_OBJECTDESC *pDst, DMUS_OBJECTDESC *pSrc)
Definition: loader.c:114
static BOOL is_cache_enabled(struct loader *This, REFCLSID class)
Definition: loader.c:96
static HRESULT WINAPI loader_QueryInterface(IDirectMusicLoader8 *iface, REFIID riid, void **ppobj)
Definition: loader.c:137
static HRESULT WINAPI loader_EnumObject(IDirectMusicLoader8 *iface, REFGUID rguidClass, DWORD dwIndex, DMUS_OBJECTDESC *pDesc)
Definition: loader.c:784
static HRESULT WINAPI loader_SetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDESC *pDesc)
Definition: loader.c:463
static struct cache_entry * find_cache_object(struct loader *This, DMUS_OBJECTDESC *desc)
Definition: loader.c:183
unsigned int idx
Definition: utils.c:40
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1397
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:216
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:523
#define swprintf
Definition: precomp.h:40
#define DMUS_E_LOADER_OBJECTNOTFOUND
Definition: dmerror.h:122
#define DMUS_E_LOADER_NOCLASSID
Definition: dmerror.h:117
#define DMUS_E_LOADER_NOFILENAME
Definition: dmerror.h:123
#define DMUS_E_LOADER_FORMATNOTSUPPORTED
Definition: dmerror.h:120
#define DMUS_E_LOADER_FAILEDOPEN
Definition: dmerror.h:119
#define DMUS_E_LOADER_BADPATH
Definition: dmerror.h:118
HRESULT DMUSIC_CreateDirectMusicLoaderResourceStream(void **ppobj)
Definition: loaderstream.c:661
HRESULT file_stream_create(const WCHAR *path, IStream **ret_iface)
Definition: loaderstream.c:435
HRESULT loader_stream_create(IDirectMusicLoader *loader, IStream *stream, IStream **ret_iface)
Definition: loaderstream.c:240
HRESULT WINAPI IDirectMusicLoaderResourceStream_Attach(LPSTREAM iface, LPBYTE pbMemData, LONGLONG llMemLength, LONGLONG llPos)
Definition: loaderstream.c:472
void dump_DMUS_OBJECTDESC(DMUS_OBJECTDESC *desc)
Definition: dmobject.c:222
const char * debugstr_dmguid(const GUID *id)
Definition: dmobject.c:36
#define DMUS_OBJ_DATE
Definition: dmusici.h:273
#define IDirectMusicLoader8_SetObject(p, a)
Definition: dmusici.h:927
#define IDirectMusicObject_ParseDescriptor(p, a, b)
Definition: dmusici.h:848
#define DMUS_OBJ_FULLPATH
Definition: dmusici.h:270
#define IDirectMusicObject_QueryInterface(p, a, b)
Definition: dmusici.h:842
#define IDirectMusicLoader_AddRef(p)
Definition: dmusici.h:878
#define IDirectMusicObject_Release(p)
Definition: dmusici.h:844
#define IDirectMusicLoader_QueryInterface(p, a, b)
Definition: dmusici.h:877
#define IDirectMusicObject_AddRef(p)
Definition: dmusici.h:843
#define IDirectMusicLoader_Release(p)
Definition: dmusici.h:879
#define DMUS_MAX_CATEGORY
Definition: dmusici.h:246
#define DMUS_OBJ_MEMORY
Definition: dmusici.h:275
#define DMUS_OBJ_NAME
Definition: dmusici.h:267
#define DMUS_OBJ_STREAM
Definition: dmusici.h:276
#define IDirectMusicLoader_SetObject(p, a)
Definition: dmusici.h:882
#define IDirectMusicLoader8_ReleaseObject(p, a)
Definition: dmusici.h:931
#define DMUS_OBJ_FILENAME
Definition: dmusici.h:269
#define IDirectMusicObject_GetDescriptor(p, a)
Definition: dmusici.h:846
#define IDirectMusicLoader8_ClearCache(p, a)
Definition: dmusici.h:932
struct IDirectMusicObject * LPDIRECTMUSICOBJECT
Definition: dmusici.h:120
#define DMUS_OBJ_CLASS
Definition: dmusici.h:266
#define DMUS_MAX_NAME
Definition: dmusici.h:245
#define DMUS_OBJ_URL
Definition: dmusici.h:271
#define DMUS_MAX_FILENAME
Definition: dmusici.h:247
#define DMUS_OBJ_VERSION
Definition: dmusici.h:272
#define IDirectMusicLoader_GetObject(p, a, b, c)
Definition: dmusici.h:881
#define DMUS_OBJ_CATEGORY
Definition: dmusici.h:268
#define DMUS_OBJ_OBJECT
Definition: dmusici.h:265
#define DMUS_OBJ_LOADED
Definition: dmusici.h:274
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxObject * pObject
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean enable
Definition: glext.h:11120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
struct task_struct * current
Definition: linux.c:32
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
static LPCWSTR file_name
Definition: protocol.c:152
#define KEY_READ
Definition: nt_native.h:1026
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
interface IStream * LPSTREAM
Definition: objfwd.h:10
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define calloc
Definition: rosglue.h:14
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR wszCategory[DMUS_MAX_CATEGORY]
Definition: dmusici.h:749
DMUS_VERSION vVersion
Definition: dmusici.h:747
IStream * pStream
Definition: dmusici.h:753
LONGLONG llMemLength
Definition: dmusici.h:751
FILETIME ftDate
Definition: dmusici.h:746
LPBYTE pbMemData
Definition: dmusici.h:752
DWORD dwValidData
Definition: dmusici.h:743
WCHAR wszFileName[DMUS_MAX_FILENAME]
Definition: dmusici.h:750
WCHAR wszName[DMUS_MAX_NAME]
Definition: dmusici.h:748
Definition: scsiwmi.h:51
Definition: cookie.c:202
Definition: svc_auth_des.c:77
struct list entry
Definition: loader.c:66
DMUS_OBJECTDESC Desc
Definition: loader.c:67
IDirectMusicObject * pObject
Definition: loader.c:68
Definition: cache.c:41
Definition: loader.c:72
unsigned int cache_class
Definition: loader.c:76
LONG ref
Definition: loader.c:74
WCHAR * search_paths[ARRAY_SIZE(classes)]
Definition: loader.c:75
IDirectMusicLoader8 IDirectMusicLoader8_iface
Definition: loader.c:73
Definition: send.c:48
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:3801
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define ERROR_NO_MORE_FILES
Definition: winerror.h:243
#define E_POINTER
Definition: winerror.h:3480
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
unsigned char BYTE
Definition: xxhash.c:193