Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenshellole.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
1.7.6.1
|