/******************************************************************************* * GAMEUX_ParseGameDefinition * * Helper function, loads data from given XML element into fields of GAME_DATA * structure * * Parameters: * lpXMLGameDefinitionElement [I] Game Definition XML element * GameData [O] structure where data loaded from * XML element will be stored in */ static HRESULT GAMEUX_ParseGameDefinition( IXMLDOMElement *gdElement, struct GAMEUX_GAME_DATA *GameData) { static const WCHAR sGameId[] = {'g','a','m','e','I','D',0}; HRESULT hr = S_OK; BSTR bstrAttribute; VARIANT variant; IXMLDOMNodeList *childrenList; IXMLDOMNode *nextNode; IXMLDOMElement *nextElement; TRACE("(%p, %p)\n", gdElement, GameData); bstrAttribute = SysAllocString(sGameId); if(!bstrAttribute) hr = E_OUTOFMEMORY; hr = IXMLDOMElement_getAttribute(gdElement, bstrAttribute, &variant); if(SUCCEEDED(hr)) { hr = ( GUIDFromStringW(V_BSTR(&variant), &GameData->guidApplicationId)==TRUE ? S_OK : E_FAIL); SysFreeString(V_BSTR(&variant)); } SysFreeString(bstrAttribute); /* browse subnodes */ if(SUCCEEDED(hr)) hr = IXMLDOMElement_get_childNodes(gdElement, &childrenList); if(SUCCEEDED(hr)) { do { hr = IXMLDOMNodeList_nextNode(childrenList, &nextNode); if(hr == S_OK) { hr = IXMLDOMNode_QueryInterface(nextNode, &IID_IXMLDOMElement, (LPVOID*)&nextElement); if(SUCCEEDED(hr)) { hr = GAMEUX_ProcessGameDefinitionElement(nextElement, GameData); IXMLDOMElement_Release(nextElement); } IXMLDOMElement_Release(nextNode); } } while(hr == S_OK); hr = S_OK; IXMLDOMNodeList_Release(childrenList); } return hr; }
/******************************************************************************* * GAMEUX_FindGameInstanceId * * Internal helper function. Description available in gameux_private.h file */ HRESULT GAMEUX_FindGameInstanceId( LPCWSTR sGDFBinaryPath, GAME_INSTALL_SCOPE installScope, GUID* pInstanceId) { static const WCHAR sConfigGDFBinaryPath[] = {'C','o','n','f','i','g','G','D','F','B','i','n','a','r','y','P','a','t','h',0}; HRESULT hr; BOOL found = FALSE; LPWSTR lpRegistryPath = NULL; HKEY hRootKey; DWORD dwSubKeys, dwSubKeyLen, dwMaxSubKeyLen, i; LPWSTR lpName = NULL, lpValue = NULL; hr = GAMEUX_buildGameRegistryPath(installScope, NULL, &lpRegistryPath); if(SUCCEEDED(hr)) /* enumerate all subkeys of received one and search them for value "ConfigGGDFBinaryPath" */ hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpRegistryPath, 0, KEY_READ | KEY_WOW64_64KEY, &hRootKey)); if(SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RegQueryInfoKeyW(hRootKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL)); if(SUCCEEDED(hr)) { ++dwMaxSubKeyLen; /* for string terminator */ lpName = CoTaskMemAlloc(dwMaxSubKeyLen*sizeof(WCHAR)); if(!lpName) hr = E_OUTOFMEMORY; } if(SUCCEEDED(hr)) { for(i=0; i<dwSubKeys && !found; ++i) { dwSubKeyLen = dwMaxSubKeyLen; hr = HRESULT_FROM_WIN32(RegEnumKeyExW(hRootKey, i, lpName, &dwSubKeyLen, NULL, NULL, NULL, NULL)); if(SUCCEEDED(hr)) hr = GAMEUX_LoadRegistryString(hRootKey, lpName, sConfigGDFBinaryPath, &lpValue); if(SUCCEEDED(hr)) if(lstrcmpW(lpValue, sGDFBinaryPath)==0) { /* key found, let's copy instance id and exit */ hr = (GUIDFromStringW(lpName, pInstanceId) ? S_OK : E_FAIL); found = TRUE; } HeapFree(GetProcessHeap(), 0, lpValue); } } HeapFree(GetProcessHeap(), 0, lpName); RegCloseKey(hRootKey); } HeapFree(GetProcessHeap(), 0, lpRegistryPath); if((SUCCEEDED(hr) && !found) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) hr = S_FALSE; return hr; }
UINT WINAPI SHExplorerParseCmdLine(ExplorerCommandLineParseResults * pInfo) { WCHAR strField[MAX_PATH]; WCHAR strDir[MAX_PATH]; PCWSTR strCmdLine = GetCommandLineW(); PCWSTR strFieldArray = PathGetArgsW(strCmdLine); if (!*strFieldArray) { pInfo->dwFlags = 9; pInfo->pidlPath = _GetDocumentsPidl(); if (!pInfo->pidlPath) { GetWindowsDirectoryW(strDir, MAX_PATH); PathStripToRootW(strDir); pInfo->pidlPath = ILCreateFromPathW(strDir); } return (LONG) (pInfo->pidlPath); } PCWSTR strNextArg = _FindFirstField(strFieldArray); BOOL hasNext = TRUE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); while (TRUE) { // Basic flags-only params first if (!StrCmpIW(strField, L"/N")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_N | SH_EXPLORER_CMDLINE_FLAG_ONE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/S")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_S; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/E")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_E; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SELECT")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SELECT; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/NOUI")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_NOUI; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"-embedding")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_EMBED; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SEPARATE")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SEPARATE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/INPROC")) { // No idea what Inproc is supposed to do, but it gets a GUID, and parses it. TRACE("CmdLine Parser: Found %S flag\n", strField); if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); if (!GUIDFromStringW(strField, &(pInfo->guidInproc))) return FALSE; pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_INPROC; TRACE("CmdLine Parser: Parsed /INPROC flag. dwFlags=%08lx, guidInproc=%S\n", pInfo->dwFlags, strField); } else if (!StrCmpIW(strField, L"/ROOT")) { LPITEMIDLIST pidlRoot = NULL; // The window should be rooted TRACE("CmdLine Parser: Found %S flag\n", strField); if (!pInfo->pidlPath) return FALSE; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); // Root may be a pidl if (!StrCmpIW(strField, L"/IDLIST")) { if (hasNext) { hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } pidlRoot = _ILReadFromSharedMemory(strField); } else { // Or just a path string _ParsePathToPidl(strField, &pidlRoot); } pInfo->pidlRoot = pidlRoot; // The root defaults to the desktop if (!pidlRoot) { if (FAILED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &(pInfo->pidlRoot)))) pInfo->pidlRoot = NULL; } // TODO: Create rooted PIDL from pInfo->pidlPath and pInfo->pidlRoot TRACE("CmdLine Parser: Parsed /ROOT flag. dwFlags=%08lx, pidlRoot=%p\n", pInfo->dwFlags, pInfo->pidlRoot); } else { // Anything else is part of the target path to browse to TRACE("CmdLine Parser: Found target path %S\n", strField); // Which can be a shared-memory itemidlist if (!StrCmpIW(strField, L"/IDLIST")) { LPITEMIDLIST pidlArg; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); pidlArg = _ILReadFromSharedMemory(strField); if (!pidlArg) return FALSE; if (pInfo->pidlPath) ILFree(pInfo->pidlPath); pInfo->pidlPath = pidlArg; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // Or just a plain old string. WCHAR szPath[MAX_PATH]; DWORD result = GetFullPathNameW(strField, _countof(szPath), szPath, NULL); if (result != 0 && result <= _countof(szPath) && PathFileExistsW(szPath)) StringCchCopyW(strField, _countof(strField), szPath); LPITEMIDLIST pidlPath = ILCreateFromPathW(strField); pInfo->pidlPath = pidlPath; if (pidlPath) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_IDLIST; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // The path could not be parsed into an ID List, // so pass it on as a plain string. PWSTR field = StrDupW(strField); pInfo->strPath = field; if (field) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_STRING; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, strPath=%S\n", pInfo->dwFlags, field); } } } } if (!hasNext) break; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } return TRUE; }