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

shellole.cpp
Go to the documentation of this file.
00001 /*
00002  *    handling of SHELL32.DLL OLE-Objects
00003  *
00004  *    Copyright 1997    Marcus Meissner
00005  *    Copyright 1998    Juergen Schmied  <juergen.schmied@metronet.de>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <precomp.h>
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00025 
00026 extern HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
00027 
00028 static const WCHAR sShell32[12] = {'S','H','E','L','L','3','2','.','D','L','L','\0'};
00029 
00030 /**************************************************************************
00031  * Default ClassFactory types
00032  */
00033 typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
00034 HRESULT IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInst, IClassFactory **theFactory);
00035 
00036 /* FIXME: this should be SHLWAPI.24 since we can't yet import by ordinal */
00037 
00038 DWORD WINAPI __SHGUIDToStringW (REFGUID guid, LPWSTR str)
00039 {
00040     WCHAR sFormat[52] = {'{','%','0','8','l','x','-','%','0','4',
00041                  'x','-','%','0','4','x','-','%','0','2',
00042                          'x','%','0','2','x','-','%','0','2','x',
00043              '%','0','2','x','%','0','2','x','%','0',
00044              '2','x','%','0','2','x','%','0','2','x',
00045              '}','\0'};
00046 
00047     return swprintf ( str, sFormat,
00048              guid.Data1, guid.Data2, guid.Data3,
00049              guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
00050              guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
00051 
00052 }
00053 
00054 /*************************************************************************
00055  * SHCoCreateInstance [SHELL32.102]
00056  *
00057  * Equivalent to CoCreateInstance. Under Windows 9x this function could sometimes
00058  * use the shell32 built-in "mini-COM" without the need to load ole32.dll - see
00059  * SHLoadOLE for details.
00060  *
00061  * Under wine if a "LoadWithoutCOM" value is present or the object resides in
00062  * shell32.dll the function will load the object manually without the help of ole32
00063  *
00064  * NOTES
00065  *     exported by ordinal
00066  *
00067  * SEE ALSO
00068  *     CoCreateInstace, SHLoadOLE
00069  */
00070 HRESULT WINAPI SHCoCreateInstance(
00071     LPCWSTR aclsid,
00072     const CLSID *clsid,
00073     LPUNKNOWN pUnkOuter,
00074     REFIID refiid,
00075     LPVOID *ppv)
00076 {
00077     DWORD    hres;
00078     CLSID    iid;
00079     const    CLSID * myclsid = clsid;
00080     WCHAR    sKeyName[MAX_PATH];
00081     const    WCHAR sCLSID[7] = {'C','L','S','I','D','\\','\0'};
00082     WCHAR    sClassID[60];
00083     const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
00084     const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
00085     WCHAR    sDllPath[MAX_PATH];
00086     HKEY    hKey;
00087     DWORD    dwSize;
00088     BOOLEAN bLoadFromShell32 = FALSE;
00089     BOOLEAN bLoadWithoutCOM = FALSE;
00090     CComPtr<IClassFactory>        pcf;
00091 
00092     if(!ppv) return E_POINTER;
00093     *ppv=NULL;
00094 
00095     /* if the clsid is a string, convert it */
00096     if (!clsid)
00097     {
00098       if (!aclsid) return REGDB_E_CLASSNOTREG;
00099       CLSIDFromString((LPOLESTR)aclsid, &iid);
00100       myclsid = &iid;
00101     }
00102 
00103     TRACE("(%p,%s,unk:%p,%s,%p)\n",
00104         aclsid, shdebugstr_guid(myclsid), pUnkOuter, shdebugstr_guid(&refiid), ppv);
00105 
00106     /* we look up the dll path in the registry */
00107         __SHGUIDToStringW(*myclsid, sClassID);
00108     wcscpy(sKeyName, sCLSID);
00109     wcscat(sKeyName, sClassID);
00110     wcscat(sKeyName, sInProcServer32);
00111 
00112     if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) {
00113         dwSize = sizeof(sDllPath);
00114         SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );
00115 
00116         /* if a special registry key is set, we load a shell extension without help of OLE32 */
00117         bLoadWithoutCOM = (ERROR_SUCCESS == SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0));
00118 
00119         /* if the com object is inside shell32, omit use of ole32 */
00120         bLoadFromShell32 = (0==lstrcmpiW( PathFindFileNameW(sDllPath), sShell32));
00121 
00122         RegCloseKey (hKey);
00123     } else {
00124         /* since we can't find it in the registry we try internally */
00125         bLoadFromShell32 = TRUE;
00126     }
00127 
00128     TRACE("WithoutCom=%u FromShell=%u\n", bLoadWithoutCOM, bLoadFromShell32);
00129 
00130     /* now we create an instance */
00131     if (bLoadFromShell32) {
00132         if (! SUCCEEDED(DllGetClassObject(*myclsid, IID_IClassFactory, (LPVOID*)&pcf))) {
00133             ERR("LoadFromShell failed for CLSID=%s\n", shdebugstr_guid(myclsid));
00134         }
00135     } else if (bLoadWithoutCOM) {
00136 
00137         /* load an external dll without ole32 */
00138         HINSTANCE hLibrary;
00139         typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
00140         DllGetClassObjectFunc DllGetClassObject;
00141 
00142         if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
00143             ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
00144         hres = E_ACCESSDENIED;
00145             goto end;
00146         } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
00147             ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(sDllPath));
00148             FreeLibrary( hLibrary );
00149         hres = E_ACCESSDENIED;
00150             goto end;
00151         } else if (! SUCCEEDED(hres = DllGetClassObject(*myclsid, IID_IClassFactory, (LPVOID*)&pcf))) {
00152             TRACE("GetClassObject failed 0x%08x\n", hres);
00153             goto end;
00154         }
00155 
00156     } else {
00157 
00158         /* load an external dll in the usual way */
00159         hres = CoCreateInstance(*myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
00160         goto end;
00161     }
00162 
00163     /* here we should have a ClassFactory */
00164     if (!pcf) return E_ACCESSDENIED;
00165 
00166     hres = pcf->CreateInstance(pUnkOuter, refiid, ppv);
00167 end:
00168     if(hres!=S_OK)
00169     {
00170       ERR("failed (0x%08x) to create CLSID:%s IID:%s\n",
00171               hres, shdebugstr_guid(myclsid), shdebugstr_guid(&refiid));
00172       ERR("class not found in registry\n");
00173     }
00174 
00175     TRACE("-- instance: %p\n",*ppv);
00176     return hres;
00177 }
00178 
00179 /*************************************************************************
00180  * SHCLSIDFromString                [SHELL32.147]
00181  *
00182  * Under Windows 9x this was an ANSI version of CLSIDFromString. It also allowed
00183  * to avoid dependency on ole32.dll (see SHLoadOLE for details).
00184  *
00185  * Under Windows NT/2000/XP this is equivalent to CLSIDFromString
00186  *
00187  * NOTES
00188  *     exported by ordinal
00189  *
00190  * SEE ALSO
00191  *     CLSIDFromString, SHLoadOLE
00192  */
00193 DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
00194 {
00195     WCHAR buffer[40];
00196     TRACE("(%p(%s) %p)\n", clsid, clsid, id);
00197     if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
00198         return CO_E_CLASSSTRING;
00199     return CLSIDFromString( buffer, id );
00200 }
00201 
00202 DWORD WINAPI SHCLSIDFromStringW (LPCWSTR clsid, CLSID *id)
00203 {
00204     TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
00205     return CLSIDFromString((LPWSTR)clsid, id);
00206 }
00207 
00208 EXTERN_C DWORD WINAPI SHCLSIDFromStringAW (LPCVOID clsid, CLSID *id)
00209 {
00210     if (SHELL_OsIsUnicode())
00211       return SHCLSIDFromStringW ((LPCWSTR)clsid, id);
00212     return SHCLSIDFromStringA ((LPCSTR)clsid, id);
00213 }
00214 
00215 /*************************************************************************
00216  *             SHGetMalloc            [SHELL32.@]
00217  *
00218  * Equivalent to CoGetMalloc(MEMCTX_TASK, ...). Under Windows 9x this function
00219  * could use the shell32 built-in "mini-COM" without the need to load ole32.dll -
00220  * see SHLoadOLE for details.
00221  *
00222  * PARAMS
00223  *  lpmal [O] Destination for IMalloc interface.
00224  *
00225  * RETURNS
00226  *  Success: S_OK. lpmal contains the shells IMalloc interface.
00227  *  Failure. An HRESULT error code.
00228  *
00229  * SEE ALSO
00230  *  CoGetMalloc, SHLoadOLE
00231  */
00232 HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
00233 {
00234     TRACE("(%p)\n", lpmal);
00235     return CoGetMalloc(MEMCTX_TASK, lpmal);
00236 }
00237 
00238 /*************************************************************************
00239  * SHAlloc                    [SHELL32.196]
00240  *
00241  * Equivalent to CoTaskMemAlloc. Under Windows 9x this function could use
00242  * the shell32 built-in "mini-COM" without the need to load ole32.dll -
00243  * see SHLoadOLE for details.
00244  *
00245  * NOTES
00246  *     exported by ordinal
00247  *
00248  * SEE ALSO
00249  *     CoTaskMemAlloc, SHLoadOLE
00250  */
00251 LPVOID WINAPI SHAlloc(SIZE_T len)
00252 {
00253     LPVOID ret;
00254 
00255     ret = CoTaskMemAlloc(len);
00256     TRACE("%u bytes at %p\n",len, ret);
00257     return ret;
00258 }
00259 
00260 /*************************************************************************
00261  * SHFree                    [SHELL32.195]
00262  *
00263  * Equivalent to CoTaskMemFree. Under Windows 9x this function could use
00264  * the shell32 built-in "mini-COM" without the need to load ole32.dll -
00265  * see SHLoadOLE for details.
00266  *
00267  * NOTES
00268  *     exported by ordinal
00269  *
00270  * SEE ALSO
00271  *     CoTaskMemFree, SHLoadOLE
00272  */
00273 void WINAPI SHFree(LPVOID pv)
00274 {
00275     TRACE("%p\n",pv);
00276     CoTaskMemFree(pv);
00277 }
00278 
00279 /*************************************************************************
00280  * SHGetDesktopFolder            [SHELL32.@]
00281  */
00282 HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
00283 {
00284     HRESULT    hres = S_OK;
00285     TRACE("\n");
00286 
00287     if(!psf) return E_INVALIDARG;
00288     *psf = NULL;
00289     hres = CDesktopFolder::_CreatorClass::CreateInstance(NULL, IID_IShellFolder, (void**)psf);
00290 
00291     TRACE("-- %p->(%p)\n",psf, *psf);
00292     return hres;
00293 }
00294 /**************************************************************************
00295  * Default ClassFactory Implementation
00296  *
00297  * SHCreateDefClassObject
00298  *
00299  * NOTES
00300  *  Helper function for dlls without their own classfactory.
00301  *  A generic classfactory is returned.
00302  *  When the CreateInstance of the cf is called the callback is executed.
00303  */
00304 
00305 class IDefClFImpl :
00306     public CComObjectRootEx<CComMultiThreadModelNoCS>,
00307     public IClassFactory
00308 {
00309 private:
00310     CLSID                    *rclsid;
00311     LPFNCREATEINSTANCE        lpfnCI;
00312     const IID                *riidInst;
00313     LONG                    *pcRefDll;        /* pointer to refcounter in external dll (ugrrr...) */
00314 public:
00315     IDefClFImpl();
00316     HRESULT Initialize(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInstx);
00317 
00318     // IClassFactory
00319     virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject);
00320     virtual HRESULT WINAPI LockServer(BOOL fLock);
00321 
00322 BEGIN_COM_MAP(IDefClFImpl)
00323     COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
00324 END_COM_MAP()
00325 };
00326 
00327 IDefClFImpl::IDefClFImpl()
00328 {
00329     lpfnCI = NULL;
00330     riidInst = NULL;
00331     pcRefDll = NULL;
00332     rclsid = NULL;
00333 }
00334 
00335 HRESULT IDefClFImpl::Initialize(LPFNCREATEINSTANCE lpfnCIx, PLONG pcRefDllx, const IID *riidInstx)
00336 {
00337     lpfnCI = lpfnCIx;
00338     riidInst = riidInstx;
00339     pcRefDll = pcRefDllx;
00340 
00341     if (pcRefDll)
00342         InterlockedIncrement(pcRefDll);
00343 
00344     TRACE("(%p)%s\n", this, shdebugstr_guid(riidInst));
00345     return S_OK;
00346 }
00347 
00348 /******************************************************************************
00349  * IDefClF_fnCreateInstance
00350  */
00351 HRESULT WINAPI IDefClFImpl::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
00352 {
00353     TRACE("%p->(%p,%s,%p)\n", this, pUnkOuter, shdebugstr_guid(&riid), ppvObject);
00354 
00355     *ppvObject = NULL;
00356 
00357     if (riidInst == NULL || IsEqualCLSID(riid, *riidInst) || IsEqualCLSID(riid, IID_IUnknown))
00358     {
00359         return lpfnCI(pUnkOuter, riid, ppvObject);
00360     }
00361 
00362     ERR("unknown IID requested %s\n", shdebugstr_guid(&riid));
00363     return E_NOINTERFACE;
00364 }
00365 
00366 /******************************************************************************
00367  * IDefClF_fnLockServer
00368  */
00369 HRESULT WINAPI IDefClFImpl::LockServer(BOOL fLock)
00370 {
00371     TRACE("%p->(0x%x), not implemented\n", this, fLock);
00372     return E_NOTIMPL;
00373 }
00374 
00375 /**************************************************************************
00376  *  IDefClF_fnConstructor
00377  */
00378 
00379 HRESULT IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInst, IClassFactory **theFactory)
00380 {
00381     CComObject<IDefClFImpl>                    *theClassObject;
00382     CComPtr<IClassFactory>                    result;
00383     HRESULT                                    hResult;
00384 
00385     if (theFactory == NULL)
00386         return E_POINTER;
00387     *theFactory = NULL;
00388     ATLTRY (theClassObject = new CComObject<IDefClFImpl>);
00389     if (theClassObject == NULL)
00390         return E_OUTOFMEMORY;
00391     hResult = theClassObject->QueryInterface (IID_IClassFactory, (void **)&result);
00392     if (FAILED (hResult))
00393     {
00394         delete theClassObject;
00395         return hResult;
00396     }
00397     hResult = theClassObject->Initialize (lpfnCI, pcRefDll, riidInst);
00398     if (FAILED (hResult))
00399         return hResult;
00400     *theFactory = result.Detach ();
00401     return S_OK;
00402 }
00403 
00404 /******************************************************************************
00405  * SHCreateDefClassObject            [SHELL32.70]
00406  */
00407 HRESULT WINAPI SHCreateDefClassObject(
00408     REFIID    riid,
00409     LPVOID*    ppv,
00410     LPFNCREATEINSTANCE lpfnCI,    /* [in] create instance callback entry */
00411     LPDWORD    pcRefDll,        /* [in/out] ref count of the dll */
00412     REFIID    riidInst)        /* [in] optional interface to the instance */
00413 {
00414     IClassFactory                *pcf;
00415     HRESULT                        hResult;
00416 
00417     TRACE("%s %p %p %p %s\n", shdebugstr_guid(&riid), ppv, lpfnCI, pcRefDll, shdebugstr_guid(&riidInst));
00418 
00419     if (!IsEqualCLSID(riid, IID_IClassFactory))
00420         return E_NOINTERFACE;
00421     hResult = IDefClF_fnConstructor(lpfnCI, (PLONG)pcRefDll, &riidInst, &pcf);
00422     if (FAILED(hResult))
00423         return hResult;
00424     *ppv = pcf;
00425     return NOERROR;
00426 }
00427 
00428 /*************************************************************************
00429  *  DragAcceptFiles        [SHELL32.@]
00430  */
00431 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
00432 {
00433     LONG exstyle;
00434 
00435     if( !IsWindow(hWnd) ) return;
00436     exstyle = GetWindowLongPtrA(hWnd,GWL_EXSTYLE);
00437     if (b)
00438       exstyle |= WS_EX_ACCEPTFILES;
00439     else
00440       exstyle &= ~WS_EX_ACCEPTFILES;
00441     SetWindowLongPtrA(hWnd,GWL_EXSTYLE,exstyle);
00442 }
00443 
00444 /*************************************************************************
00445  * DragFinish        [SHELL32.@]
00446  */
00447 void WINAPI DragFinish(HDROP h)
00448 {
00449     TRACE("\n");
00450     GlobalFree((HGLOBAL)h);
00451 }
00452 
00453 /*************************************************************************
00454  * DragQueryPoint        [SHELL32.@]
00455  */
00456 BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
00457 {
00458         DROPFILES *lpDropFileStruct;
00459     BOOL bRet;
00460 
00461     TRACE("\n");
00462 
00463     lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
00464 
00465         *p = lpDropFileStruct->pt;
00466     bRet = lpDropFileStruct->fNC;
00467 
00468     GlobalUnlock(hDrop);
00469     return bRet;
00470 }
00471 
00472 /*************************************************************************
00473  *  DragQueryFileA        [SHELL32.@]
00474  *  DragQueryFile         [SHELL32.@]
00475  */
00476 UINT WINAPI DragQueryFileA(
00477     HDROP hDrop,
00478     UINT lFile,
00479     LPSTR lpszFile,
00480     UINT lLength)
00481 {
00482     LPSTR lpDrop;
00483     UINT i = 0;
00484     DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
00485 
00486     TRACE("(%p, %x, %p, %u)\n",    hDrop,lFile,lpszFile,lLength);
00487 
00488     if(!lpDropFileStruct) goto end;
00489 
00490     lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
00491 
00492         if(lpDropFileStruct->fWide) {
00493             LPWSTR lpszFileW = NULL;
00494 
00495             if(lpszFile) {
00496                 lpszFileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, lLength*sizeof(WCHAR));
00497                 if(lpszFileW == NULL) {
00498                     goto end;
00499                 }
00500             }
00501             i = DragQueryFileW(hDrop, lFile, lpszFileW, lLength);
00502 
00503             if(lpszFileW) {
00504                 WideCharToMultiByte(CP_ACP, 0, lpszFileW, -1, lpszFile, lLength, 0, NULL);
00505                 HeapFree(GetProcessHeap(), 0, lpszFileW);
00506             }
00507             goto end;
00508         }
00509 
00510     while (i++ < lFile)
00511     {
00512       while (*lpDrop++); /* skip filename */
00513       if (!*lpDrop)
00514       {
00515         i = (lFile == 0xFFFFFFFF) ? i : 0;
00516         goto end;
00517       }
00518     }
00519 
00520     i = strlen(lpDrop);
00521     if (!lpszFile ) goto end;   /* needed buffer size */
00522     lstrcpynA (lpszFile, lpDrop, lLength);
00523 end:
00524     GlobalUnlock(hDrop);
00525     return i;
00526 }
00527 
00528 /*************************************************************************
00529  *  DragQueryFileW        [SHELL32.@]
00530  */
00531 UINT WINAPI DragQueryFileW(
00532     HDROP hDrop,
00533     UINT lFile,
00534     LPWSTR lpszwFile,
00535     UINT lLength)
00536 {
00537     LPWSTR lpwDrop;
00538     UINT i = 0;
00539     DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
00540 
00541     TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
00542 
00543     if(!lpDropFileStruct) goto end;
00544 
00545     lpwDrop = (LPWSTR) ((LPSTR)lpDropFileStruct + lpDropFileStruct->pFiles);
00546 
00547         if(lpDropFileStruct->fWide == FALSE) {
00548             LPSTR lpszFileA = NULL;
00549 
00550             if(lpszwFile) {
00551                 lpszFileA = (LPSTR)HeapAlloc(GetProcessHeap(), 0, lLength);
00552                 if(lpszFileA == NULL) {
00553                     goto end;
00554                 }
00555             }
00556             i = DragQueryFileA(hDrop, lFile, lpszFileA, lLength);
00557 
00558             if(lpszFileA) {
00559                 MultiByteToWideChar(CP_ACP, 0, lpszFileA, -1, lpszwFile, lLength);
00560                 HeapFree(GetProcessHeap(), 0, lpszFileA);
00561             }
00562             goto end;
00563         }
00564 
00565     i = 0;
00566     while (i++ < lFile)
00567     {
00568       while (*lpwDrop++); /* skip filename */
00569       if (!*lpwDrop)
00570       {
00571         i = (lFile == 0xFFFFFFFF) ? i : 0;
00572         goto end;
00573       }
00574     }
00575 
00576     i = wcslen(lpwDrop);
00577     if ( !lpszwFile) goto end;   /* needed buffer size */
00578     lstrcpynW (lpszwFile, lpwDrop, lLength);
00579 end:
00580     GlobalUnlock(hDrop);
00581     return i;
00582 }
00583 
00584 /*************************************************************************
00585  *  SHPropStgCreate             [SHELL32.685]
00586  */
00587 EXTERN_C HRESULT WINAPI SHPropStgCreate(IPropertySetStorage *psstg, REFFMTID fmtid,
00588          const CLSID *pclsid, DWORD grfFlags, DWORD grfMode,
00589          DWORD dwDisposition, IPropertyStorage **ppstg, UINT *puCodePage)
00590 {
00591     PROPSPEC prop;
00592     PROPVARIANT ret;
00593     HRESULT hres;
00594 
00595     TRACE("%p %s %s %x %x %x %p %p\n", psstg, debugstr_guid(&fmtid), debugstr_guid(pclsid),
00596         grfFlags, grfMode, dwDisposition, ppstg, puCodePage);
00597 
00598     hres = psstg->Open(fmtid, grfMode, ppstg);
00599 
00600      switch (dwDisposition)
00601      {
00602          case CREATE_ALWAYS:
00603              if (SUCCEEDED(hres))
00604              {
00605                  reinterpret_cast<IPropertyStorage*>(*ppstg)->Release();
00606                  hres = psstg->Delete(fmtid);
00607                  if(FAILED(hres))
00608                      return hres;
00609                  hres = E_FAIL;
00610              }
00611 
00612          case OPEN_ALWAYS:
00613          case CREATE_NEW:
00614              if (FAILED(hres))
00615                  hres = psstg->Create(fmtid, pclsid, grfFlags, grfMode, ppstg);
00616 
00617          case OPEN_EXISTING:
00618              if (FAILED(hres))
00619                  return hres;
00620 
00621              if (puCodePage)
00622              {
00623                  prop.ulKind = PRSPEC_PROPID;
00624                  prop.propid = PID_CODEPAGE;
00625                  hres = reinterpret_cast<IPropertyStorage*>(*ppstg)->ReadMultiple(1, &prop, &ret);
00626                  if (FAILED(hres) || ret.vt!=VT_I2)
00627                      *puCodePage = 0;
00628                  else
00629                      *puCodePage = ret.iVal;
00630              }
00631      }
00632 
00633      return S_OK;
00634 }
00635 
00636 /*************************************************************************
00637  *  SHPropStgReadMultiple       [SHELL32.688]
00638  */
00639 EXTERN_C HRESULT WINAPI SHPropStgReadMultiple(IPropertyStorage *pps, UINT uCodePage,
00640          ULONG cpspec, const PROPSPEC *rgpspec, PROPVARIANT *rgvar)
00641 {
00642     STATPROPSETSTG stat;
00643     HRESULT hres;
00644 
00645     FIXME("%p %u %u %p %p\n", pps, uCodePage, cpspec, rgpspec, rgvar);
00646 
00647     memset(rgvar, 0, cpspec*sizeof(PROPVARIANT));
00648     hres = pps->ReadMultiple(cpspec, rgpspec, rgvar);
00649     if (FAILED(hres))
00650         return hres;
00651 
00652     if (!uCodePage)
00653     {
00654         PROPSPEC prop;
00655         PROPVARIANT ret;
00656 
00657         prop.ulKind = PRSPEC_PROPID;
00658         prop.propid = PID_CODEPAGE;
00659         hres = pps->ReadMultiple(1, &prop, &ret);
00660         if(FAILED(hres) || ret.vt!=VT_I2)
00661             return S_OK;
00662 
00663         uCodePage = ret.iVal;
00664     }
00665 
00666     hres = pps->Stat(&stat);
00667     if (FAILED(hres))
00668         return S_OK;
00669 
00670     /* TODO: do something with codepage and stat */
00671     return S_OK;
00672 }
00673 
00674 /*************************************************************************
00675  *  SHPropStgWriteMultiple      [SHELL32.689]
00676  */
00677 EXTERN_C HRESULT WINAPI SHPropStgWriteMultiple(IPropertyStorage *pps, UINT *uCodePage,
00678          ULONG cpspec, const PROPSPEC *rgpspec, PROPVARIANT *rgvar, PROPID propidNameFirst)
00679 {
00680     STATPROPSETSTG stat;
00681     UINT codepage;
00682     HRESULT hres;
00683 
00684     FIXME("%p %p %u %p %p %d\n", pps, uCodePage, cpspec, rgpspec, rgvar, propidNameFirst);
00685 
00686     hres = pps->Stat(&stat);
00687     if (FAILED(hres))
00688         return hres;
00689 
00690     if (uCodePage && *uCodePage)
00691         codepage = *uCodePage;
00692     else
00693     {
00694         PROPSPEC prop;
00695         PROPVARIANT ret;
00696 
00697         prop.ulKind = PRSPEC_PROPID;
00698         prop.propid = PID_CODEPAGE;
00699         hres = pps->ReadMultiple(1, &prop, &ret);
00700         if (FAILED(hres))
00701             return hres;
00702         if (ret.vt!=VT_I2 || !ret.iVal)
00703             return E_FAIL;
00704 
00705         codepage = ret.iVal;
00706         if (uCodePage)
00707             *uCodePage = codepage;
00708     }
00709 
00710     /* TODO: do something with codepage and stat */
00711 
00712     hres = pps->WriteMultiple(cpspec, rgpspec, rgvar, propidNameFirst);
00713     return hres;
00714 }

Generated on Sun May 27 2012 04:26: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.