diff options
Diffstat (limited to 'src/utilcode/appxutil.cpp')
-rw-r--r-- | src/utilcode/appxutil.cpp | 820 |
1 files changed, 0 insertions, 820 deletions
diff --git a/src/utilcode/appxutil.cpp b/src/utilcode/appxutil.cpp index 759fbffcb1..5d095a4873 100644 --- a/src/utilcode/appxutil.cpp +++ b/src/utilcode/appxutil.cpp @@ -19,7 +19,6 @@ #include "shlwapi.h" // Path manipulation APIs -#ifdef FEATURE_CORECLR GVAL_IMPL(bool, g_fAppX); INDEBUG(bool g_fIsAppXAsked;) @@ -49,822 +48,3 @@ namespace AppX #endif }; -#else // FEATURE_CORECLR - -//--------------------------------------------------------------------------------------------- -// Convenience values - -#ifndef E_INSUFFICIENT_BUFFER - #define E_INSUFFICIENT_BUFFER (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) -#endif - -#ifndef E_FILE_NOT_FOUND - #define E_FILE_NOT_FOUND (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) -#endif - -//--------------------------------------------------------------------------------------------- -using clr::str::IsNullOrEmpty; - -//--------------------------------------------------------------------------------------------- -typedef decltype(GetCurrentPackageId) GetCurrentPackageId_t; -typedef decltype(GetCurrentPackageInfo) GetCurrentPackageInfo_t; -typedef decltype(GetCurrentPackagePath) GetCurrentPackagePath_t; -typedef decltype(OpenPackageInfoByFullName) OpenPackageInfoByFullName_t; -typedef decltype(ClosePackageInfo) ClosePackageInfo_t; -typedef decltype(GetPackageInfo) GetPackageInfo_t; - -//--------------------------------------------------------------------------------------------- -// Caches AppX ARI API-related information. -struct AppXRTInfo -{ - HMODULE m_hAppXRTMod; - bool m_fIsAppXProcess; - bool m_fIsAppXAdaptiveApp; - bool m_fIsAppXNGen; - - GetCurrentPackageId_t * m_pfnGetCurrentPackageId; - GetCurrentPackageInfo_t * m_pfnGetCurrentPackageInfo; - GetCurrentPackagePath_t * m_pfnGetCurrentPackagePath; - - NewArrayHolder<BYTE> m_pbAppContainerInfo; - DWORD m_cbAppContainerInfo; - - struct CurrentPackageInfo - { - UINT32 m_cbCurrentPackageInfo; - PBYTE m_pbCurrentPackageInfo; - UINT32 m_nCount; - - CurrentPackageInfo(UINT32 cbPkgInfo, PBYTE pbPkgInfo, UINT32 nCount) - : m_cbCurrentPackageInfo(cbPkgInfo) - , m_pbCurrentPackageInfo(pbPkgInfo) - , m_nCount(nCount) - { LIMITED_METHOD_CONTRACT; } - - ~CurrentPackageInfo() - { - LIMITED_METHOD_CONTRACT; - if (m_pbCurrentPackageInfo != nullptr) - { - delete [] m_pbCurrentPackageInfo; - m_pbCurrentPackageInfo = nullptr; - } - } - }; - - CurrentPackageInfo * m_pCurrentPackageInfo; - - NewArrayHolder<WCHAR> m_AdaptiveAppWinmetadataDir; - - AppXRTInfo() : - m_hAppXRTMod(nullptr), - m_fIsAppXProcess(false), - m_fIsAppXAdaptiveApp(false), - m_fIsAppXNGen(false), - m_pfnGetCurrentPackageId(nullptr), - m_pfnGetCurrentPackageInfo(nullptr), - m_pfnGetCurrentPackagePath(nullptr), - m_pbAppContainerInfo(nullptr), - m_pCurrentPackageInfo(nullptr), - m_AdaptiveAppWinmetadataDir(nullptr) - { LIMITED_METHOD_CONTRACT; } - - ~AppXRTInfo() - { - LIMITED_METHOD_CONTRACT; - if (m_pCurrentPackageInfo != nullptr) - { - delete m_pCurrentPackageInfo; - m_pCurrentPackageInfo = nullptr; - } - - if (m_hAppXRTMod != nullptr) - { - FreeLibrary(m_hAppXRTMod); - m_hAppXRTMod = nullptr; - } - } -}; // struct AppXRTInfo - -GPTR_IMPL(AppXRTInfo, g_pAppXRTInfo); // Relies on zero init static memory. - -#ifndef DACCESS_COMPILE - -//--------------------------------------------------------------------------------------------- -static -HRESULT GetAppContainerTokenInfoForProcess( - DWORD pid, - NewArrayHolder<BYTE>& pbAppContainerTokenInfo, - DWORD* pcbAppContainerTokenInfo) -{ - PRECONDITION(CheckPointer(pcbAppContainerTokenInfo, NULL_OK)); - - HRESULT hr = S_OK; - - pbAppContainerTokenInfo = nullptr; - - // In order to get the AppContainer SID we need to open the process token - HandleHolder hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); - if (hProcess == NULL) - return HRESULT_FROM_GetLastError(); - - HandleHolder hToken; - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) - return HRESULT_FROM_GetLastError(); - - // Query the process to see if it's inside an AppContainer - ULONG isAppContainer = 0; - DWORD actualLength = 0; - if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenIsAppContainer), &isAppContainer, sizeof(isAppContainer), &actualLength)) - return HRESULT_FROM_GetLastError(); - - _ASSERTE(actualLength > 0); - - // Not an AppContainer so bail - if (!isAppContainer) - { - return S_FALSE; - } - - // Now we need the AppContainer SID so first get the required buffer length - actualLength = 0; - VERIFY(!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), NULL, 0, &actualLength)); - hr = HRESULT_FROM_GetLastError(); - _ASSERTE(hr == E_INSUFFICIENT_BUFFER); - - // Something unexpected happened - if (hr != E_INSUFFICIENT_BUFFER) - return hr; - - // Now we know the length of the AppContainer SID so create a buffer and retrieve it - pbAppContainerTokenInfo = new (nothrow) BYTE[actualLength]; - IfNullRet(pbAppContainerTokenInfo); - - if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), pbAppContainerTokenInfo.GetValue(), actualLength, &actualLength)) - return HRESULT_FROM_GetLastError(); - - if (pcbAppContainerTokenInfo != nullptr) - *pcbAppContainerTokenInfo = actualLength; - - return S_OK; -} - -//--------------------------------------------------------------------------------------------- -// Initializes a global AppXRTInfo structure if it has not already been initialized. Returns -// false only in the event of OOM; otherwise caches the result of ARI information in -// g_pAppXRTInfo. Thread safe. -static -HRESULT InitAppXRT() -{ - // This will be used for catastrophic errors. - HRESULT hr = S_OK; - - if (VolatileLoad(&g_pAppXRTInfo) == nullptr) - { - NewHolder<AppXRTInfo> pAppXRTInfo = new (nothrow) AppXRTInfo(); - IfNullRet(pAppXRTInfo); // Catastrophic error. - - pAppXRTInfo->m_fIsAppXProcess = false; - - do - { - if (!RunningOnWin8()) - { - break; - } - - LPCWSTR wzAppXRTDll = W("api-ms-win-appmodel-runtime-l1-1-0.dll"); - // Does not use GetLoadWithAlteredSearchPathFlag() because that would cause infinite recursion. - pAppXRTInfo->m_hAppXRTMod = WszLoadLibraryEx(wzAppXRTDll, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (pAppXRTInfo->m_hAppXRTMod == nullptr) - { // Error is catastrophic: can't find kernel32.dll? - hr = HRESULT_FROM_GetLastError(); - break; - } - - pAppXRTInfo->m_pfnGetCurrentPackageId = reinterpret_cast<GetCurrentPackageId_t *>( - GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageId")); - if (pAppXRTInfo->m_pfnGetCurrentPackageId == nullptr) - { // Error is non-catastrophic: could be running downlevel - break; - } - - pAppXRTInfo->m_pfnGetCurrentPackageInfo = reinterpret_cast<GetCurrentPackageInfo_t *>( - GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageInfo")); - if (pAppXRTInfo->m_pfnGetCurrentPackageInfo == nullptr) - { // Error is catastrophic: GetCurrentPackageId is available but not GetCurrentPackageInfo? - hr = HRESULT_FROM_GetLastError(); - break; - } - - pAppXRTInfo->m_pfnGetCurrentPackagePath = reinterpret_cast<GetCurrentPackagePath_t *>( - GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackagePath")); - if (pAppXRTInfo->m_pfnGetCurrentPackagePath == nullptr) - { // Error is catastrophic: GetCurrentPackageInfo is available but not GetCurrentPackagePath? - hr = HRESULT_FROM_GetLastError(); - break; - } - - // Determine if this is an AppX process - UINT32 cbBuffer = 0; - LONG lRes = (*pAppXRTInfo->m_pfnGetCurrentPackageId)(&cbBuffer, nullptr); - pAppXRTInfo->m_fIsAppXProcess = (lRes == ERROR_INSUFFICIENT_BUFFER); - - _ASSERTE(AppX::IsAppXSupported()); - - hr = GetAppContainerTokenInfoForProcess( - GetCurrentProcessId(), - pAppXRTInfo->m_pbAppContainerInfo, - &pAppXRTInfo->m_cbAppContainerInfo); - - if (FAILED(hr)) - { - if (pAppXRTInfo->m_fIsAppXProcess) - { // Error is catastrophic: running in true immersive process but no token info? - } - else - { // Error is non-catastrophic: reset HRESULT to S_OK. - hr = S_OK; - } - break; - } - } - while (false); - - if (InterlockedCompareExchangeT<AppXRTInfo>(&g_pAppXRTInfo, pAppXRTInfo, nullptr) == nullptr) - { - pAppXRTInfo.SuppressRelease(); - } - } - - return hr; -} - -//--------------------------------------------------------------------------------------------- -// Inline helper to check first an only init when required. -static inline HRESULT CheckInitAppXRT() -{ - return (VolatileLoad(&g_pAppXRTInfo) != nullptr) ? S_OK : InitAppXRT(); -} - -#endif // !DACCESS_COMPILE - -//--------------------------------------------------------------------------------------------- -// Contains general helper methods for interacting with AppX functionality. This code will -// gracefully fail on downlevel OS by returning false from AppX::IsAppXProcess, so always -// call this API first to check before calling any of the others defined in this namespace. -// -// See http://windows/windows8/docs/Windows%208%20Feature%20Documents/Developer%20Experience%20(DEVX)/Apps%20Experience%20(APPX)/Modern%20Client/App%20Runtime%20Improvements%20API%20Developer%20Platform%20Spec.docm -// for more information. - -namespace AppX -{ -#ifdef DACCESS_COMPILE - - //----------------------------------------------------------------------------------------- - // DAC-only IsAppXProcess. Returns false if g_pAppXRTInfo has not been initialized. - bool DacIsAppXProcess() - { - LIMITED_METHOD_DAC_CONTRACT; - return (g_pAppXRTInfo != nullptr && g_pAppXRTInfo->m_fIsAppXProcess); - } - -#else // DACCESS_COMPILE - - //--------------------------------------------------------------------------------------------- - // cleans up resources allocated in InitAppXRT() - void ShutDown() - { - if (VolatileLoad(&g_pAppXRTInfo) != nullptr) - { - delete g_pAppXRTInfo; - g_pAppXRTInfo = nullptr; - } - } - - //----------------------------------------------------------------------------------------- - // Returns true if the current process is immersive. - // NOTE: a return value of true doesn't necessarily indicate that the process is a - // real Metro app, e.g. it could be an ngen process compiling an AppX assembly. - bool IsAppXProcess() - { - LIMITED_METHOD_CONTRACT; - HRESULT hr = S_OK; - - if (FAILED(hr = CheckInitAppXRT())) - { - SetLastError(hr); // HRESULT_FROM_WIN32 is idempotent when error value is HRESULT. - return false; - } - - return g_pAppXRTInfo->m_fIsAppXProcess; - } - - //----------------------------------------------------------------------------------------- - // Returns true if the current process is immersive. - // Only produces reliable results after IsAppXProcess is inititalized - bool IsAppXProcess_Initialized_NoFault() - { - LIMITED_METHOD_CONTRACT; - if (VolatileLoad(&g_pAppXRTInfo) == nullptr) - { - return false; - } - return g_pAppXRTInfo->m_fIsAppXProcess; - } - - bool IsAppXNGen() - { - LIMITED_METHOD_CONTRACT; - return VolatileLoad(&g_pAppXRTInfo) != nullptr && g_pAppXRTInfo->m_fIsAppXNGen; - } - - //----------------------------------------------------------------------------------------- - HRESULT InitCurrentPackageInfoCache() - { - LIMITED_METHOD_CONTRACT; - HRESULT hr = S_OK; - - UINT32 cbBuffer = 0; - hr = HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr)); - if (hr != E_INSUFFICIENT_BUFFER) - return hr; - - NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]); - IfNullRet(pbBuffer); - - UINT32 nCount = 0; - IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount))); - - NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo( - new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount)); - IfNullRet(pPkgInfo); - - if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>( - &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr) - { - pPkgInfo.SuppressRelease(); - } - - return S_OK; - } - - //----------------------------------------------------------------------------------------- - FORCEINLINE HRESULT CheckInitCurrentPackageInfoCache() - { - WRAPPER_NO_CONTRACT; - PRECONDITION(IsAppXProcess()); - - if (!IsAppXProcess()) - return E_UNEXPECTED; - - if (g_pAppXRTInfo->m_pCurrentPackageInfo == nullptr) - return InitCurrentPackageInfoCache(); - else - return S_OK; - } - - //----------------------------------------------------------------------------------------- - LPCWSTR GetHeadPackageMoniker() - { - STANDARD_VM_CONTRACT; - - IfFailThrow(CheckInitCurrentPackageInfoCache()); - return reinterpret_cast<PPACKAGE_INFO>( - g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo)->packageFullName; - } - - //----------------------------------------------------------------------------------------- - // Returns the current process' PACKAGE_ID in the provided buffer. See the ARI spec (above) - // for more information. - HRESULT GetCurrentPackageId( - PUINT32 pBufferLength, - PBYTE pBuffer) - { - LIMITED_METHOD_CONTRACT; - HRESULT hr = S_OK; - - IfFailRet(CheckInitAppXRT()); - IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageId)(pBufferLength, pBuffer))); - - return S_OK; - } - - //----------------------------------------------------------------------------------------- - // Returns the current process' PACKAGE_INFO in the provided buffer. See the ARI spec - // (above) for more information. - HRESULT GetCurrentPackageInfo( - UINT32 uiFlags, - PUINT32 pcbBuffer, - PBYTE pbBuffer, - PUINT32 pnCount) - { - LIMITED_METHOD_CONTRACT; - PRECONDITION(IsAppXProcess()); - PRECONDITION(CheckPointer(pcbBuffer)); - - HRESULT hr = S_OK; - - IfFailRet(CheckInitAppXRT()); - - if (pcbBuffer == nullptr) - return E_INVALIDARG; - - if (uiFlags == PACKAGE_FILTER_CLR_DEFAULT) - { - IfFailRet(CheckInitCurrentPackageInfoCache()); - - DWORD cbBuffer = *pcbBuffer; - *pcbBuffer = g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo; - if (pnCount != nullptr) - { - *pnCount = g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount; - } - - if (pbBuffer == nullptr || cbBuffer < g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo) - { - return E_INSUFFICIENT_BUFFER; - } - memcpy(pbBuffer, g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo, g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo); - } - else - { - IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(uiFlags, pcbBuffer, pbBuffer, pnCount))); - } - - return S_OK; - } - - //----------------------------------------------------------------------------------------- - bool IsAdaptiveApp() - { - LIMITED_METHOD_CONTRACT; - - HRESULT hr = S_OK; - static bool cachedIsAdaptiveApp = false; - - if (!IsAppXProcess()) - { - return false; - } - - if (!cachedIsAdaptiveApp) - { - cachedIsAdaptiveApp = true; - LPWSTR adaptiveAppWinmetaDataDir = NULL; - - if (SUCCEEDED(hr = AppX::GetWinMetadataDirForAdaptiveApps(&adaptiveAppWinmetaDataDir))) - { - g_pAppXRTInfo->m_fIsAppXAdaptiveApp = clr::fs::Dir::Exists(adaptiveAppWinmetaDataDir); - - } - else - { - SetLastError(hr); - g_pAppXRTInfo->m_fIsAppXAdaptiveApp = false; - } - - } - - return g_pAppXRTInfo->m_fIsAppXAdaptiveApp; - } - - - //----------------------------------------------------------------------------------------- - // length : Upon success, contains the the length of packagePath - // [in/out] - // - // packageRoot : Upon success, contains the full packagePath - // [out] [ Note: The memory has to be preallocated for the above length] - // - HRESULT GetCurrentPackagePath(_Inout_ UINT32* length, _Out_opt_ PWSTR packageRoot) - { - PRECONDITION(IsAppXProcess()); - PRECONDITION(CheckPointer(length)); - - HRESULT hr; - IfFailRet(CheckInitAppXRT()); - - IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackagePath)(length, packageRoot))); - return S_OK; - } - - //----------------------------------------------------------------------------------------- - // winMetadDataDir : Upon success, contains the absolute path for the winmetadata directory for the adaptive app - // [out] NOTE: The string the pointer points to is global memory and never should be modified - // - HRESULT GetWinMetadataDirForAdaptiveApps(_Out_ LPWSTR* winMetadDataDir) - { - - PRECONDITION(IsAppXProcess()); - - HRESULT hr; - - IfFailRet(CheckInitAppXRT()); - - if (g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir == nullptr) - { - LPCWSTR wzWinMetadataFolder=W("\\WinMetadata"); - NewArrayHolder<WCHAR> wzCompletePath; - UINT32 length=0; - - hr = GetCurrentPackagePath(&length, NULL); - if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) - return hr; - - NewArrayHolder<WCHAR> wzPath_holder = new (nothrow) WCHAR[length]; - - IfNullRet(wzPath_holder); - IfFailRet(GetCurrentPackagePath(&length, wzPath_holder.GetValue())); - - DWORD cchFullPathBuf = length + (DWORD)wcslen(wzWinMetadataFolder) + 1; - IfNullRet(wzCompletePath = new (nothrow) WCHAR[cchFullPathBuf]); - IfFailRet(clr::fs::Path::Combine(wzPath_holder.GetValue(), wzWinMetadataFolder, &cchFullPathBuf, wzCompletePath.GetValue())); - g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir = wzCompletePath.Extract(); - } - - *winMetadDataDir = g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir; - - return S_OK; - } - -#if defined(FEATURE_APPX_BINDER) - //----------------------------------------------------------------------------------------- - // Iterates the current process' packages and returns the first package that contains a - // file matching wzFileName. - // - // wzFileName : The file to look for in the current process' packages. If this is a - // [in] relative path, then it appends the path to the root of each package in - // sequence to see if the resulting path points to an existing file. If this - // is an absolute path, then for each package it determines if the package - // root is a prefix of wzFileName. - // pcchPathName : Upon entry contains the length of the buffer pwzPathName, and upon return - // [in/out] contains either the number of characters written or the buffer size - // required. - // pwzPathName : Upon success, contains the absolute path for the first matching file. - // [out] - HRESULT FindFileInCurrentPackage( - PCWSTR wzFileName, - PUINT32 pcchPathName, - PWSTR pwzPathName, - UINT32 uiFlags, - __in PCWSTR *rgwzAltPaths, - __in UINT32 cAltPaths, - FindFindInPackageFlags findInCurrentPackageFlags) - { - LIMITED_METHOD_CONTRACT; - PRECONDITION(IsAppXProcess()); - PRECONDITION(CheckPointer(wzFileName)); - PRECONDITION(CheckPointer(pcchPathName)); - PRECONDITION(CheckPointer(pwzPathName)); - - HRESULT hr = S_OK; - - if (!IsAppXProcess()) - return E_UNEXPECTED; - - // PACKAGE_FILTER_ALL_LOADED is obsolete, and shouldn't be used. - // We also don't currently handle the case where PACKAGE_FILTER_HEAD isn't set. - _ASSERTE(uiFlags != PACKAGE_FILTER_ALL_LOADED && (uiFlags & PACKAGE_FILTER_HEAD) != 0); - if (uiFlags == PACKAGE_FILTER_ALL_LOADED || (uiFlags & PACKAGE_FILTER_HEAD) == 0) - return E_NOTIMPL; - - // File name must be non-null and relative - if (IsNullOrEmpty(wzFileName) || pcchPathName == nullptr || pwzPathName == nullptr) - return E_INVALIDARG; - - // If we've been provided a full path and the file doesn't actually exist - // then we can immediately say that this function will fail with "file not found". - bool fIsRelative = clr::fs::Path::IsRelative(wzFileName); - if (!fIsRelative && !clr::fs::File::Exists(wzFileName)) - return E_FILE_NOT_FOUND; - - IfFailRet(CheckInitCurrentPackageInfoCache()); - - DWORD const cchFileName = static_cast<DWORD>(wcslen(wzFileName)); - DWORD cchFullPathBuf = _MAX_PATH; - NewArrayHolder<WCHAR> wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf]; - IfNullRet(wzFullPathBuf); - - auto FindFileInCurrentPackageHelper = [&](LPCWSTR wzPath) -> HRESULT - { - HRESULT hr = S_OK; - - if (!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath) && clr::fs::Path::HasLongFormatPrefix(wzPath)) - return COR_E_BAD_PATHNAME; // We can't handle long format paths. - - // If the path is relative, concatenate the package root and the file name and see - // if the file exists. - if (fIsRelative) - { - DWORD cchFullPath = cchFullPathBuf; - hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf); - if (hr == E_INSUFFICIENT_BUFFER) - { - IfNullRet(wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf = (cchFullPath + 1)]); - hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf); - } - IfFailRet(hr); - - if (!clr::fs::Path::IsValid(wzFullPathBuf, cchFullPath, !!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath))) - return COR_E_BAD_PATHNAME; - - if (clr::fs::File::Exists(wzFullPathBuf)) - { - DWORD cchPathName = *pcchPathName; - *pcchPathName = cchFullPath; - return StringCchCopy(pwzPathName, cchPathName, wzFullPathBuf); - } - } - // If the path is absolute, see if the file name contains the pacakge root as a prefix - // and if the file exists. - else - { - DWORD cchPath = static_cast<DWORD>(wcslen(wzPath)); - - // Determine if wzPath is a path prefix of wzFileName - if (cchPath < cchFileName && - _wcsnicmp(wzPath, wzFileName, cchPath) == 0 && - (wzFileName[cchPath] == W('\\') || wzPath[cchPath-1] == W('\\'))) // Ensure wzPath is not just a prefix, but a path prefix - { - if (clr::fs::File::Exists(wzFileName)) - { - DWORD cchPathName = *pcchPathName; - *pcchPathName = cchFileName; - return StringCchCopy(pwzPathName, cchPathName, wzFileName); - } - } - } - - return S_FALSE; - }; // FindFileInCurrentPackageHelper - - if (!(findInCurrentPackageFlags & FindFindInPackageFlags_SkipCurrentPackageGraph)) - { - PCPACKAGE_INFO pCurNode = reinterpret_cast<PPACKAGE_INFO>( - g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo); - PCPACKAGE_INFO pEndNode = pCurNode + g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount; - for (; pCurNode != pEndNode; ++pCurNode) - { - IfFailRet(FindFileInCurrentPackageHelper(pCurNode->path)); - - if (hr == S_OK) - { - return hr; - } - - // End search if dependent packages should not be checked. - if ((uiFlags & PACKAGE_FILTER_DIRECT) == 0) - { - break; - } - } - } - - // Process alternative paths - for (UINT iAltPath = 0; iAltPath < cAltPaths; iAltPath++) - { - IfFailRet(FindFileInCurrentPackageHelper(rgwzAltPaths[iAltPath])); - - if (hr == S_OK) - { - return hr; - } - } - - return E_FILE_NOT_FOUND; - } -#endif // FEATURE_APPX_BINDER - - //----------------------------------------------------------------------------------------- - HRESULT GetAppContainerTokenInfoForProcess( - DWORD dwPid, - NewArrayHolder<BYTE>& pbAppContainerTokenInfo, - DWORD* pcbAppContainerTokenInfo) - { - LIMITED_METHOD_CONTRACT; - - HRESULT hr = S_OK; - - pbAppContainerTokenInfo = nullptr; - - if (!IsAppXSupported()) - { - return S_FALSE; - } - - if (dwPid == GetCurrentProcessId()) - { - if (FAILED(hr = CheckInitAppXRT())) - { - SetLastError(hr); - return S_FALSE; - } - - if (g_pAppXRTInfo->m_pbAppContainerInfo == nullptr) - { - return S_FALSE; - } - else - { - pbAppContainerTokenInfo = g_pAppXRTInfo->m_pbAppContainerInfo.GetValue(); - pbAppContainerTokenInfo.SuppressRelease(); // Caller does not need to free mem. - if (pcbAppContainerTokenInfo != nullptr) - { - *pcbAppContainerTokenInfo = g_pAppXRTInfo->m_cbAppContainerInfo; - } - return S_OK; - } - } - else - { - return ::GetAppContainerTokenInfoForProcess(dwPid, pbAppContainerTokenInfo, pcbAppContainerTokenInfo); - } - } - - // Called during NGen to pretend that we're in a certain package. Due to Windows restriction, we can't - // start NGen worker processes in the right package environment (only in the right AppContainer). So - // NGen calls this function with a package name, to indicate that all AppX-related code should behave as - // if the current process is running in that package. - HRESULT SetCurrentPackageForNGen(__in PCWSTR pszPackageFullName) - { - LIMITED_METHOD_CONTRACT; - - HRESULT hr = S_OK; - - IfFailRet(CheckInitAppXRT()); - - _ASSERTE(IsAppXSupported()); - _ASSERTE(g_pAppXRTInfo->m_hAppXRTMod != nullptr); - - HMODULE hAppXRTMod = g_pAppXRTInfo->m_hAppXRTMod; - OpenPackageInfoByFullName_t *pfnOpenPackageInfoByFullName - = reinterpret_cast<OpenPackageInfoByFullName_t*>(GetProcAddress(hAppXRTMod, "OpenPackageInfoByFullName")); - _ASSERTE(pfnOpenPackageInfoByFullName != nullptr); - if (pfnOpenPackageInfoByFullName == nullptr) - return HRESULT_FROM_GetLastError(); - - ClosePackageInfo_t *pfnClosePackageInfo - = reinterpret_cast<ClosePackageInfo_t*>(GetProcAddress(hAppXRTMod, "ClosePackageInfo")); - _ASSERTE(pfnClosePackageInfo != nullptr); - if (pfnClosePackageInfo == nullptr) - return HRESULT_FROM_GetLastError(); - - GetPackageInfo_t *pfnGetPackageInfo - = reinterpret_cast<GetPackageInfo_t*>(GetProcAddress(hAppXRTMod, "GetPackageInfo")); - _ASSERTE(pfnGetPackageInfo != nullptr); - if (pfnGetPackageInfo == nullptr) - return HRESULT_FROM_GetLastError(); - - PACKAGE_INFO_REFERENCE packageInfoReference; - hr = HRESULT_FROM_WIN32(pfnOpenPackageInfoByFullName(pszPackageFullName, 0, &packageInfoReference)); - if (FAILED(hr)) - return hr; - - // Automatically close packageInfoReference before we return. - class PackageInfoReferenceHolder - { - public: - PackageInfoReferenceHolder(ClosePackageInfo_t *pfnClosePackageInfo, PACKAGE_INFO_REFERENCE &packageInfoReference) - :m_pfnClosePackageInfo(pfnClosePackageInfo), - m_packageInfoReference(packageInfoReference) - { - } - ~PackageInfoReferenceHolder() { m_pfnClosePackageInfo(m_packageInfoReference); } - private: - ClosePackageInfo_t *m_pfnClosePackageInfo; - PACKAGE_INFO_REFERENCE &m_packageInfoReference; - } pirh(pfnClosePackageInfo, packageInfoReference); - - UINT32 cbBuffer = 0; - hr = HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr)); - if (hr != E_INSUFFICIENT_BUFFER) - return hr; - - NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]); - IfNullRet(pbBuffer); - - UINT32 nCount = 0; - IfFailRet(HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount))); - - NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo( - new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount)); - IfNullRet(pPkgInfo); - - if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>( - &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr) - { - pPkgInfo.SuppressRelease(); - } - - g_pAppXRTInfo->m_fIsAppXProcess = true; - g_pAppXRTInfo->m_fIsAppXNGen = true; - - return hr; - } - -#endif // DACCESS_COMPILE -} // namespace AppX - - -#endif // FEATURE_CORECLR |