title: C++ MapViewOfFile fails
body: <p>I am trying to memory-map a file on Windows using VS2010. 
  I am doing this in a DLL.
  The first instance of the DLL maps the file just fine.
  The second instance within the same process causes </p>
  
  <pre><code>*ppvData = ::MapViewOfFile( *phMapping, FILE_MAP_READ, 0, 0, 0 );
  </code></pre>
  
  <p>to fail with the error "Not enough memory available for this command".
  I am not sure why this happens. </p>
  
  <p>If I map 2 different files instead of twice the same file, all works fine, so I don't trust the "Not enough memory" error message. </p>
  
  <p>Thank you.</p>
  
  <pre><code>hr = MapFile(sPath, &amp;m_hVoiceData, &amp;m_pVoiceData,wsErr );
  
  HRESULT CTTSEngObj::MapFile( wstring uPath,  // Value that contains file path
                              HANDLE * phMapping,          // Pointer to file mapping handle
                              void ** ppvData,             // Pointer to the data
                              wstring &amp;uError)
  {
      HRESULT hr = S_OK;
      CSpDynamicString dstrFilePath(uPath.c_str());
  
      if ( SUCCEEDED( hr ) )
      {
          bool fWorked = false;
          *phMapping = NULL;
          *ppvData = NULL;
          HANDLE hFile;
  #ifdef _WIN32_WCE
          hFile = CreateFileForMapping( dstrFilePath, GENERIC_READ,
                                        FILE_SHARE_READ, NULL, OPEN_EXISTING,
                                        FILE_ATTRIBUTE_NORMAL, NULL );
  #else
          hFile = CreateFile(CW2T(dstrFilePath), GENERIC_READ,
                              FILE_SHARE_READ, NULL, OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL, NULL );
  #endif
          if (hFile != INVALID_HANDLE_VALUE)
          {
              *phMapping = ::CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
              if (*phMapping)
              {
                  *ppvData = ::MapViewOfFile( *phMapping, FILE_MAP_READ, 0, 0, 0 );
                  if (*ppvData)
                  {
                      fWorked = true;
                  }
                  else
                  {
                      uError=GetLastErrorStdStrW();
                  }
              }
              else
              {
                  uError=L"mapfile: fm failed";
              }
              ::CloseHandle( hFile );
          }
          else
          {
              uError=L"mapfile: invalidhandle";
          }
          if (!fWorked)
          {
              hr = HRESULT_FROM_WIN32(::GetLastError());
              if (*phMapping)
              {
                  ::CloseHandle(*phMapping);
                  *phMapping = NULL;
              }
          }
      }
      else
      {
          uError=L"mapfile: dynstr";
      }
      return hr;
  } /* CTTSEngObj::MapFile */
  </code></pre>
  
  <p>And this is how it is declared:</p>
  
  <pre><code>class ATL_NO_VTABLE CTTSEngObj : 
      public CComObjectRootEx&lt;CComMultiThreadModel&gt;,
      public CComCoClass&lt;CTTSEngObj, &amp;CLSID_SampleTTSEngine&gt;,
      public ISpTTSEngine,
      public ISpObjectWithToken
  {
  
    private:
      CComPtr&lt;ISpObjectToken&gt; m_cpToken;
      HANDLE                  m_hVoiceData;
      void*                   m_pVoiceData;
  </code></pre>