Exemple #1
0
TEST_F(ContextMapTest, VerifyWithThreadsPathological) {
  ContextMap<size_t> mp;

  // Context collection and exit race threads:
  vector<std::shared_ptr<CoreContext>> contexts;

  // Exit race controller:
  AutoRequired<ExitRaceSignal> signal;

  // Create a number of dependent contexts:
  for(size_t i = 0; i < 100; i++) {
    AutoCreateContext context;
    contexts.push_back(context);

    // Store a shared pointer
    mp.Add(i, context);

    // Start the context
    context->Initiate();
  }

  // Set the signal:
  signal->Signal();

  // Verify that the map empties once our zero-count is hit:
  for(size_t i = 0; i < contexts.size(); i++) {
    contexts[i]->SignalShutdown(true);
  }

  // Clear the context collection:
  contexts.clear();
  EXPECT_EQ(0UL, mp.size()) << "Context map did not empty as expected";
}
Exemple #2
0
TEST_F(ContextMapTest, ConcurrentDestructionTestPathological) {
  for(size_t i = 0; i < 100; i++) {
    // Create our map and a few contexts:
    ContextMap<string> mp;
    AutoCreateContext contexts[4];
    weak_ptr<SimpleThreaded> threads[4];

    // Insert into the map:
    mp.Add("pathological_destruction0", contexts[0]);
    mp.Add("pathological_destruction1", contexts[1]);
    mp.Add("pathological_destruction2", contexts[2]);
    mp.Add("pathological_destruction3", contexts[3]);

    // Add a thread and kick off the context:
    for(size_t i = ARRAYCOUNT(contexts); i--;) {
      threads[i] = contexts[i]->Inject<SimpleThreaded>();
      contexts[i]->Initiate();
    }

    // Immediately tear contexts down:
    for(size_t i = ARRAYCOUNT(contexts); i--;)
      contexts[i]->SignalShutdown();

    // Wait on anything not signalled:
    for(size_t i = 0; i < ARRAYCOUNT(threads); i++) {
      auto cur = threads[i].lock();
      if(cur)
        ASSERT_TRUE(cur->WaitFor(std::chrono::seconds(1))) << "Spawned thread did not exit in a timely fashion";
    }
  }
}
Exemple #3
0
TEST_F(ContextMapTest, VerifySimpleEnumeration) {
  ContextMap<string> mp;
  AutoCreateContext ctxt1;
  AutoCreateContext ctxt2;
  AutoCreateContext ctxt3;

  mp.Add("context_se_1", ctxt1);
  mp.Add("context_se_2", ctxt2);
  mp.Add("context_se_3", ctxt3);

  std::set<std::string> found;

  size_t count = 0;
  mp.Enumerate(
    [&count, &found] (const string& name, std::shared_ptr<CoreContext>& ctxt) -> bool {
      count++;
      found.insert(name);
      return true;
    }
  );

  EXPECT_EQ(3UL, count) << "Failed to enumerate all expected context pointers";
  EXPECT_EQ(1UL, found.count("context_se_1")) << "Failed to find map element '1'";
  EXPECT_EQ(1UL, found.count("context_se_2")) << "Failed to find map element '2'";
  EXPECT_EQ(1UL, found.count("context_se_3")) << "Failed to find map element '3'";
}
Exemple #4
0
// Fetches a previously constructed context by name.
Context* GetContext(const String& name)
{
	ContextMap::iterator i = contexts.find(name);
	if (i == contexts.end())
		return NULL;

	return (*i).second;
}
Exemple #5
0
CQueue::OnCreateFile(
    /*[in]*/ IWDFIoQueue*       pQueue,
    /*[in]*/ IWDFIoRequest*     pRequest,
    /*[in]*/ IWDFFile*          pFileObject
    )
{
    UNREFERENCED_PARAMETER(pQueue);
    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FLAG_QUEUE, "%!FUNC! Entry");

    //  This critical section protects the section of code where we
    //  Create the serializer and results interfaces used in handling I/O messages.
    //  We only need to create them once, then we hang on to them for the lifetime of this
    //  queue object.
    CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection);
    HRESULT hr = S_OK;

    // Create the WPD serializer
    if ((hr == S_OK) &&
        (m_pWpdSerializer == NULL))
    {
        hr = CoCreateInstance(CLSID_WpdSerializer,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IWpdSerializer,
                              (VOID**)&m_pWpdSerializer);

        CHECK_HR(hr, "Failed to CoCreate CLSID_WpdSerializer");
    }

    // Create the client context map and associate it with the File Object
    // so we can obtain it on a per-client basis.
    if (hr == S_OK)
    {
        ContextMap* pClientContextMap = new ContextMap();

        if(pClientContextMap != NULL)
        {
            hr = pFileObject->AssignContext(this, (void*)pClientContextMap);
            CHECK_HR(hr, "Failed to set client context map");

            // Release the client context map if we cannot set it
            // properly
            if(FAILED(hr))
            {
                pClientContextMap->Release();
                pClientContextMap = NULL;
            }
        }
        else
        {
            hr = E_OUTOFMEMORY;
            CHECK_HR(hr, "Failed to create client context map");
        }
    }

    pRequest->Complete(hr);
    return;
}
Exemple #6
0
TEST_F(ContextMapTest, VerifyWithThreads) {
  ContextMap<string> mp;
  std::shared_ptr<SimpleThreaded> threaded;
  std::weak_ptr<CoreContext> weakContext;

  {
    AutoCreateContext context;

    // Obtain a weak pointer of our own, and add to the context:
    weakContext = context;
    mp.Add("context_withthreads", context);

    // Add a thread to hold the context open for awhile:
    threaded = context->Inject<SimpleThreaded>();

    // Start the context
    context->Initiate();
  }

  // Assert that the context still actually exists:
  ASSERT_TRUE(!weakContext.expired()) << "Simple thread exited before it was signalled to exit";

  {
    // Verify that we can still find the context while the thread is alive:
    std::shared_ptr<CoreContext> context = mp.Find("context_withthreads");
    ASSERT_TRUE(!!context.get()) << "Map evicted a context before expected";

    // Relock the weak context, verify that we get back the same pointer:
    auto relocked = weakContext.lock();
    EXPECT_EQ(relocked, context) << "Mapped context pointer was not identical to a previously stored context pointer";

    // Terminate whole context
    context->SignalTerminate();
  }

  // Release our threaded entity:
  threaded.reset();

  {
    // Verify that the context is gone now that everything in it has stopped running
    auto ctxt = mp.Find("context_withthreads");
    EXPECT_FALSE(ctxt) << "Context was not properly evicted from the map";

    // Just return early if the context was empty as we expected, the next part of this test is for diagnostics
    if(!ctxt)
      return;

    // Release the pointer so we aren't guilty of holding a reference to the very thing whose
    // destruction we are trying to assure.
    ctxt.reset();

    // Sleep for a little bit and run the verification again.  If the prior expectation fails,
    // but this one succeeds, it could be due to race conditions in CoreThread
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    ctxt = mp.Find("context_withthreads");
    EXPECT_FALSE(ctxt) << "Context was not properly evicted even after waiting for a time to ensure eviction";
  }
}
Exemple #7
0
void KJavaServerMaintainer::releaseContext(QObject *w, const QString &doc)
{
    ContextMap::iterator it = m_contextmap.find(qMakePair(w, doc));
    if(it != m_contextmap.end() && --(*it).second <= 0)
    {
        kdDebug(6100) << "KJavaServerMaintainer::releaseContext" << endl;
        (*it).first->deleteLater();
        m_contextmap.remove(it);
    }
}
Exemple #8
0
static void retrace_glXDestroyContext(trace::Call &call) {
    ContextMap::iterator it;
    it = context_map.find(call.arg(1).toUIntPtr());
    if (it == context_map.end()) {
        return;
    }

    it->second->release();

    context_map.erase(it);
}
static Context *
getContext(unsigned long long context_ptr) {
    if (context_ptr == 0) {
        return NULL;
    }

    ContextMap::const_iterator it;
    it = context_map.find(context_ptr);

    return (it != context_map.end()) ? it->second : NULL;
}
Exemple #10
0
TEST_F(ContextMapTest, OutOfOrderDeletionTest) {
  try {
    AutoCreateContext controlled;
    ContextMap<size_t> mp;

    // Add the current context to the map:
    mp.Add(1, controlled);

    // Map is destroyed first, then the enclosed context--no exceptions should be thrown
  } catch(...) {
    FAIL() << "Exception thrown while attempting an out-of-order teardown";
  }
}
Exemple #11
0
static void retrace_wglDeleteContext(trace::Call &call) {
    unsigned long long hglrc = call.arg(0).toUIntPtr();

    ContextMap::iterator it;
    it = context_map.find(hglrc);
    if (it == context_map.end()) {
        return;
    }

    it->second->release();
    
    context_map.erase(it);
}
Exemple #12
0
KJavaAppletContext *KJavaServerMaintainer::getContext(QObject *w, const QString &doc)
{
    ContextMap::key_type key = qMakePair(w, doc);
    ContextMap::iterator it = m_contextmap.find(key);
    if(it != m_contextmap.end())
    {
        ++((*it).second);
        return (*it).first;
    }
    KJavaAppletContext *const context = new KJavaAppletContext();
    m_contextmap.insert(key, qMakePair(context, 1));
    return context;
}
Exemple #13
0
static Context *
getContext(unsigned long long context_ptr) {
    if (context_ptr == 0) {
        return NULL;
    }

    ContextMap::const_iterator it;
    it = context_map.find(context_ptr);
    if (it == context_map.end()) {
        return (context_map[context_ptr] = glretrace::createContext());
    }

    return it->second;
}
Exemple #14
0
static glws::Context *
getContext(unsigned long long context_ptr) {
    if (context_ptr == 0) {
        return NULL;
    }

    ContextMap::const_iterator it;
    it = context_map.find(context_ptr);
    if (it == context_map.end()) {
        return (context_map[context_ptr] = ws->createContext(visual, NULL));
    }

    return it->second;
}
static void retrace_eglDestroyContext(trace::Call &call) {
    unsigned long long orig_context = call.arg(1).toUIntPtr();

    ContextMap::iterator it;
    it = context_map.find(orig_context);

    if (it != context_map.end()) {
        glretrace::Context *currentContext = glretrace::getCurrentContext();
        if (it->second != currentContext) {
            // TODO: reference count
            delete it->second;
        }
        context_map.erase(it);
    }
}
Exemple #16
0
static Context *
getContext(unsigned long long context_ptr) {
    if (context_ptr == 0) {
        return NULL;
    }

    ContextMap::const_iterator it;
    it = context_map.find(context_ptr);
    if (it == context_map.end()) {
        assert(false);
        return NULL;
    }

    return it->second;
}
Exemple #17
0
CQueue::OnCleanup(
    IWDFObject* pWdfObject
    )
{
    // Destroy the client context map
    HRESULT     hr                = S_OK;
    ContextMap* pClientContextMap = NULL;

    hr = pWdfObject->RetrieveContext((void**)&pClientContextMap);
    if((hr == S_OK) && (pClientContextMap != NULL))
    {
        pClientContextMap->Release();
        pClientContextMap = NULL;
    }
}
static void retrace_CGLDestroyContext(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    unsigned long long ctx = call.arg(0).toUIntPtr();

    ContextMap::iterator it;
    it = context_map.find(ctx);
    if (it == context_map.end()) {
        return;
    }

    delete it->second;

    context_map.erase(it);
}
Exemple #19
0
CQueue::OnCleanup(
    IWDFObject* pWdfObject
    )
{
    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FLAG_QUEUE, "%!FUNC! Entry");

    // Destroy the client context map
    HRESULT     hr                = S_OK;
    ContextMap* pClientContextMap = NULL;

    hr = pWdfObject->RetrieveContext((void**)&pClientContextMap);
    if((hr == S_OK) && (pClientContextMap != NULL))
    {
        pClientContextMap->Release();
        pClientContextMap = NULL;
    }
}
Exemple #20
0
TEST_F(ContextMapTest, AdjacentCleanupTest) {
  ContextMap<string> mp;
  std::weak_ptr<CoreContext> outerWeak;
  std::weak_ptr<CoreContext> innerWeak;

  // Add two contexts, and let one go out of scope
  AutoCreateContext outer;
  mp.Add("0", outer);
  outerWeak = outer;

  {
    AutoCreateContext inner;
    mp.Add("1", inner);
    innerWeak = inner;

    // Verify that we can find both contexts
    std::shared_ptr<CoreContext> outerSearched = mp.Find("0");
    ASSERT_TRUE(!!outerSearched.get()) << "Outer context just added, but couldn't be found";

    std::shared_ptr<CoreContext> innerSearched = mp.Find("1");
    ASSERT_TRUE(!!innerSearched.get()) << "Inner context just added, but couldn't be found";
  }

  // Inner should be 404 by now
  ASSERT_TRUE(innerWeak.expired()) << "Unexpected outstanding reference to the inner context";

  // Try to find the outer context.  This should evict the inner context.
  mp.Find("0");
  ASSERT_EQ(1UL, mp.size()) << "Proximity eviction didn't function as expected";
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_CLOSE
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: the context the driver returned to
 *      the client in OnOpenResource.
 *
 *  The driver should:
 *  - Destroy any data associated with this context.
 */
HRESULT WpdObjectResources::OnCloseResource(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT     hr                 = S_OK;
    LPWSTR      wszResourceContext = NULL;
    ContextMap* pContextMap        = NULL;

    UNREFERENCED_PARAMETER(pResults);

    // First get ALL parameters for this command.  If we cannot get ALL parameters
    // then E_INVALIDARG should be returned and no further processing should occur.

    // Get the resource context identifier for this resource operation.  We will
    // need this to lookup the specific resource context in the client context map.
    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &wszResourceContext);
    if (hr != S_OK)
    {
        hr = E_INVALIDARG;
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT");
    }

    // Get the client context map so we can retrieve the resource context for this resource
    // operation using the WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT property value obtained above.
    if (hr == S_OK)
    {
        hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap);
        CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP");
    }

    // Destroy any data allocated/associated with the resource context and then remove it from the context map.
    // We no longer need to keep this context around because the resource operation has been ended.
    if (hr == S_OK)
    {
        pContextMap->Remove(wszResourceContext);
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(wszResourceContext);

    SAFE_RELEASE(pContextMap);

    return hr;
}
Exemple #22
0
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_ENUMERATION_END_FIND
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_ENUMERATION_CONTEXT: the context the driver returned to
 *      the client in OnStartFind.
 *
 *  The driver should:
 *  - Destroy any data associated with this context.
 */
HRESULT WpdObjectEnumerator::OnEndFind(
    _In_    IPortableDeviceValues*  pParams,
    _Inout_ IPortableDeviceValues*  pResults)
{
    HRESULT     hr              = S_OK;
    LPWSTR      wszEnumContext  = NULL;
    ContextMap* pContextMap     = NULL;

    UNREFERENCED_PARAMETER(pResults);

    // First get ALL parameters for this command.  If we cannot get ALL parameters
    // then E_INVALIDARG should be returned and no further processing should occur.

    // Get the enumeration context identifier for this enumeration operation.  We will
    // need this to lookup the specific enumeration context in the client context map.
    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_ENUMERATION_CONTEXT, &wszEnumContext);
    if (hr != S_OK)
    {
        hr = E_INVALIDARG;
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_ENUMERATION_CONTEXT");
    }

    // Get the client context map so we can retrieve the enumeration context for this enumeration
    // operation using the WPD_PROPERTY_OBJECT_ENUMERATION_CONTEXT property value obtained above.
    if (hr == S_OK)
    {
        hr = GetClientContextMap(pParams, &pContextMap);
        CHECK_HR(hr, "Failed to get the client context map");
    }

    // Destroy any data allocated/associated with the enumeration context and then remove it from the context map.
    // We no longer need to keep this context around because the enumeration has been ended.
    if (hr == S_OK)
    {
        pContextMap->Remove(wszEnumContext);
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(wszEnumContext);

    SAFE_RELEASE(pContextMap);

    return hr;
}
Exemple #23
0
// Fetches a context by index.
Context* GetContext(int index)
{
	ContextMap::iterator i = contexts.begin();
	int count = 0;

	if (index >= GetNumContexts())
		index = GetNumContexts() - 1;

	while (count < index)
	{
		++i;
		++count;
	}

	if (i == contexts.end())
		return NULL;

	return (*i).second;
}
static Context *
getContext(unsigned long long ctx) {
    if (ctx == 0) {
        return NULL;
    }

    ContextMap::const_iterator it;
    it = context_map.find(ctx);
    if (it == context_map.end()) {
        Context *context;
        context_map[ctx] = context = glretrace::createContext(sharedContext);
        if (!sharedContext) {
            sharedContext = context;
        }
        return context;
    }

    return it->second;
}
Exemple #25
0
void Shutdown()
{
	// Notify all plugins we're being shutdown.
	PluginRegistry::Instance()->NotifyShutdown();

	// Release all remaining contexts.
	for (ContextMap::iterator itr = contexts.begin(); itr != contexts.end(); ++itr)
		Core::Log::Message(Log::LT_WARNING, "Context '%s' still active on shutdown.", (*itr).first.CString());
	contexts.clear();

	TemplateCache::Shutdown();
	StyleSheetFactory::Shutdown();
	StyleSheetSpecification::Shutdown();
	FontDatabase::Shutdown();
	TextureDatabase::Shutdown();
	Factory::Instance()->Shutdown();
  Factory::DestroyInstance();

	Log::Shutdown();

  PluginRegistry::DestroyInstance();
  PropertyParserColour::DestroyInstance();
  PropCounterSingleton::DestroyInstance();

	initialised = false;

	if (render_interface != NULL)
		render_interface->RemoveReference();

	if (file_interface != NULL)
		file_interface->RemoveReference();

	if (system_interface != NULL)
		system_interface->RemoveReference();
	
	render_interface = NULL;
	file_interface = NULL;
	system_interface = NULL;
}
Exemple #26
0
TEST_F(ContextMapTest, VerifySimple) {
  ContextMap<string> mp;

  // Create a new context and add it to the map:
  {
    AutoCreateContext context;

    // Verify the reference count or the rest of the test will fail
    ASSERT_EQ(context.use_count(), 1) << "A newly created context's use count isn't what was expected";

    // Add and ensure the reference count is unmodified
    mp.Add("context_simple", context);
    ASSERT_EQ(context.use_count(), 1) << "The map altered the context use count";

    // We should be able to find this context now:
    std::shared_ptr<CoreContext> found = mp.Find("context_simple");
    EXPECT_TRUE(!!found.get()) << "Failed to find a context that was just inserted into a context map";
  }

  // We shouldn't be able to find it now that it's gone out of scope:
  std::shared_ptr<CoreContext> notFound = mp.Find("context_simple");
  EXPECT_FALSE(!!notFound.get()) << "Context was not evicted as expected when it went out of scope";
}
Exemple #27
0
int map_main(int argc, char* argv[]) {

    ContextMap *context = new ContextMap();
    if (!context->parseCmdArgs(argc, argv, 1) || context->getShowHelp() || !context->isValidState()) {
        if (!context->getErrorMsg().empty()) {
            cerr << context->getErrorMsg() << endl;
        }
        map_help();
        delete context;
        return 0;
    }
    FileMap *fileMap = new FileMap(context);

    bool retVal = fileMap->mapFiles();
    delete fileMap;
    delete context;
    return retVal ? 0 : 1;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_READ
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: the context the driver returned to
 *      the client in OnOpenResource.
 *  - WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ: the number of bytes to
 *      read from the resource.
 *
 *  The driver should:
 *  - Read data associated with the resource and return it back to the caller in
 *      WPD_PROPERTY_OBJECT_RESOURCES_DATA.
 *  - Report the number of bytes actually read from the resource in
 *      WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ.  This number may be smaller
 *      than WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ when reading the last
 *      chunk of data from the resource.
 */
HRESULT WpdObjectResources::OnReadResource(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT                   hr                 = S_OK;
    LPWSTR                    wszResourceContext = NULL;
    DWORD                     dwNumBytesToRead   = 0;
    DWORD                     dwNumBytesRead     = 0;
    BYTE*                     pBuffer            = NULL;
    DWORD                     cbBuffer           = 0;
    WpdObjectResourceContext* pResourceContext   = NULL;
    ContextMap*               pContextMap        = NULL;

    // Get the enumeration context identifier for this enumeration operation.  We will
    // need this to lookup the specific enumeration context in the client context map.
    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &wszResourceContext);
    if (hr != S_OK)
    {
        hr = E_INVALIDARG;
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT");
    }

    // Get the number of bytes to read
    if (hr == S_OK)
    {
        hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ, &dwNumBytesToRead);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ");
    }

    // Get the destination buffer
    if (hr == S_OK)
    {
        hr = pParams->GetBufferValue(WPD_PROPERTY_OBJECT_RESOURCES_DATA, &pBuffer, &cbBuffer);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_DATA");
    }

    // Get the client context map so we can retrieve the resource context for this resource
    // operation using the WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT property value obtained above.
    if (hr == S_OK)
    {
        hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap);
        CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP");
    }

    if (hr == S_OK)
    {
        pResourceContext = (WpdObjectResourceContext*)pContextMap->GetContext(wszResourceContext);
        if (pResourceContext == NULL)
        {
            hr = E_INVALIDARG;
            CHECK_HR(hr, "Missing resource context");
        }
    }

    // Read the next chunk of data for this request
    if (hr == S_OK && pBuffer != NULL)
    {
        hr = ReadDataFromResource(pResourceContext, pBuffer, dwNumBytesToRead, &dwNumBytesRead);
        CHECK_HR(hr, "Failed to read %d bytes from resource", dwNumBytesToRead);
    }

    if (hr == S_OK && pBuffer != NULL)
    {
        hr = pResults->SetBufferValue(WPD_PROPERTY_OBJECT_RESOURCES_DATA, pBuffer, dwNumBytesRead);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_DATA");
    }

    if (hr == S_OK)
    {
        hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ, dwNumBytesRead);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ");
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(wszResourceContext);

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(pBuffer);

    SAFE_RELEASE(pContextMap);

    return hr;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_OPEN
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: the object identifier of the
 *      object which contains the specified resource
 *
 *  - WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: the specified resource
 *      to open
 *
 *  - WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE: the access mode to which to
 *      open the specified resource
 *
 *  The driver should:
 *  - Create a new context for this resource operation.
 *  - Return an identifier for the context in WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT.
 *  - Set the optimal transfer size in WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE
 *
 */
HRESULT WpdObjectResources::OnOpenResource(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT     hr              = S_OK;
    LPWSTR      wszObjectID     = NULL;
    PROPERTYKEY Key             = WPD_PROPERTY_NULL;
    DWORD       dwMode          = STGM_READ;
    CAtlStringW strStrObjectID;
    CAtlStringW strResourceContext;
    ContextMap* pContextMap     = NULL;

    // Get the Object identifier of the object which contains the specified resource
    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID, &wszObjectID);
    if (hr != S_OK)
    {
        hr = E_INVALIDARG;
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID");
    }

    // Get the resource key
    if (hr == S_OK)
    {
        hr = pParams->GetKeyValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS, &Key);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS");
    }

    // Get the access mode
    if (hr == S_OK)
    {
        hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE, &dwMode);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE");
    }

    // Validate whether the params given to us are correct.  In this case, we need to check that the object
    // supports the resource requested, and can be opened in the requested access mode.
    if (hr == S_OK)
    {
        // In this sample, we only have one object (README_FILE_OBJECT_ID) which supports a
        // resource (WPD_RESOURCE_DEFAULT) for reading only.
        // So if any other Object ID or any other resource is specified, it must be invalid.
        strStrObjectID = wszObjectID;
        if(strStrObjectID.CompareNoCase(README_FILE_OBJECT_ID) != 0)
        {
            hr = E_INVALIDARG;
            CHECK_HR(hr, "Object [%ws] does not support resources", wszObjectID);
        }
        if (hr == S_OK)
        {
            if (!IsEqualPropertyKey(Key, WPD_RESOURCE_DEFAULT))
            {
                hr = E_INVALIDARG;
                CHECK_HR(hr, "Only WPD_RESOURCE_DEFAULT is supported in this sample driver");
            }
        }
        if (hr == S_OK)
        {
            if ((dwMode & STGM_WRITE) != 0)
            {
                hr = E_ACCESSDENIED;
                CHECK_HR(hr, "This resource is not available for write access");
            }
        }
    }

    // Get the context map which the driver stored in pParams for convenience
    if (hr == S_OK)
    {
        hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap);
        CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP");
    }

    // Create a new resource operation context, initialize it, and add it to the client context map.
    if (hr == S_OK)
    {
        WpdObjectResourceContext* pResourceContext = new WpdObjectResourceContext();
        if (pResourceContext != NULL)
        {
            // Initialize the resource context with ...
            pResourceContext->m_strObjectID      = wszObjectID;
            pResourceContext->m_Resource         = Key;
            pResourceContext->m_BytesTransferred = 0;
            pResourceContext->m_BytesTotal       = GetObjectSize(wszObjectID);

            // Add the resource context to the context map
            pContextMap->Add(pResourceContext, strResourceContext);

            // Release the resource context because it has been AddRef'ed during Add()
            SAFE_RELEASE(pResourceContext);
        }
        else
        {
            hr = E_OUTOFMEMORY;
            CHECK_HR(hr, "Failed to allocate resource context");
        }
    }

    if (hr == S_OK)
    {
        hr = pResults->SetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, strResourceContext);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT");
    }

    // Set the optimal buffer size
    if (hr == S_OK)
    {
        hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE, FILE_OPTIMAL_READ_BUFFER_SIZE_VALUE);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE value");
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(wszObjectID);

    SAFE_RELEASE(pContextMap);

    return hr;
}
Exemple #30
0
		virtual void OnContextDestroy(Context* context)
		{
			contexts.erase(context->GetName());
		}