/************************************************************************** * ISF_MyComputer_fnParseDisplayName */ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface, HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) { IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface); HRESULT hr = E_INVALIDARG; LPCWSTR szNext = NULL; WCHAR szElement[MAX_PATH]; LPITEMIDLIST pidlTemp = NULL; CLSID clsid; TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes); *ppidl = 0; if (pchEaten) *pchEaten = 0; /* strange but like the original */ /* handle CLSID paths */ if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') { szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); TRACE ("-- element: %s\n", debugstr_w (szElement)); SHCLSIDFromStringW (szElement + 2, &clsid); pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } /* do we have an absolute path name ? */ else if (PathGetDriveNumberW (lpszDisplayName) >= 0 && lpszDisplayName[2] == (WCHAR) '\\') { szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); /* make drive letter uppercase to enable PIDL comparison */ szElement[0] = toupper(szElement[0]); pidlTemp = _ILCreateDrive (szElement); } if (szNext && *szNext) { hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); } else { if (pdwAttributes && *pdwAttributes) SHELL32_GetItemAttributes ((IShellFolder*)&This->IShellFolder2_iface, pidlTemp, pdwAttributes); hr = S_OK; } *ppidl = pidlTemp; TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr); return hr; }
/************************************************************************** * ISF_Desktop_fnParseDisplayName * * NOTES * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds * to MyComputer */ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface, HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) { IDesktopFolderImpl *This = impl_from_IShellFolder2(iface); IShellFolder *shell_folder = (IShellFolder*)iface; WCHAR szElement[MAX_PATH]; LPCWSTR szNext = NULL; LPITEMIDLIST pidlTemp = NULL; PARSEDURLW urldata; HRESULT hr = S_OK; CLSID clsid; TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes); if (!ppidl) return E_INVALIDARG; *ppidl = 0; if (!lpszDisplayName) return E_INVALIDARG; if (pchEaten) *pchEaten = 0; /* strange but like the original */ urldata.cbSize = sizeof(urldata); if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') { szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); TRACE ("-- element: %s\n", debugstr_w (szElement)); SHCLSIDFromStringW (szElement + 2, &clsid); pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } else if (PathGetDriveNumberW (lpszDisplayName) >= 0) { /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */ if (UNIXFS_is_rooted_at_desktop()) pidlTemp = _ILCreateGuid(PT_GUID, &CLSID_UnixDosFolder); else pidlTemp = _ILCreateMyComputer (); szNext = lpszDisplayName; } else if (PathIsUNCW(lpszDisplayName)) { pidlTemp = _ILCreateNetwork(); szNext = lpszDisplayName; } else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) ) { *ppidl = pidlTemp; return S_OK; } else if (SUCCEEDED(ParseURLW(lpszDisplayName, &urldata))) { if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */ { TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix)); SHCLSIDFromStringW (urldata.pszSuffix+2, &clsid); pidlTemp = _ILCreateGuid (PT_GUID, &clsid); } else return IEParseDisplayNameWithBCW(CP_ACP,lpszDisplayName,pbc,ppidl); } else { /* it's a filesystem path on the desktop. Let a FSFolder parse it */ if (*lpszDisplayName) { if (*lpszDisplayName == '/') { /* UNIX paths should be parsed by unixfs */ IShellFolder *unixFS; hr = UnixFolder_Constructor(NULL, &IID_IShellFolder, (LPVOID*)&unixFS); if (SUCCEEDED(hr)) { hr = IShellFolder_ParseDisplayName(unixFS, NULL, NULL, lpszDisplayName, NULL, &pidlTemp, NULL); IShellFolder_Release(unixFS); } } else { /* build a complete path to create a simple pidl */ WCHAR szPath[MAX_PATH]; LPWSTR pathPtr; lstrcpynW(szPath, This->sPathTarget, MAX_PATH); pathPtr = PathAddBackslashW(szPath); if (pathPtr) { lstrcpynW(pathPtr, lpszDisplayName, MAX_PATH - (pathPtr - szPath)); hr = _ILCreateFromPathW(szPath, &pidlTemp); } else { /* should never reach here, but for completeness */ hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); } } } else pidlTemp = _ILCreateMyComputer(); szNext = NULL; } if (SUCCEEDED(hr) && pidlTemp) { if (szNext && *szNext) { hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); } else { if (pdwAttributes && *pdwAttributes) hr = SHELL32_GetItemAttributes(shell_folder, pidlTemp, pdwAttributes); } } *ppidl = pidlTemp; TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr); return hr; }
EXTERN_C DWORD WINAPI SHCLSIDFromStringAW (LPCVOID clsid, CLSID *id) { if (SHELL_OsIsUnicode()) return SHCLSIDFromStringW ((LPCWSTR)clsid, id); return SHCLSIDFromStringA ((LPCSTR)clsid, id); }
DWORD WINAPI SHCLSIDFromStringAW (LPCVOID clsid, CLSID *id) { if (SHELL_OsIsUnicode()) return SHCLSIDFromStringW (clsid, id); return SHCLSIDFromStringA (clsid, id); }
/************************************************************************* * SHCoCreateInstance [SHELL32.102] * * Equivalent to CoCreateInstance. Under Windows 9x this function could sometimes * use the shell32 built-in "mini-COM" without the need to load ole32.dll - see * SHLoadOLE for details. * * Under wine if a "LoadWithoutCOM" value is present or the object resides in * shell32.dll the function will load the object manually without the help of ole32 * * NOTES * exported by ordinal * * SEE ALSO * CoCreateInstace, SHLoadOLE */ HRESULT WINAPI SHCoCreateInstance( LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv) { DWORD hres; IID iid; const CLSID * myclsid = clsid; WCHAR sKeyName[MAX_PATH]; const WCHAR sCLSID[7] = {'C','L','S','I','D','\\','\0'}; WCHAR sClassID[60]; const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'}; const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'}; WCHAR sDllPath[MAX_PATH]; HKEY hKey = 0; DWORD dwSize; IClassFactory * pcf = NULL; if(!ppv) return E_POINTER; *ppv=NULL; /* if the clsid is a string, convert it */ if (!clsid) { if (!aclsid) return REGDB_E_CLASSNOTREG; SHCLSIDFromStringW(aclsid, &iid); myclsid = &iid; } TRACE("(%p,%s,unk:%p,%s,%p)\n", aclsid,shdebugstr_guid(myclsid),pUnkOuter,shdebugstr_guid(refiid),ppv); if (SUCCEEDED(DllGetClassObject(myclsid, &IID_IClassFactory,(LPVOID*)&pcf))) { hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv); IClassFactory_Release(pcf); goto end; } /* we look up the dll path in the registry */ SHStringFromGUIDW(myclsid, sClassID, sizeof(sClassID)/sizeof(WCHAR)); lstrcpyW(sKeyName, sCLSID); lstrcatW(sKeyName, sClassID); lstrcatW(sKeyName, sInProcServer32); if (RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) return E_ACCESSDENIED; /* if a special registry key is set, we load a shell extension without help of OLE32 */ if (!SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0)) { /* load an external dll without ole32 */ HANDLE hLibrary; typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv); DllGetClassObjectFunc DllGetClassObject; dwSize = sizeof(sDllPath); SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize ); if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) { ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath)); hres = E_ACCESSDENIED; goto end; } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) { ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(sDllPath)); FreeLibrary( hLibrary ); hres = E_ACCESSDENIED; goto end; } else if (FAILED(hres = DllGetClassObject(myclsid, &IID_IClassFactory, (LPVOID*)&pcf))) { TRACE("GetClassObject failed 0x%08x\n", hres); goto end; } hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv); IClassFactory_Release(pcf); } else { /* load an external dll in the usual way */ hres = CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv); } end: if (hKey) RegCloseKey(hKey); if(hres!=S_OK) { ERR("failed (0x%08x) to create CLSID:%s IID:%s\n", hres, shdebugstr_guid(myclsid), shdebugstr_guid(refiid)); ERR("class not found in registry\n"); } TRACE("-- instance: %p\n",*ppv); return hres; }