BOOL PELoader::open(const WCHAR* moduleName) { HMODULE newhMod = NULL; DWORD dwFileSizeLow; _ASSERTE(moduleName); if (!moduleName) return FALSE; m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (m_hFile == INVALID_HANDLE_VALUE) return FALSE; dwFileSizeLow = GetFileSize( m_hFile, NULL); if (dwFileSizeLow == INVALID_FILE_SIZE) return FALSE; m_FileSize = dwFileSizeLow; m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (m_hMapFile == NULL) return FALSE; newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0); if (newhMod == NULL) return FALSE; return open(newhMod); }
LPVOID NLSTable::MapDataFile(LPCWSTR pMappingName, LPCSTR pFileName, HANDLE *hFileMap) { _ASSERTE(pMappingName != NULL); // Must be a named file mapping object. _ASSERTE(pFileName != NULL); // Must have a valid file name. _ASSERTE(hFileMap != NULL); // Must have a valid location for the handle. THROWSCOMPLUSEXCEPTION(); *hFileMap = NULL; LPVOID pData=NULL; //It's silly to have this up here, but it makes the compiler happy. HANDLE hFile = OpenDataFile(pFileName); if (hFile == INVALID_HANDLE_VALUE) { goto ErrorExit; } *hFileMap = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); CloseHandle(hFile); if (*hFileMap == NULL) { _ASSERTE(!"Error in CreateFileMapping"); goto ErrorExit; } // // Map a view of the file mapping. // pData = MapViewOfFile(*hFileMap, FILE_MAP_READ, 0, 0, 0); if (pData == NULL) { _ASSERTE(!"Error in MapViewOfFile"); goto ErrorExit; } return (pData); ErrorExit: if (*hFileMap) { CloseHandle(*hFileMap); } //If we can't get the table, we're in trouble anyway. Throw an EE Exception. FATAL_EE_ERROR(); return NULL; }
HRESULT GetHash(__in LPWSTR moduleName, ALG_ID iHashAlg, BYTE** pbCurrentValue, // should be NULL DWORD *cbCurrentValue) { HRESULT hr = E_FAIL; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD dwCount = sizeof(DWORD); PBYTE pbBuffer = NULL; DWORD dwBufferLen; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapFile = NULL; hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return E_FAIL; dwBufferLen = SafeGetFileSize(hFile,NULL); if (dwBufferLen == 0xffffffff) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapFile == NULL) goto exit; pbBuffer = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); if (pbBuffer == NULL) goto exit; // No need to late bind this stuff, all these crypto API entry points happen // to live in ADVAPI32. if ((!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) || (!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) || (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) || (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) cbCurrentValue, &dwCount, 0))) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } *pbCurrentValue = new BYTE[*cbCurrentValue]; if (!(*pbCurrentValue)) { hr = E_OUTOFMEMORY; goto exit; } if(!CryptGetHashParam(hHash, HP_HASHVAL, *pbCurrentValue, cbCurrentValue, 0)) { hr = HRESULT_FROM_WIN32(GetLastError()); delete[] *pbCurrentValue; *pbCurrentValue = 0; goto exit; } hr = S_OK; exit: if (pbBuffer) UnmapViewOfFile(pbBuffer); if (hMapFile) CloseHandle(hMapFile); CloseHandle(hFile); if (hHash) CryptDestroyHash(hHash); if (hProv) CryptReleaseContext(hProv, 0); return hr; }
//***************************************************************************** // Map the file contents to a memory mapped file and return a pointer to the // data. For read/write with a backing store, map the file using an internal // paging system. //***************************************************************************** HRESULT StgIO::MapFileToMem( // Return code. void *&ptr, // Return pointer to file data. ULONG *pcbSize, // Return size of data. LPSECURITY_ATTRIBUTES pAttributes) // Security token. { char rcShared[MAXSHMEM]; // ANSI version of shared name. HRESULT hr = S_OK; // Don't penalize for multiple calls. Also, allow calls for mem type so // callers don't need to do so much checking. if (IsBackingStore() || IsMemoryMapped() || (m_iType == STGIO_MEM) || (m_iType == STGIO_SHAREDMEM) || (m_iType == STGIO_HFILEMEM)) { ptr = m_pData; if (pcbSize) *pcbSize = m_cbData; return (S_OK); } //#CopySmallFiles // Check the size of the data we want to map. If it is small enough, then // simply allocate a chunk of memory from a finer grained heap. This saves // virtual memory space, page table entries, and should reduce overall working set. // Also, open for read/write needs a full backing store. if ((m_cbData <= SMALL_ALLOC_MAP_SIZE) && (SMALL_ALLOC_MAP_SIZE > 0)) { DWORD cbRead = m_cbData; _ASSERTE(m_pData == 0); // Just malloc a chunk of data to use. m_pBaseData = m_pData = AllocateMemory(m_cbData); if (!m_pData) { hr = OutOfMemory(); goto ErrExit; } // Read all of the file contents into this piece of memory. IfFailGo( Seek(0, FILE_BEGIN) ); if (FAILED(hr = Read(m_pData, cbRead, &cbRead))) { FreeMemory(m_pData); m_pData = 0; goto ErrExit; } _ASSERTE(cbRead == m_cbData); // If the file isn't being opened for exclusive mode, then free it. // If it is for exclusive, then we need to keep the handle open so the // file is locked, preventing other readers. Also leave it open if // in read/write mode so we can truncate and rewrite. if (m_hFile == INVALID_HANDLE_VALUE || ((m_fFlags & DBPROP_TMODEF_EXCLUSIVE) == 0 && (m_fFlags & DBPROP_TMODEF_WRITE) == 0)) { // If there was a handle open, then free it. if (m_hFile != INVALID_HANDLE_VALUE) { VERIFY(CloseHandle(m_hFile)); m_hFile = INVALID_HANDLE_VALUE; } // Free the stream pointer. else if (m_pIStream != 0) { m_pIStream->Release(); m_pIStream = 0; } // Switch the type to memory only access. m_iType = STGIO_MEM; } else m_iType = STGIO_HFILEMEM; // Free the memory when we shut down. m_bFreeMem = true; } // Finally, a real mapping file must be created. else { // Now we will map, so better have it right. _ASSERTE(m_hFile != INVALID_HANDLE_VALUE || m_iType == STGIO_STREAM); _ASSERTE(m_rgPageMap == 0); // For read mode, use a memory mapped file since the size will never // change for the life of the handle. if ((m_fFlags & DBPROP_TMODEF_WRITE) == 0 && m_iType != STGIO_STREAM) { // Create a mapping object for the file. _ASSERTE(m_hMapping == 0); DWORD dwProtectionFlags = PAGE_READONLY; if ((m_hMapping = WszCreateFileMapping(m_hFile, pAttributes, dwProtectionFlags, 0, 0, nullptr)) == 0) { return (MapFileError(GetLastError())); } m_mtMappedType = MTYPE_FLAT; // Check to see if the memory already exists, in which case we have // no guarantees it is the right piece of data. if (GetLastError() == ERROR_ALREADY_EXISTS) { hr = PostError(CLDB_E_SMDUPLICATE, rcShared); goto ErrExit; } // Now map the file into memory so we can read from pointer access. // <REVISIT_TODO>Note: Added a check for IsBadReadPtr per the Services team which // indicates that under some conditions this API can give you back // a totally bogus pointer.</REVISIT_TODO> if ((m_pBaseData = m_pData = MapViewOfFile(m_hMapping, FILE_MAP_READ, 0, 0, 0)) == 0) { hr = MapFileError(GetLastError()); if (SUCCEEDED(hr)) { _ASSERTE_MSG(FALSE, "Error code doesn't indicate error."); hr = PostError(CLDB_E_FILE_CORRUPT); } // In case we got back a bogus pointer. m_pBaseData = m_pData = NULL; goto ErrExit; } } // In write mode, we need the hybrid combination of being able to back up // the data in memory via cache, but then later rewrite the contents and // throw away our cached copy. Memory mapped files are not good for this // case due to poor write characteristics. else { ULONG iMaxSize; // How much memory required for file. // Figure out how many pages we'll require, round up actual data // size to page size. iMaxSize = (((m_cbData - 1) & ~(m_iPageSize - 1)) + m_iPageSize); // Check integer overflow in previous statement if (iMaxSize < m_cbData) { IfFailGo(PostError(COR_E_OVERFLOW)); } // Allocate a bit vector to track loaded pages. if ((m_rgPageMap = new (nothrow) BYTE[iMaxSize / m_iPageSize]) == 0) return (PostError(OutOfMemory())); memset(m_rgPageMap, 0, sizeof(BYTE) * (iMaxSize / m_iPageSize)); // Allocate space for the file contents. if ((m_pBaseData = m_pData = ::ClrVirtualAlloc(0, iMaxSize, MEM_RESERVE, PAGE_NOACCESS)) == 0) { hr = PostError(OutOfMemory()); goto ErrExit; } } } // Reset any changes made by mapping. IfFailGo( Seek(0, FILE_BEGIN) ); ErrExit: // Check for errors and clean up. if (FAILED(hr)) { if (m_hMapping) CloseHandle(m_hMapping); m_hMapping = 0; m_pBaseData = m_pData = 0; m_cbData = 0; } ptr = m_pData; if (pcbSize) *pcbSize = m_cbData; return (hr); }