Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmediacatenum.c
Go to the documentation of this file.
00001 /* 00002 * IEnumMoniker implementation for DEVENUM.dll 00003 * 00004 * Copyright (C) 2002 Robert Shearman 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 * 00020 * NOTES ON THIS FILE: 00021 * - Implements IEnumMoniker interface which enumerates through moniker 00022 * objects created from HKEY_CLASSES/CLSID/{DEVICE_CLSID}/Instance 00023 */ 00024 00025 #include "devenum_private.h" 00026 #include "oleauto.h" 00027 #include "ocidl.h" 00028 00029 #include "wine/debug.h" 00030 00031 WINE_DEFAULT_DEBUG_CHANNEL(devenum); 00032 00033 static ULONG WINAPI DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface); 00034 static ULONG WINAPI DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface); 00035 static ULONG WINAPI DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface); 00036 00037 typedef struct 00038 { 00039 const IPropertyBagVtbl *lpVtbl; 00040 LONG ref; 00041 HKEY hkey; 00042 } RegPropBagImpl; 00043 00044 00045 static HRESULT WINAPI DEVENUM_IPropertyBag_QueryInterface( 00046 LPPROPERTYBAG iface, 00047 REFIID riid, 00048 LPVOID *ppvObj) 00049 { 00050 RegPropBagImpl *This = (RegPropBagImpl *)iface; 00051 00052 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj); 00053 00054 if (This == NULL || ppvObj == NULL) return E_POINTER; 00055 00056 if (IsEqualGUID(riid, &IID_IUnknown) || 00057 IsEqualGUID(riid, &IID_IPropertyBag)) 00058 { 00059 *ppvObj = iface; 00060 DEVENUM_IPropertyBag_AddRef(iface); 00061 return S_OK; 00062 } 00063 00064 FIXME("- no interface IID: %s\n", debugstr_guid(riid)); 00065 return E_NOINTERFACE; 00066 } 00067 00068 /********************************************************************** 00069 * DEVENUM_IPropertyBag_AddRef (also IUnknown) 00070 */ 00071 static ULONG WINAPI DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface) 00072 { 00073 RegPropBagImpl *This = (RegPropBagImpl *)iface; 00074 00075 TRACE("(%p)->() AddRef from %d\n", iface, This->ref); 00076 00077 return InterlockedIncrement(&This->ref); 00078 } 00079 00080 /********************************************************************** 00081 * DEVENUM_IPropertyBag_Release (also IUnknown) 00082 */ 00083 static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface) 00084 { 00085 RegPropBagImpl *This = (RegPropBagImpl *)iface; 00086 ULONG ref; 00087 00088 TRACE("(%p)->() ReleaseThis->ref from %d\n", iface, This->ref); 00089 00090 ref = InterlockedDecrement(&This->ref); 00091 if (ref == 0) { 00092 RegCloseKey(This->hkey); 00093 CoTaskMemFree(This); 00094 DEVENUM_UnlockModule(); 00095 } 00096 return ref; 00097 } 00098 00099 static HRESULT WINAPI DEVENUM_IPropertyBag_Read( 00100 LPPROPERTYBAG iface, 00101 LPCOLESTR pszPropName, 00102 VARIANT* pVar, 00103 IErrorLog* pErrorLog) 00104 { 00105 LPVOID pData = NULL; 00106 DWORD received; 00107 DWORD type = 0; 00108 RegPropBagImpl *This = (RegPropBagImpl *)iface; 00109 HRESULT res = S_OK; 00110 LONG reswin32; 00111 00112 TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog); 00113 00114 if (!pszPropName || !pVar) 00115 return E_POINTER; 00116 00117 reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, NULL, NULL, &received); 00118 res = HRESULT_FROM_WIN32(reswin32); 00119 00120 if (SUCCEEDED(res)) 00121 { 00122 pData = HeapAlloc(GetProcessHeap(), 0, received); 00123 00124 /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */ 00125 reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, &type, pData, &received); 00126 res = HRESULT_FROM_WIN32(reswin32); 00127 } 00128 00129 if (SUCCEEDED(res)) 00130 { 00131 res = E_INVALIDARG; /* assume we cannot coerce into right type */ 00132 00133 TRACE("Read %d bytes (%s)\n", received, type == REG_SZ ? debugstr_w(pData) : "binary data"); 00134 00135 switch (type) 00136 { 00137 case REG_SZ: 00138 switch (V_VT(pVar)) 00139 { 00140 case VT_LPWSTR: 00141 V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received); 00142 memcpy(V_UNION(pVar, bstrVal), pData, received); 00143 res = S_OK; 00144 break; 00145 case VT_EMPTY: 00146 V_VT(pVar) = VT_BSTR; 00147 /* fall through */ 00148 case VT_BSTR: 00149 V_UNION(pVar, bstrVal) = SysAllocStringLen(pData, received/sizeof(WCHAR) - 1); 00150 res = S_OK; 00151 break; 00152 } 00153 break; 00154 case REG_DWORD: 00155 TRACE("REG_DWORD: %x\n", *(DWORD *)pData); 00156 switch (V_VT(pVar)) 00157 { 00158 case VT_EMPTY: 00159 V_VT(pVar) = VT_I4; 00160 /* fall through */ 00161 case VT_I4: 00162 case VT_UI4: 00163 V_UNION(pVar, ulVal) = *(DWORD *)pData; 00164 res = S_OK; 00165 break; 00166 } 00167 break; 00168 case REG_BINARY: 00169 { 00170 SAFEARRAYBOUND bound; 00171 void * pArrayElements; 00172 bound.lLbound = 0; 00173 bound.cElements = received; 00174 TRACE("REG_BINARY: len = %d\n", received); 00175 switch (V_VT(pVar)) 00176 { 00177 case VT_EMPTY: 00178 V_VT(pVar) = VT_ARRAY | VT_UI1; 00179 /* fall through */ 00180 case VT_ARRAY | VT_UI1: 00181 if (!(V_UNION(pVar, parray) = SafeArrayCreate(VT_UI1, 1, &bound))) 00182 res = E_OUTOFMEMORY; 00183 else 00184 res = S_OK; 00185 break; 00186 } 00187 00188 if (res == E_INVALIDARG) 00189 break; 00190 00191 res = SafeArrayAccessData(V_UNION(pVar, parray), &pArrayElements); 00192 if (FAILED(res)) 00193 break; 00194 00195 CopyMemory(pArrayElements, pData, received); 00196 res = SafeArrayUnaccessData(V_UNION(pVar, parray)); 00197 break; 00198 } 00199 } 00200 if (res == E_INVALIDARG) 00201 FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar), type); 00202 } 00203 00204 HeapFree(GetProcessHeap(), 0, pData); 00205 00206 TRACE("<- %x\n", res); 00207 return res; 00208 } 00209 00210 static HRESULT WINAPI DEVENUM_IPropertyBag_Write( 00211 LPPROPERTYBAG iface, 00212 LPCOLESTR pszPropName, 00213 VARIANT* pVar) 00214 { 00215 RegPropBagImpl *This = (RegPropBagImpl *)iface; 00216 LPVOID lpData = NULL; 00217 DWORD cbData = 0; 00218 DWORD dwType = 0; 00219 HRESULT res = S_OK; 00220 00221 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar); 00222 00223 switch (V_VT(pVar)) 00224 { 00225 case VT_BSTR: 00226 TRACE("writing %s\n", debugstr_w(V_UNION(pVar, bstrVal))); 00227 lpData = V_UNION(pVar, bstrVal); 00228 dwType = REG_SZ; 00229 cbData = (lstrlenW(V_UNION(pVar, bstrVal)) + 1) * sizeof(WCHAR); 00230 break; 00231 case VT_I4: 00232 case VT_UI4: 00233 TRACE("writing %u\n", V_UNION(pVar, ulVal)); 00234 lpData = &V_UNION(pVar, ulVal); 00235 dwType = REG_DWORD; 00236 cbData = sizeof(DWORD); 00237 break; 00238 case VT_ARRAY | VT_UI1: 00239 { 00240 LONG lUbound = 0; 00241 LONG lLbound = 0; 00242 dwType = REG_BINARY; 00243 res = SafeArrayGetLBound(V_UNION(pVar, parray), 1, &lLbound); 00244 res = SafeArrayGetUBound(V_UNION(pVar, parray), 1, &lUbound); 00245 cbData = (lUbound - lLbound + 1) /* * sizeof(BYTE)*/; 00246 TRACE("cbData: %d\n", cbData); 00247 res = SafeArrayAccessData(V_UNION(pVar, parray), &lpData); 00248 break; 00249 } 00250 default: 00251 FIXME("Variant type %d not handled\n", V_VT(pVar)); 00252 return E_FAIL; 00253 } 00254 00255 if (RegSetValueExW(This->hkey, 00256 pszPropName, 0, 00257 dwType, lpData, cbData) != ERROR_SUCCESS) 00258 res = E_FAIL; 00259 00260 if (V_VT(pVar) & VT_ARRAY) 00261 res = SafeArrayUnaccessData(V_UNION(pVar, parray)); 00262 00263 return res; 00264 } 00265 00266 static const IPropertyBagVtbl IPropertyBag_Vtbl = 00267 { 00268 DEVENUM_IPropertyBag_QueryInterface, 00269 DEVENUM_IPropertyBag_AddRef, 00270 DEVENUM_IPropertyBag_Release, 00271 DEVENUM_IPropertyBag_Read, 00272 DEVENUM_IPropertyBag_Write 00273 }; 00274 00275 static HRESULT DEVENUM_IPropertyBag_Construct(HANDLE hkey, IPropertyBag **ppBag) 00276 { 00277 RegPropBagImpl * rpb = CoTaskMemAlloc(sizeof(RegPropBagImpl)); 00278 if (!rpb) 00279 return E_OUTOFMEMORY; 00280 rpb->lpVtbl = &IPropertyBag_Vtbl; 00281 rpb->ref = 1; 00282 rpb->hkey = hkey; 00283 *ppBag = (IPropertyBag*)rpb; 00284 DEVENUM_LockModule(); 00285 return S_OK; 00286 } 00287 00288 00289 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_QueryInterface( 00290 LPMONIKER iface, 00291 REFIID riid, 00292 LPVOID *ppvObj) 00293 { 00294 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00295 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); 00296 00297 if (This == NULL || ppvObj == NULL) return E_POINTER; 00298 00299 *ppvObj = NULL; 00300 00301 if (IsEqualGUID(riid, &IID_IUnknown) || 00302 IsEqualGUID(riid, &IID_IPersist) || 00303 IsEqualGUID(riid, &IID_IPersistStream) || 00304 IsEqualGUID(riid, &IID_IMoniker)) 00305 { 00306 *ppvObj = iface; 00307 DEVENUM_IMediaCatMoniker_AddRef(iface); 00308 return S_OK; 00309 } 00310 00311 FIXME("- no interface IID: %s\n", debugstr_guid(riid)); 00312 return E_NOINTERFACE; 00313 } 00314 00315 /********************************************************************** 00316 * DEVENUM_IMediaCatMoniker_AddRef (also IUnknown) 00317 */ 00318 static ULONG WINAPI DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface) 00319 { 00320 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00321 TRACE("\n"); 00322 00323 return InterlockedIncrement(&This->ref); 00324 } 00325 00326 /********************************************************************** 00327 * DEVENUM_IMediaCatMoniker_Release (also IUnknown) 00328 */ 00329 static ULONG WINAPI DEVENUM_IMediaCatMoniker_Release(LPMONIKER iface) 00330 { 00331 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00332 ULONG ref; 00333 TRACE("\n"); 00334 00335 ref = InterlockedDecrement(&This->ref); 00336 if (ref == 0) { 00337 RegCloseKey(This->hkey); 00338 CoTaskMemFree(This); 00339 DEVENUM_UnlockModule(); 00340 } 00341 return ref; 00342 } 00343 00344 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetClassID( 00345 LPMONIKER iface, 00346 CLSID* pClassID) 00347 { 00348 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00349 FIXME("(%p)->(%p): stub\n", This, pClassID); 00350 00351 if (pClassID == NULL) 00352 return E_POINTER; 00353 00354 return E_NOTIMPL; 00355 } 00356 00357 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsDirty(LPMONIKER iface) 00358 { 00359 FIXME("(%p)->(): stub\n", iface); 00360 00361 return S_FALSE; 00362 } 00363 00364 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Load(LPMONIKER iface, IStream* pStm) 00365 { 00366 FIXME("(%p)->(%p): stub\n", iface, pStm); 00367 00368 return E_NOTIMPL; 00369 } 00370 00371 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Save(LPMONIKER iface, IStream* pStm, BOOL fClearDirty) 00372 { 00373 FIXME("(%p)->(%p, %s): stub\n", iface, pStm, fClearDirty ? "true" : "false"); 00374 00375 return STG_E_CANTSAVE; 00376 } 00377 00378 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetSizeMax( 00379 LPMONIKER iface, 00380 ULARGE_INTEGER* pcbSize) 00381 { 00382 FIXME("(%p)->(%p): stub\n", iface, pcbSize); 00383 00384 ZeroMemory(pcbSize, sizeof(*pcbSize)); 00385 00386 return S_OK; 00387 } 00388 00389 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject( 00390 LPMONIKER iface, 00391 IBindCtx* pbc, 00392 IMoniker* pmkToLeft, 00393 REFIID riidResult, 00394 void** ppvResult) 00395 { 00396 IUnknown * pObj = NULL; 00397 IPropertyBag * pProp = NULL; 00398 CLSID clsID; 00399 VARIANT var; 00400 HRESULT res = E_FAIL; 00401 00402 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00403 00404 VariantInit(&var); 00405 00406 TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult); 00407 00408 *ppvResult = NULL; 00409 00410 if(pmkToLeft==NULL) 00411 { 00412 /* first activation of this class */ 00413 LPVOID pvptr; 00414 res=IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, &pvptr); 00415 pProp = pvptr; 00416 if (SUCCEEDED(res)) 00417 { 00418 V_VT(&var) = VT_LPWSTR; 00419 res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL); 00420 } 00421 if (SUCCEEDED(res)) 00422 { 00423 res = CLSIDFromString(V_UNION(&var,bstrVal), &clsID); 00424 CoTaskMemFree(V_UNION(&var, bstrVal)); 00425 } 00426 if (SUCCEEDED(res)) 00427 { 00428 res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IUnknown,&pvptr); 00429 pObj = pvptr; 00430 } 00431 } 00432 00433 if (pObj!=NULL) 00434 { 00435 /* get the requested interface from the loaded class */ 00436 res = S_OK; 00437 if (pProp) { 00438 HRESULT res2; 00439 LPVOID ppv = NULL; 00440 res2 = IUnknown_QueryInterface(pObj, &IID_IPersistPropertyBag, &ppv); 00441 if (SUCCEEDED(res2)) { 00442 res = IPersistPropertyBag_Load((IPersistPropertyBag *) ppv, pProp, NULL); 00443 IPersistPropertyBag_Release((IPersistPropertyBag *) ppv); 00444 } 00445 } 00446 if (SUCCEEDED(res)) 00447 res= IUnknown_QueryInterface(pObj,riidResult,ppvResult); 00448 IUnknown_Release(pObj); 00449 } 00450 00451 if (pProp) 00452 { 00453 IPropertyBag_Release(pProp); 00454 } 00455 00456 TRACE("<- 0x%x\n", res); 00457 00458 return res; 00459 } 00460 00461 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToStorage( 00462 LPMONIKER iface, 00463 IBindCtx* pbc, 00464 IMoniker* pmkToLeft, 00465 REFIID riid, 00466 void** ppvObj) 00467 { 00468 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00469 TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj); 00470 00471 *ppvObj = NULL; 00472 00473 if (pbc || pmkToLeft) 00474 return MK_E_NOSTORAGE; 00475 00476 if (IsEqualGUID(riid, &IID_IPropertyBag)) 00477 { 00478 HANDLE hkey; 00479 DuplicateHandle(GetCurrentProcess(), This->hkey, GetCurrentProcess(), &hkey, 0, 0, DUPLICATE_SAME_ACCESS); 00480 return DEVENUM_IPropertyBag_Construct(hkey, (IPropertyBag**)ppvObj); 00481 } 00482 00483 return MK_E_NOSTORAGE; 00484 } 00485 00486 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Reduce( 00487 LPMONIKER iface, 00488 IBindCtx* pbc, 00489 DWORD dwReduceHowFar, 00490 IMoniker** ppmkToLeft, 00491 IMoniker** ppmkReduced) 00492 { 00493 TRACE("(%p)->(%p, %d, %p, %p)\n", iface, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced); 00494 00495 if (ppmkToLeft) 00496 *ppmkToLeft = NULL; 00497 *ppmkReduced = iface; 00498 00499 return MK_S_REDUCED_TO_SELF; 00500 } 00501 00502 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ComposeWith( 00503 LPMONIKER iface, 00504 IMoniker* pmkRight, 00505 BOOL fOnlyIfNotGeneric, 00506 IMoniker** ppmkComposite) 00507 { 00508 FIXME("(%p)->(%p, %s, %p): stub\n", iface, pmkRight, fOnlyIfNotGeneric ? "true" : "false", ppmkComposite); 00509 00510 /* FIXME: use CreateGenericComposite? */ 00511 *ppmkComposite = NULL; 00512 00513 return E_NOTIMPL; 00514 } 00515 00516 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Enum( 00517 LPMONIKER iface, 00518 BOOL fForward, 00519 IEnumMoniker** ppenumMoniker) 00520 { 00521 FIXME("(%p)->(%s, %p): stub\n", iface, fForward ? "true" : "false", ppenumMoniker); 00522 00523 *ppenumMoniker = NULL; 00524 00525 return S_OK; 00526 } 00527 00528 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsEqual( 00529 LPMONIKER iface, 00530 IMoniker* pmkOtherMoniker) 00531 { 00532 FIXME("(%p)->(%p): stub\n", iface, pmkOtherMoniker); 00533 00534 return E_NOTIMPL; 00535 } 00536 00537 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Hash( 00538 LPMONIKER iface, 00539 DWORD* pdwHash) 00540 { 00541 TRACE("(%p)->(%p)\n", iface, pdwHash); 00542 00543 *pdwHash = 0; 00544 00545 return S_OK; 00546 } 00547 00548 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsRunning( 00549 LPMONIKER iface, 00550 IBindCtx* pbc, 00551 IMoniker* pmkToLeft, 00552 IMoniker* pmkNewlyRunning) 00553 { 00554 FIXME("(%p)->(%p, %p, %p): stub\n", iface, pbc, pmkToLeft, pmkNewlyRunning); 00555 00556 return S_FALSE; 00557 } 00558 00559 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetTimeOfLastChange( 00560 LPMONIKER iface, 00561 IBindCtx* pbc, 00562 IMoniker* pmkToLeft, 00563 FILETIME* pFileTime) 00564 { 00565 TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, pFileTime); 00566 00567 pFileTime->dwLowDateTime = 0xFFFFFFFF; 00568 pFileTime->dwHighDateTime = 0x7FFFFFFF; 00569 00570 return MK_E_UNAVAILABLE; 00571 } 00572 00573 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Inverse( 00574 LPMONIKER iface, 00575 IMoniker** ppmk) 00576 { 00577 TRACE("(%p)->(%p)\n", iface, ppmk); 00578 00579 *ppmk = NULL; 00580 00581 return MK_E_NOINVERSE; 00582 } 00583 00584 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_CommonPrefixWith( 00585 LPMONIKER iface, 00586 IMoniker* pmkOtherMoniker, 00587 IMoniker** ppmkPrefix) 00588 { 00589 TRACE("(%p)->(%p, %p)\n", iface, pmkOtherMoniker, ppmkPrefix); 00590 00591 *ppmkPrefix = NULL; 00592 00593 return MK_E_NOPREFIX; 00594 } 00595 00596 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo( 00597 LPMONIKER iface, 00598 IMoniker* pmkOther, 00599 IMoniker** ppmkRelPath) 00600 { 00601 TRACE("(%p)->(%p, %p)\n", iface, pmkOther, ppmkRelPath); 00602 00603 *ppmkRelPath = pmkOther; 00604 00605 return MK_S_HIM; 00606 } 00607 00608 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName( 00609 LPMONIKER iface, 00610 IBindCtx* pbc, 00611 IMoniker* pmkToLeft, 00612 LPOLESTR* ppszDisplayName) 00613 { 00614 MediaCatMoniker *This = (MediaCatMoniker *)iface; 00615 WCHAR wszBuffer[MAX_PATH]; 00616 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; 00617 LONG received = sizeof(wszFriendlyName); 00618 00619 TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, ppszDisplayName); 00620 00621 *ppszDisplayName = NULL; 00622 00623 /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */ 00624 if (RegQueryValueW(This->hkey, wszFriendlyName, wszBuffer, &received) == ERROR_SUCCESS) 00625 { 00626 *ppszDisplayName = CoTaskMemAlloc(received); 00627 strcpyW(*ppszDisplayName, wszBuffer); 00628 return S_OK; 00629 } 00630 00631 return E_FAIL; 00632 } 00633 00634 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ParseDisplayName( 00635 LPMONIKER iface, 00636 IBindCtx* pbc, 00637 IMoniker* pmkToLeft, 00638 LPOLESTR pszDisplayName, 00639 ULONG* pchEaten, 00640 IMoniker** ppmkOut) 00641 { 00642 FIXME("(%p)->(%p, %p, %s, %p, %p)\n", iface, pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut); 00643 00644 *pchEaten = 0; 00645 *ppmkOut = NULL; 00646 00647 return MK_E_SYNTAX; 00648 } 00649 00650 static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsSystemMoniker( 00651 LPMONIKER iface, 00652 DWORD* pdwMksys) 00653 { 00654 TRACE("(%p)->(%p)\n", iface, pdwMksys); 00655 00656 return S_FALSE; 00657 } 00658 00659 static const IMonikerVtbl IMoniker_Vtbl = 00660 { 00661 DEVENUM_IMediaCatMoniker_QueryInterface, 00662 DEVENUM_IMediaCatMoniker_AddRef, 00663 DEVENUM_IMediaCatMoniker_Release, 00664 DEVENUM_IMediaCatMoniker_GetClassID, 00665 DEVENUM_IMediaCatMoniker_IsDirty, 00666 DEVENUM_IMediaCatMoniker_Load, 00667 DEVENUM_IMediaCatMoniker_Save, 00668 DEVENUM_IMediaCatMoniker_GetSizeMax, 00669 DEVENUM_IMediaCatMoniker_BindToObject, 00670 DEVENUM_IMediaCatMoniker_BindToStorage, 00671 DEVENUM_IMediaCatMoniker_Reduce, 00672 DEVENUM_IMediaCatMoniker_ComposeWith, 00673 DEVENUM_IMediaCatMoniker_Enum, 00674 DEVENUM_IMediaCatMoniker_IsEqual, 00675 DEVENUM_IMediaCatMoniker_Hash, 00676 DEVENUM_IMediaCatMoniker_IsRunning, 00677 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange, 00678 DEVENUM_IMediaCatMoniker_Inverse, 00679 DEVENUM_IMediaCatMoniker_CommonPrefixWith, 00680 DEVENUM_IMediaCatMoniker_RelativePathTo, 00681 DEVENUM_IMediaCatMoniker_GetDisplayName, 00682 DEVENUM_IMediaCatMoniker_ParseDisplayName, 00683 DEVENUM_IMediaCatMoniker_IsSystemMoniker 00684 }; 00685 00686 MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) 00687 { 00688 MediaCatMoniker * pMoniker = NULL; 00689 pMoniker = CoTaskMemAlloc(sizeof(MediaCatMoniker)); 00690 if (!pMoniker) 00691 return NULL; 00692 00693 pMoniker->lpVtbl = &IMoniker_Vtbl; 00694 pMoniker->ref = 0; 00695 pMoniker->hkey = NULL; 00696 00697 DEVENUM_IMediaCatMoniker_AddRef((LPMONIKER)pMoniker); 00698 00699 DEVENUM_LockModule(); 00700 00701 return pMoniker; 00702 } 00703 00704 /********************************************************************** 00705 * DEVENUM_IEnumMoniker_QueryInterface (also IUnknown) 00706 */ 00707 static HRESULT WINAPI DEVENUM_IEnumMoniker_QueryInterface( 00708 LPENUMMONIKER iface, 00709 REFIID riid, 00710 LPVOID *ppvObj) 00711 { 00712 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00713 00714 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj); 00715 00716 if (This == NULL || ppvObj == NULL) return E_POINTER; 00717 00718 if (IsEqualGUID(riid, &IID_IUnknown) || 00719 IsEqualGUID(riid, &IID_IEnumMoniker)) 00720 { 00721 *ppvObj = iface; 00722 DEVENUM_IEnumMoniker_AddRef(iface); 00723 return S_OK; 00724 } 00725 00726 FIXME("- no interface IID: %s\n", debugstr_guid(riid)); 00727 return E_NOINTERFACE; 00728 } 00729 00730 /********************************************************************** 00731 * DEVENUM_IEnumMoniker_AddRef (also IUnknown) 00732 */ 00733 static ULONG WINAPI DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface) 00734 { 00735 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00736 ULONG ref = InterlockedIncrement(&This->ref); 00737 00738 TRACE("(%p)->() AddRef from %d\n", iface, ref - 1); 00739 00740 return ref; 00741 } 00742 00743 /********************************************************************** 00744 * DEVENUM_IEnumMoniker_Release (also IUnknown) 00745 */ 00746 static ULONG WINAPI DEVENUM_IEnumMoniker_Release(LPENUMMONIKER iface) 00747 { 00748 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00749 ULONG ref = InterlockedDecrement(&This->ref); 00750 00751 TRACE("(%p)->() Release from %d\n", iface, ref + 1); 00752 00753 if (!ref) 00754 { 00755 RegCloseKey(This->hkey); 00756 CoTaskMemFree(This); 00757 DEVENUM_UnlockModule(); 00758 return 0; 00759 } 00760 return ref; 00761 } 00762 00763 static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched) 00764 { 00765 WCHAR buffer[MAX_PATH + 1]; 00766 LONG res; 00767 ULONG fetched = 0; 00768 MediaCatMoniker * pMoniker; 00769 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00770 00771 TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); 00772 00773 while (fetched < celt) 00774 { 00775 res = RegEnumKeyW(This->hkey, This->index, buffer, sizeof(buffer) / sizeof(WCHAR)); 00776 if (res != ERROR_SUCCESS) 00777 { 00778 break; 00779 } 00780 pMoniker = DEVENUM_IMediaCatMoniker_Construct(); 00781 if (!pMoniker) 00782 return E_OUTOFMEMORY; 00783 00784 if (RegOpenKeyW(This->hkey, buffer, &pMoniker->hkey) != ERROR_SUCCESS) 00785 { 00786 DEVENUM_IMediaCatMoniker_Release((LPMONIKER)pMoniker); 00787 break; 00788 } 00789 rgelt[fetched] = (LPMONIKER)pMoniker; 00790 fetched++; 00791 } 00792 00793 This->index += fetched; 00794 00795 TRACE("-- fetched %d\n", fetched); 00796 00797 if (pceltFetched) 00798 *pceltFetched = fetched; 00799 00800 if (fetched != celt) 00801 return S_FALSE; 00802 else 00803 return S_OK; 00804 } 00805 00806 static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(LPENUMMONIKER iface, ULONG celt) 00807 { 00808 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00809 DWORD subKeys; 00810 00811 TRACE("(%p)->(%d)\n", iface, celt); 00812 00813 /* Before incrementing, check if there are any more values to run thru. 00814 Some programs use the Skip() function to get the amount of devices */ 00815 if(RegQueryInfoKeyW(This->hkey, NULL, NULL, NULL, &subKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 00816 { 00817 return S_FALSE; 00818 } 00819 if((This->index + celt) >= subKeys) 00820 { 00821 return S_FALSE; 00822 } 00823 00824 This->index += celt; 00825 00826 return S_OK; 00827 } 00828 00829 static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(LPENUMMONIKER iface) 00830 { 00831 EnumMonikerImpl *This = (EnumMonikerImpl *)iface; 00832 00833 TRACE("(%p)->()\n", iface); 00834 00835 This->index = 0; 00836 00837 return S_OK; 00838 } 00839 00840 static HRESULT WINAPI DEVENUM_IEnumMoniker_Clone(LPENUMMONIKER iface, IEnumMoniker ** ppenum) 00841 { 00842 FIXME("(%p)->(%p): stub\n", iface, ppenum); 00843 00844 return E_NOTIMPL; 00845 } 00846 00847 /********************************************************************** 00848 * IEnumMoniker_Vtbl 00849 */ 00850 static const IEnumMonikerVtbl IEnumMoniker_Vtbl = 00851 { 00852 DEVENUM_IEnumMoniker_QueryInterface, 00853 DEVENUM_IEnumMoniker_AddRef, 00854 DEVENUM_IEnumMoniker_Release, 00855 DEVENUM_IEnumMoniker_Next, 00856 DEVENUM_IEnumMoniker_Skip, 00857 DEVENUM_IEnumMoniker_Reset, 00858 DEVENUM_IEnumMoniker_Clone 00859 }; 00860 00861 HRESULT DEVENUM_IEnumMoniker_Construct(HKEY hkey, IEnumMoniker ** ppEnumMoniker) 00862 { 00863 EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); 00864 if (!pEnumMoniker) 00865 return E_OUTOFMEMORY; 00866 00867 pEnumMoniker->lpVtbl = &IEnumMoniker_Vtbl; 00868 pEnumMoniker->ref = 1; 00869 pEnumMoniker->index = 0; 00870 pEnumMoniker->hkey = hkey; 00871 00872 *ppEnumMoniker = (IEnumMoniker *)pEnumMoniker; 00873 00874 DEVENUM_LockModule(); 00875 00876 return S_OK; 00877 } Generated on Fri May 25 2012 04:19:26 for ReactOS by
1.7.6.1
|