📄 serdmaplugin.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "aygshell.h"
#include <ras.h>
#include <resource.h>
#include "SERDMAPlugIn.h"
#include "SERDMAASGUID.h"
#define ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))
static const GUID g_guidCSERDMAPlugin = __uuidof(CLS_CSERDMAPlugin);
static LONG s_clockDLL = 0;
static LONG s_crefDLL = 0;
//Context Menu registry entries
const WCHAR c_wszRegKey[] = L"SOFTWARE\\Microsoft\\Shell\\Extensions\\ContextMenus\\ActiveSync\\ActiveSyncConnect\\{f672ddb2-bb6f-4b8c-b580-e8b71758e394}";
const WCHAR c_wszDelay[] = L"DelayLoad";
//COM registration
const WCHAR c_wszCLSID[] = L"CLSID\\{f672ddb2-bb6f-4b8c-b580-e8b71758e394}\\InProcServer32";
WCHAR c_wszDll[] = L"SERDMAASPlugIn.dll";
const CHAR c_szCommand[] = "CONNECT"; //Invoke command
const WCHAR c_wszRnaCmdParam[] = L"-n -m -e\"%s\""; //RNAAPP command line options
WCHAR c_wszSERDMAReplEntryName[] = L"`DMA Default"; //move to resource file for localization
const WCHAR c_wszRnaApp[] = L"rnaapp.exe";
const WCHAR c_wszDialog[] = L"Dialog"; //RNAAPP dialog window
const WCHAR c_wszReplWnd[] = L"ReplLog"; //Sync Application
WCHAR c_wszSERDMALineDeviceFriendlyName[] = L"Serial over DMA"; // This is the FriendlyName string from HKLM\Drivers\SERDMA
HINSTANCE g_hInstance;
// ******************************************************************************************
//
// DLL entry point
//
// ******************************************************************************************
BOOL WINAPI DllMain(HANDLE hinstDll, DWORD dwReason, LPVOID /*lpReserved*/)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstance = (HINSTANCE)hinstDll;
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//********************************************************************************************
// CClassFactory::QueryInterface
//
// Purpose:
// Standard QI. We support IClassFactory and IUnknown.
//
// Parameters:
// riid = INPUT - IID of interface to QI for
// ppvObj = OUTPUT - where interface point is placed
//
// Returns:
// HRESULT indicating success
//********************************************************************************************
HRESULT CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
{
if ((riid == IID_IUnknown) || (riid == IID_IClassFactory))
{
*ppvObj = this;
AddRef();
return S_OK;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
}
//********************************************************************************************
// CClassFactory::AddRef
//
// Purpose: Increments the reference count by one
//
// Returns:
// ULONG indicating current ref count
//********************************************************************************************
ULONG CClassFactory::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
//********************************************************************************************
// CClassFactory::Release
//
// Purpose:
// Decrements the reference count by one, and destroys the object if there are no more
// references.
//
// Returns:
// ULONG indicating current ref count
//********************************************************************************************
ULONG CClassFactory::Release(void)
{
ULONG RefCount;
RefCount = InterlockedDecrement(&m_cRef);
if (RefCount==0)
{
delete this;
}
return RefCount;
}
//********************************************************************************************
// CClassFactory::CreateInstance
//
// Purpose:
// Created a instance of a class
//
// Parameters:
// pUnkOuter = INPUT - Outer object
// riid = INPUT - Class id on the object to create
// ppvObj = OUTPUT - new object created
//
// Returns:
// HRESULT indicating success
//********************************************************************************************
HRESULT CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID FAR* ppvObj)
{
HRESULT Result;
if (pUnkOuter)
{
Result=E_INVALIDARG; // No aggregations
}
else
{
IUnknown *punk = new CSERDMAPlugIn();
if (punk)
{
Result = punk->QueryInterface(riid, ppvObj);
punk->Release();
}
else
{
Result = E_OUTOFMEMORY;
}
}
return Result;
}
//********************************************************************************************
// CClassFactory::LockServer
//
// Purpose:
// Called by the client of a class object to keep a server open in memory,
// allowing instances to be created more quickly.
//
// Parameters:
// fLock = INPUT - If TRUE, increments the lock count; if FALSE, decrements the lock count.
//
// Returns:
// HRESULT indicating success
//********************************************************************************************
STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
InterlockedIncrement(&s_clockDLL);
}
else
{
InterlockedDecrement(&s_clockDLL);
}
return NOERROR;
}
//********************************************************************************************
// DllAddRef
//
// Purpose: Increments the reference count by one
//
//********************************************************************************************
STDAPI_(ULONG) DllAddRef(void)
{
ULONG ulRet = InterlockedIncrement(&s_crefDLL);
ASSERT(ulRet < 1000); // reasonable upper limit
return ulRet;
}
//********************************************************************************************
// DllRelease
//
// Purpose:
// Decrements the reference count by one
//
//********************************************************************************************
STDAPI_(ULONG) DllRelease(void)
{
ULONG ulRet = InterlockedDecrement(&s_crefDLL);
ASSERT(ulRet >= 0); // don't underflow
return ulRet;
}
//********************************************************************************************
// DllRelease
//
// Purpose:
// This function determines whether the dynamic-link library (DLL) that implements this
// function is in use. If it is not, the caller can safely unload the DLL from memory.
//
//********************************************************************************************
STDAPI DllCanUnloadNow()
{
HRESULT Result = ResultFromScode((s_crefDLL == 0) && (s_clockDLL == 0) ? S_OK : S_FALSE);
return Result;
}
//********************************************************************************************
// DllRelease
//
// Purpose:
// This function retrieves the class object from a DLL object handler or object
// application. DllGetClassObject is called from within the CoGetClassObject function
// when the class context is a DLL.
//
// Parameters:
// rclsid = INPUT - CLSID that will associate the correct data and code.
// riid = INPUT - Reference to the identifier of the interface
// ppvObj = OUTPUT - Address of pointer variable that receives the interface pointer requested in riid
//
// Returns:
// HRESULT indicating success
//
//********************************************************************************************
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppvObj)
{
HRESULT Result;
*ppvObj = NULL;
if(g_guidCSERDMAPlugin != rclsid)
{
return CLASS_E_CLASSNOTAVAILABLE;
}
CClassFactory *pcf = new CClassFactory();
if (!pcf)
{
return E_OUTOFMEMORY;
}
// Note if the QueryInterface fails, the Release will delete the object
Result = pcf->QueryInterface(riid, ppvObj);
pcf->Release();
return Result;
}
extern "C" HRESULT WINAPI OneStopFactory(LPCWSTR /*pszType*/, IContextMenu ** ppObj)
{
*ppObj = new CSERDMAPlugIn;
if (*ppObj == NULL)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
//********************************************************************************************
// CSERDMAPlugIn::constructor
//********************************************************************************************
CSERDMAPlugIn::CSERDMAPlugIn() :
m_lRefCount(1),
pObjectWithSite(NULL)
{
DllAddRef();
}
//********************************************************************************************
// CSERDMAPlugIn::destructors
//********************************************************************************************
CSERDMAPlugIn::~CSERDMAPlugIn()
{
if(pObjectWithSite)
{
pObjectWithSite->Release();
}
DllRelease();
}
//********************************************************************************************
// CSERDMAPlugIn::QueryInterface
//
// Purpose:
// Standard QI. We support IMassNotifyLayer and IUnknown.
//
// Parameters:
// riid = INPUT - IID of interface to QI for
// ppv = OUTPUT - where interface point is placed
//
// Returns:
// HRESULT indicating success
//********************************************************************************************
STDMETHODIMP CSERDMAPlugIn::QueryInterface(REFIID riid, LPVOID *ppv)
{
HRESULT hr = S_OK;
//
// Check parameters
//
if (ppv == NULL)
{
hr = E_INVALIDARG;
goto Exit;
}
//
// Initialize [out] parameters
//
*ppv = NULL;
//
// Find IID
//
if (riid == IID_IUnknown)
{
*ppv = static_cast<IUnknown*>(this);
}
else if (riid == IID_IContextMenu) //IID_IContextMenu
{
*ppv = static_cast<IContextMenu*>(this);
}
else if (riid == IID_IObjectWithSite) //IID_IObjectWithSite
{
if(NULL == pObjectWithSite)
{
pObjectWithSite = new CSERDMAPlugSite;
if(NULL == pObjectWithSite)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
}
*ppv = static_cast<IObjectWithSite*>(pObjectWithSite);
}
else
{
hr = E_NOINTERFACE;
goto Exit;
}
//
// AddRef the outgoing interface
//
static_cast<IUnknown *>(*ppv)->AddRef();
hr = S_OK;
Exit:
return hr;
}
//********************************************************************************************
// CSERDMAPlugIn::AddRef
//
// Purpose:
// Standard IUnknown::AddRef() implementation.
//
// Returns:
// ULONG indicating ref count
//********************************************************************************************
STDMETHODIMP_(ULONG) CSERDMAPlugIn::AddRef(void)
{
return ::InterlockedIncrement(&m_lRefCount);
}
//********************************************************************************************
// CSERDMAPlugIn::Release
//
// Purpose:
// Standard IUnknown::Release implementation.
//
// Returns:
// ULONG indicating current ref count
//********************************************************************************************
STDMETHODIMP_(ULONG) CSERDMAPlugIn::Release(void)
{
if (::InterlockedDecrement(&m_lRefCount) == 0)
{
delete this;
return 0;
}
return m_lRefCount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -