ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mediacatenum.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.