1 /* 2 * IParseDisplayName implementation for DEVENUM.dll 3 * 4 * Copyright (C) 2002 Robert Shearman 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 * 20 * NOTES ON THIS FILE: 21 * - Implements IParseDisplayName interface which creates a moniker 22 * from a string in a special format 23 */ 24 #include "devenum_private.h" 25 26 #include "wine/debug.h" 27 28 WINE_DEFAULT_DEBUG_CHANNEL(devenum); 29 30 static HRESULT WINAPI DEVENUM_IParseDisplayName_QueryInterface(IParseDisplayName *iface, 31 REFIID riid, void **ppv) 32 { 33 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); 34 35 if (!ppv) 36 return E_POINTER; 37 38 if (IsEqualGUID(riid, &IID_IUnknown) || 39 IsEqualGUID(riid, &IID_IParseDisplayName)) 40 { 41 *ppv = iface; 42 IParseDisplayName_AddRef(iface); 43 return S_OK; 44 } 45 46 FIXME("- no interface IID: %s\n", debugstr_guid(riid)); 47 *ppv = NULL; 48 return E_NOINTERFACE; 49 } 50 51 static ULONG WINAPI DEVENUM_IParseDisplayName_AddRef(IParseDisplayName *iface) 52 { 53 TRACE("\n"); 54 55 DEVENUM_LockModule(); 56 57 return 2; /* non-heap based object */ 58 } 59 60 static ULONG WINAPI DEVENUM_IParseDisplayName_Release(IParseDisplayName *iface) 61 { 62 TRACE("\n"); 63 64 DEVENUM_UnlockModule(); 65 66 return 1; /* non-heap based object */ 67 } 68 69 /********************************************************************** 70 * DEVENUM_IParseDisplayName_ParseDisplayName 71 * 72 * Creates a moniker referenced to by the display string argument 73 * 74 * POSSIBLE BUGS: 75 * Might not handle more complicated strings properly (ie anything 76 * not in "@device:sw:{CLSID1}\<filter name or CLSID>" format 77 */ 78 static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayName *iface, 79 IBindCtx *pbc, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut) 80 { 81 LPOLESTR pszBetween = NULL; 82 LPOLESTR pszClass = NULL; 83 MediaCatMoniker * pMoniker = NULL; 84 CLSID clsidDevice; 85 HRESULT res = S_OK; 86 WCHAR wszRegKeyName[MAX_PATH]; 87 HKEY hbasekey; 88 int classlen; 89 static const WCHAR wszRegSeparator[] = {'\\', 0 }; 90 91 TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut); 92 93 *ppmkOut = NULL; 94 if (pchEaten) 95 *pchEaten = strlenW(pszDisplayName); 96 97 pszDisplayName = strchrW(pszDisplayName, '{'); 98 pszBetween = strchrW(pszDisplayName, '}') + 2; 99 100 /* size = pszBetween - pszDisplayName - 1 (for '\\' after CLSID) 101 * + 1 (for NULL character) 102 */ 103 classlen = (int)(pszBetween - pszDisplayName - 1); 104 pszClass = CoTaskMemAlloc((classlen + 1) * sizeof(WCHAR)); 105 if (!pszClass) 106 return E_OUTOFMEMORY; 107 108 memcpy(pszClass, pszDisplayName, classlen * sizeof(WCHAR)); 109 pszClass[classlen] = 0; 110 111 TRACE("Device CLSID: %s\n", debugstr_w(pszClass)); 112 113 res = CLSIDFromString(pszClass, &clsidDevice); 114 115 if (SUCCEEDED(res)) 116 { 117 res = DEVENUM_GetCategoryKey(&clsidDevice, &hbasekey, wszRegKeyName, MAX_PATH); 118 } 119 120 if (SUCCEEDED(res)) 121 { 122 pMoniker = DEVENUM_IMediaCatMoniker_Construct(); 123 if (pMoniker) 124 { 125 strcatW(wszRegKeyName, wszRegSeparator); 126 strcatW(wszRegKeyName, pszBetween); 127 128 if (RegCreateKeyW(hbasekey, wszRegKeyName, &pMoniker->hkey) == ERROR_SUCCESS) 129 *ppmkOut = &pMoniker->IMoniker_iface; 130 else 131 { 132 IMoniker_Release(&pMoniker->IMoniker_iface); 133 res = MK_E_NOOBJECT; 134 } 135 } 136 } 137 138 CoTaskMemFree(pszClass); 139 140 TRACE("-- returning: %x\n", res); 141 return res; 142 } 143 144 /********************************************************************** 145 * IParseDisplayName_Vtbl 146 */ 147 static const IParseDisplayNameVtbl IParseDisplayName_Vtbl = 148 { 149 DEVENUM_IParseDisplayName_QueryInterface, 150 DEVENUM_IParseDisplayName_AddRef, 151 DEVENUM_IParseDisplayName_Release, 152 DEVENUM_IParseDisplayName_ParseDisplayName 153 }; 154 155 /* The one instance of this class */ 156 IParseDisplayName DEVENUM_ParseDisplayName = { &IParseDisplayName_Vtbl }; 157