//----------------------------------------------------------------------------- // Open our private block //----------------------------------------------------------------------------- HRESULT IPCReaderInterface::OpenPrivateBlockOnPid(DWORD pid, DWORD dwDesiredAccess) { HRESULT hr = NO_ERROR; DWORD dwErr = 0; WCHAR szMemFileName[100]; IPCShared::GenerateName(pid, szMemFileName, 100); // Note: if our private block is open, we shouldn't be attaching to a new one. _ASSERTE(!IsPrivateBlockOpen()); if (IsPrivateBlockOpen()) { return ERROR_ALREADY_EXISTS; } m_handlePrivateBlock = WszOpenFileMapping(dwDesiredAccess, FALSE, szMemFileName); dwErr = GetLastError(); if (m_handlePrivateBlock == NULL) { hr = HRESULT_FROM_WIN32(dwErr); goto errExit; } m_ptrPrivateBlock = (PrivateIPCControlBlock*) MapViewOfFile( m_handlePrivateBlock, dwDesiredAccess, 0, 0, 0); dwErr = GetLastError(); if (m_ptrPrivateBlock== NULL) { hr = HRESULT_FROM_WIN32(dwErr); goto errExit; } // Client must connect their pointers by calling GetXXXBlock() functions errExit: if (!SUCCEEDED(hr)) { ClosePrivateBlock(); } return hr; }
//----------------------------------------------------------------------------- // Get a client's private block based on enum // This is a robust function. // It will return NULL if: // * the IPC block is closed (also ASSERT), // * the eClient is out of range (From version mismatch) // * the request block is removed (probably version mismatch) // Else it will return a pointer to the requested block //----------------------------------------------------------------------------- void * IPCReaderInterface::GetPrivateBlock(EPrivateIPCClient eClient) { _ASSERTE(IsPrivateBlockOpen()); // This block doesn't exist if we're closed or out of the table's range if (!IsPrivateBlockOpen() || (DWORD) eClient >= m_ptrPrivateBlock->m_header.m_numEntries) { return NULL; } if (Internal_CheckEntryEmpty(*m_ptrPrivateBlock, eClient)) { return NULL; } return Internal_GetBlock(*m_ptrPrivateBlock, eClient); }
USHORT IPCReaderInterface::GetBuildNumber() { _ASSERTE(IsPrivateBlockOpen()); return m_ptrPrivateBlock->m_header.m_BuildNumber; }
HINSTANCE IPCReaderInterface::GetInstance() { _ASSERTE(IsPrivateBlockOpen()); return m_ptrPrivateBlock->m_header.m_hInstance; }
DWORD IPCReaderInterface::GetBlockSize() { _ASSERTE(IsPrivateBlockOpen()); return m_ptrPrivateBlock->m_header.m_blockSize; }
DWORD IPCReaderInterface::GetBlockVersion() { _ASSERTE(IsPrivateBlockOpen()); return m_ptrPrivateBlock->m_header.m_dwVersion; }
//----------------------------------------------------------------------------- // Open our private block //----------------------------------------------------------------------------- HRESULT IPCReaderInterface::OpenPrivateBlockOnPid(DWORD pid, DWORD dwDesiredAccess) { CONTRACTL { NOTHROW; GC_NOTRIGGER; } CONTRACTL_END; // Note: if our private block is open, we shouldn't be attaching to a new one. _ASSERTE(!IsPrivateBlockOpen()); if (IsPrivateBlockOpen()) { // if we goto errExit, it will close the file. We don't want that. return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); } HRESULT hr = S_OK; EX_TRY { // We should not be trying to open the IPC block of an x86 process from // within an ia64 process, or vice versa. This can only happen on // Server2003 and later. bool fCompatible = false;