CAtlModule类的实现

CAtlModule类的实现:

=======================   dll   =======================
template   <class   T>
class   ATL_NO_VTABLE   CAtlDllModuleT   :   public   CAtlModuleT <T>
{
public   :
.....
}

=======================   exe   =======================
template   <class   T>
class   ATL_NO_VTABLE   CAtlExeModuleT   :   public   CAtlModuleT <T>
{
public   :
.....
}

=======================   service   =======================
template   <class   T,   UINT   nServiceNameID>
class   ATL_NO_VTABLE   CAtlServiceModuleT   :   public   CAtlExeModuleT <T>
{
public   :
.....
}

=======================   others   =======================
template   <class   T>
class   ATL_NO_VTABLE   CAtlExeModuleT   :   public   CAtlModuleT <T>
{
public   :
.....
}

template   <class   T>
class   ATL_NO_VTABLE   CAtlModuleT   :   public   CAtlModule
{
public   :
.....
}

class   ATL_NO_VTABLE   CAtlModule   :   public   _ATL_MODULE
{
public   :
.....
}

typedef   _ATL_MODULE70   _ATL_MODULE;

struct   _ATL_MODULE70
{
UINT   cbSize;
LONG   m_nLockCnt;
_ATL_TERMFUNC_ELEM*   m_pTermFuncs;
CComCriticalSection   m_csStaticDataInitAndTypeInfo;
};

类继承关系图:
_ATL_MODULE
        ¦
        ¦
CAtlModule  
        ¦
        ¦
CAtlModuleT   ------>   CAtlDllModuleT
        ¦
        ¦
CAtlExeModuleT   ----->   CAtlServiceModuleT 

CAtlModule类的函数分布:

=======================    CAtlModule    =======================  
class    ATL_NO_VTABLE   CAtlModule   :    public    _ATL_MODULE 

public    : 
static    GUID   m_libid; 
IGlobalInterfaceTable
*    m_pGIT; 

CAtlModule()   
throw (){   ...   } 
void    Term()    throw (){   ...   } 
~ CAtlModule()    throw (){   ...   } 
virtual    LONG   Lock()    throw (){   ...   } 
virtual    LONG   Unlock()    throw (){   ...   } 
virtual    LONG   GetLockCount()    throw (){   ...   } 
HRESULT   AddTermFunc(_ATL_TERMFUNC
*    pFunc,   DWORD_PTR   dw)    throw (){   ...   } 
virtual    HRESULT   GetGITPtr(IGlobalInterfaceTable **    ppGIT)    throw (){   ...   } 
virtual    HRESULT   AddCommonRGSReplacements(IRegistrarBase *     /* pRegistrar */ )    throw ()    =     0

//    Resource-based   Registration 
#ifdef   _ATL_STATIC_REGISTRY 
//    Statically   linking   to   Registry   Ponent 
HRESULT   WINAPI   UpdateRegistryFromResourceS(LPCTSTR   lpszRes,   BOOL   bRegister, 
struct    _ATL_REGMAP_ENTRY *    pMapEntries    =    NULL)    throw (); 
HRESULT   WINAPI   UpdateRegistryFromResourceS(UINT   nResID,   BOOL   bRegister, 
struct    _ATL_REGMAP_ENTRY *    pMapEntries    =    NULL)    throw (); 
#else  
HRESULT   WINAPI   UpdateRegistryFromResourceD(LPCTSTR   lpszRes,   BOOL   bRegister, 
struct    _ATL_REGMAP_ENTRY *    pMapEntries    =    NULL)    throw (){   ...   } 
HRESULT   WINAPI   UpdateRegistryFromResourceD(UINT   nResID,   BOOL   bRegister, 
struct    _ATL_REGMAP_ENTRY *    pMapEntries    =    NULL)    throw (){   ...   } 
#endif  

//    Implementation 
#if    !defined(_ATL_STATIC_REGISTRY) 
inline   HRESULT   WINAPI   UpdateRegistryFromResourceDHelper(LPCOLESTR   lpszRes,   BOOL   bRegister, 
struct    _ATL_REGMAP_ENTRY *    pMapEntries    =    NULL)    throw (){   ...   } 
#endif  

static     void    EscapeSingleQuote(LPOLESTR   lpDest,   LPCOLESTR   lp)    throw (){   ...   } 

//    search   for   an   occurence   of   string   p2   in   string   p1 
static    LPCTSTR   FindOneOf(LPCTSTR   p1,   LPCTSTR   p2)    throw (){   ...   } 
static     int    WordCmpI(LPCTSTR   psz1,   LPCTSTR   psz2)    throw (){   ...   } 
}; 

 在CAtlModule   中出现了熟悉的Lock和Unlock,都为虚函数。
virtual   LONG   Lock()   throw()
{
            return   CComGlobalsThreadModel::Increment(&m_nLockCnt);
}

virtual   LONG   Unlock()   throw()
{
            return   CComGlobalsThreadModel::Decrement(&m_nLockCnt);
}

=======================    CAtlModuleT    =======================  
template   
< class    T >  
class    ATL_NO_VTABLE   CAtlModuleT   :    public    CAtlModule 

public    : 
CAtlModuleT()   
throw (){   ...   } 
static     void    InitLibId()    throw (){   ...   } 
HRESULT   RegisterServer(BOOL   bRegTypeLib   
=    FALSE,    const    CLSID *    pCLSID    =    NULL)    throw (){   ...   } 
HRESULT   UnregisterServer(BOOL   bUnRegTypeLib,   
const    CLSID *    pCLSID    =    NULL)    throw (){   ...   } 
static    HRESULT   WINAPI   UpdateRegistryAppId(BOOL    /* bRegister */ )    throw (){   ...   } 
HRESULT   RegisterAppId()   
throw (){   ...   } 
HRESULT   UnregisterAppId()   
throw (){   ...   } 
virtual    HRESULT   AddCommonRGSReplacements(IRegistrarBase *    pRegistrar)    throw (){   ...   } 
static    LPCOLESTR   GetAppId()    throw (){   ...   } 
}; 

 在CAtlModuleT中实现了RegisterServer,UnregisterServer,   RegisterAppId,   UpdateRegistryAppId ,UnregisterAppId

HRESULT   RegisterServer(BOOL   bRegTypeLib   =   FALSE,   const   CLSID*   pCLSID   =   NULL)   throw()
{
       pCLSID;
       bRegTypeLib;

       HRESULT   hr   =   S_OK; 

 #ifndef   _ATL_NO_COM_SUPPORT

       hr   =   _AtlComModule.RegisterServer(bRegTypeLib,   pCLSID); 

 #endif //   _ATL_NO_COM_SUPPORT


#ifndef   _ATL_NO_PERF_SUPPORT

       if   (SUCCEEDED(hr)   &&   _pPerfRegFunc   !=   NULL)
              hr   =   (*_pPerfRegFunc)(_AtlBaseModule.m_hInst);

#endif

        return   hr;
}

HRESULT   UnregisterServer(BOOL   bUnRegTypeLib,   const   CLSID*   pCLSID   =   NULL)   throw()
{
         bUnRegTypeLib;
         pCLSID;

         HRESULT   hr   =   S_OK;

#ifndef   _ATL_NO_PERF_SUPPORT

         if   (_pPerfUnRegFunc   !=   NULL)
                    hr   =   (*_pPerfUnRegFunc)();

#endif

#ifndef   _ATL_NO_COM_SUPPORT

        if   (SUCCEEDED(hr))
                   hr   =   _AtlComModule.UnregisterServer(bUnRegTypeLib,   pCLSID);

#endif //   _ATL_NO_COM_SUPPORT 

       return   hr;

}

static   HRESULT   WINAPI   UpdateRegistryAppId(BOOL   /*bRegister*/)   throw()
{
        return   S_OK;
}
HRESULT   RegisterAppId()   throw()
{
        return   T::UpdateRegistryAppId(TRUE);
}

HRESULT   UnregisterAppId()   throw()

       return   T::UpdateRegistryAppId(FALSE);
}

它们会在CAtlDllModuleT,CAtlExeModuleT和CAtlServiceModuleT中使用:
=======================   CAtlDllModuleT=======================
HRESULT   DllRegisterServer(BOOL   bRegTypeLib   =   TRUE)   throw()
{
       //   registers   object,   typelib   and   all   interfaces   in   typelib
       T*   pT   =   static_cast <T*> (this);
       HRESULT   hr   =   pT-> RegisterAppId();
       if   (SUCCEEDED(hr))
              hr   =   pT-> RegisterServer(bRegTypeLib);
        return   hr;
}

HRESULT   DllUnregisterServer(BOOL   bUnRegTypeLib   =   TRUE)   throw()
{
        T*   pT   =   static_cast <T*> (this);
        HRESULT   hr   =   pT-> UnregisterServer(bUnRegTypeLib);
        if   (SUCCEEDED(hr))
              hr   =   pT-> UnregisterAppId();
        return   hr;
}
=======================   CAtlExeModuleT   =======================
//   Parses   the   command   line   and   registers/unregisters   the   rgs   file   if   necessary
bool   ParseCommandLine(LPCTSTR   lpCmdLine,   HRESULT*   pnRetCode)   throw()
{
        *pnRetCode   =   S_OK;

        TCHAR   szTokens[]   =   _T( "-/ ");

        T*   pT   =   static_cast <T*> (this); 
        LPCTSTR   lpszToken   =   FindOneOf(lpCmdLine,   szTokens);
        while   (lpszToken   !=   NULL)
        {
               if   (WordCmpI(lpszToken,   _T( "UnregServer "))==0)
               {
                       *pnRetCode   =   pT-> UnregisterServer(TRUE);
                       if   (SUCCEEDED(*pnRetCode))
                             *pnRetCode   =   pT-> UnregisterAppId(); 
                       return   false;
               }

               //   Register   as   Local   Server
               if   (WordCmpI(lpszToken,   _T( "RegServer "))==0)
               {
                       *pnRetCode   =   pT-> RegisterAppId();
                       if   (SUCCEEDED(*pnRetCode))
                                *pnRetCode   =   pT-> RegisterServer(TRUE);
                       return   false;
               }

               lpszToken   =   FindOneOf(lpszToken,   szTokens);
        } 

        return   true;
}

=======================   CAtlServiceModuleT   =======================

//   Parses   the   command   line   and   registers/unregisters   the   rgs   file   if   necessary
bool   ParseCommandLine(LPCTSTR   lpCmdLine,   HRESULT*   pnRetCode)   throw()
{
         if   (!CAtlExeModuleT <T> ::ParseCommandLine(lpCmdLine,   pnRetCode))
               return   false;

         TCHAR   szTokens[]   =   _T( "-/ ");
         *pnRetCode   =   S_OK;

         T*   pT   =   static_cast <T*> (this);
         LPCTSTR   lpszToken   =   FindOneOf(lpCmdLine,   szTokens); 
         while   (lpszToken   !=   NULL) 
         {
                if   (WordCmpI(lpszToken,   _T( "Service "))==0) 
                {
                       *pnRetCode   =   pT-> RegisterAppId(true);
                       if   (SUCCEEDED(*pnRetCode))
                              *pnRetCode   =   pT-> RegisterServer(TRUE);
                       return   false;
                }
                lpszToken   =   FindOneOf(lpszToken,   szTokens);
         }
         return   true;
}

 

=======================    CAtlDllModuleT    =======================  
template   
< class    T >  
class    ATL_NO_VTABLE   CAtlDllModuleT   :    public    CAtlModuleT  < T >  

public    : 
CAtlDllModuleT()   
throw (){   ...   } 
~ CAtlDllModuleT()    throw (){   ...   } 
BOOL   WINAPI   DllMain(DWORD   dwReason,   LPVOID   
/*    lpReserved    */ )    throw (){   ...   } 
HRESULT   DllCanUnloadNow()   
throw (){   ...   } 
HRESULT   DllGetClassObject(REFCLSID   rclsid,   REFIID   riid,   LPVOID
*    ppv)    throw (){   ...   } 
HRESULT   DllRegisterServer(BOOL   bRegTypeLib   
=    TRUE)    throw (){   ...   } 
HRESULT   DllUnregisterServer(BOOL   bUnRegTypeLib   
=    TRUE)    throw (){   ...   } 

//    Obtain   a   Class   Factory 
HRESULT   GetClassObject(REFCLSID   rclsid,   REFIID   riid,   LPVOID *    ppv)    throw (){   ...   } 
}; 

CAtlDllModuleT   在中实现了更加熟悉的DllMain,DllCanUnloadNow,   DllGetClassObject,   DllRegisterServer,   DllUnregisterServer和   GetClassObject

BOOL   WINAPI   DllMain(DWORD   dwReason,   LPVOID   /*   lpReserved   */)   throw()
{
        if   (dwReason   ==   DLL_PROCESS_ATTACH)
        {
              if   (CAtlBaseModule::m_bInitFailed)
              {
                    ATLASSERT(0); 
                    return   FALSE;
              }
             _AtlBaseModule.m_eDllInitializationStage   =   Dll_Process_attached;

#ifdef   _ATL_MIN_CRT
            DisableThreadLibraryCalls(_AtlBaseModule.GetModuleInstance());
#endif 
      }
      else   if   (dwReason   ==   DLL_PROCESS_DETACH)
     {
            _AtlBaseModule.m_eDllInitializationStage   =   Dll_Process_detached;

#ifdef   _DEBUG
           //   Prevent   false   memory   leak   reporting.   ~CAtlWinModule   may   be   too   late.
           _AtlWinModule.Term();
#endif //   _DEBUG

     }

     return   TRUE;         //   ok
}

HRESULT   DllCanUnloadNow()   throw()
{
     T*   pT   =   static_cast <T*> (this);
     return   (pT-> GetLockCount()==0)   ?   S_OK   :   S_FALSE;
}

HRESULT   DllGetClassObject(REFCLSID   rclsid,   REFIID   riid,   LPVOID*   ppv)   throw()
{
      T*   pT   =   static_cast <T*> (this);
      return   pT-> GetClassObject(rclsid,   riid,   ppv);
}

HRESULT   DllRegisterServer(BOOL   bRegTypeLib   =   TRUE)   throw()
{
      //   registers   object,   typelib   and   all   interfaces   in   typelib
      T*   pT   =   static_cast <T*> (this);
      HRESULT   hr   =   pT-> RegisterAppId();
      if   (SUCCEEDED(hr))
      hr   =   pT-> RegisterServer(bRegTypeLib);
      return   hr;
}

HRESULT   DllUnregisterServer(BOOL   bUnRegTypeLib   =   TRUE)   throw()
{
     T*   pT   =   static_cast <T*> (this);
     HRESULT   hr   =   pT-> UnregisterServer(bUnRegTypeLib);
     if   (SUCCEEDED(hr))
          hr   =   pT-> UnregisterAppId();
     return   hr;
}

//   Obtain   a   Class   Factory
HRESULT   GetClassObject(REFCLSID   rclsid,   REFIID   riid,   LPVOID*   ppv)   throw()
{

#ifndef   _ATL_OLEDB_CONFORMANCE_TESTS
      ATLASSERT(ppv   !=   NULL);
#endif

       return   AtlComModuleGetClassObject(&_AtlComModule,   rclsid,   riid,   ppv);
}

=======================    CAtlExeModuleT    =======================  
template   
< class    T >  
class    ATL_NO_VTABLE   CAtlExeModuleT   :    public    CAtlModuleT  < T >  

public    : 
#ifndef   _ATL_NO_COM_SUPPORT 

DWORD   m_dwMainThreadID; 
HANDLE   m_hEventShutdown; 
DWORD   m_dwTimeOut; 
DWORD   m_dwPause; 
bool    m_bDelayShutdown; 
bool    m_bActivity; 

#endif     //    _ATL_NO_COM_SUPPORT 

CAtlExeModuleT()   
throw (){   ...   } 
~ CAtlExeModuleT()    throw (){   ...   } 
static    HRESULT   InitializeCom()    throw (){   ...   } 
static     void    UninitializeCom()    throw (){   ...   } 
LONG   Unlock()   
throw (){   ...   } 
void    MonitorShutdown()    throw (){   ...   } 
HANDLE   StartMonitor()   
throw (){   ...   } 
static    DWORD   WINAPI   MonitorProc( void *    pv)    throw (){   ...   } 
int    WinMain( int    nShowCmd)    throw (){   ...   } 

//    Scan   command   line   and   perform   registration 
//    Return   value   specifies   if   server   should   run 

//    Parses   the   command   line   and   registers/unregisters   the   rgs   file   if   necessary 
bool    ParseCommandLine(LPCTSTR   lpCmdLine,   HRESULT *    pnRetCode)    throw (){   ...   } 
HRESULT   PreMessageLoop(
int     /* nShowCmd */ )    throw (){   ...   } 
HRESULT   PostMessageLoop()   
throw (){   ...   } 
void    RunMessageLoop()    throw (){   ...   } 
HRESULT   Run(
int    nShowCmd    =    SW_HIDE)    throw (){   ...   } 

//    Register/Revoke   All   Class   Factories   with   the   OS   (EXE   only) 
HRESULT   RegisterClassObjects(DWORD   dwClsContext,   DWORD   dwFlags)    throw (){   ...   } 
HRESULT   RevokeClassObjects()   
throw (){   ...   } 
}; 

 CAtlExeModuleT重新实现了自己的Unlock
LONG   Unlock()   throw()
{
         LONG   lRet   =   CComGlobalsThreadModel::Decrement(&m_nLockCnt);

         #ifndef   _ATL_NO_COM_SUPPORT

         if   (lRet   ==   0)
         {
                if   (m_bDelayShutdown)
               {
                         m_bActivity   =   true;
                         ::SetEvent(m_hEventShutdown);   //   tell   monitor   that   we   transitioned   to   zero
               }
               else
               {
                        ::PostThreadMessage(m_dwMainThreadID,   WM_QUIT,   0,   0);
                }
         }

        #endif //   _ATL_NO_COM_SUPPORT

          return   lRet;
}

=======================    CAtlServiceModuleT    =======================  
template   
< class    T,   UINT   nServiceNameID >  
class    ATL_NO_VTABLE   CAtlServiceModuleT   :    public    CAtlExeModuleT  < T >  

public    : 

CAtlServiceModuleT()   
throw (){   ...   } 
int    WinMain( int    nShowCmd)    throw (){   ...   } 
HRESULT   Start(
int    nShowCmd)    throw (){   ...   } 
inline   HRESULT   RegisterAppId(
bool    bService    =     false )    throw (){   ...   } 
HRESULT   UnregisterAppId()   
throw (){   ...   } 

//    Parses   the   command   line   and   registers/unregisters   the   rgs   file   if   necessary 
bool    ParseCommandLine(LPCTSTR   lpCmdLine,   HRESULT *    pnRetCode)    throw (){   ...   } 
void    ServiceMain(DWORD   dwArgc,   LPTSTR *    lpszArgv)    throw (){   ...   } 
HRESULT   Run(
int    nShowCmd    =    SW_HIDE)    throw (){   ...   } 
HRESULT   PreMessageLoop(
int    nShowCmd)    throw (){   ...   } 

//    This   function   provides   the   default   security   settings   for   your   service, 
//    you   should   overide   this   in   your   specific   service   module   class   to   change 
//    as   appropriate.     By   default,   this   will   allow   any   caller   and   calls   will   be 
//    on   the   callers   security   token   (impersonated). 
HRESULT   InitializeSecurity()    throw (){   ...   } 

void    OnStop()    throw (){   } 

void    OnPause()    throw (){   } 
void    OnContinue()    throw (){   } 
void    OnInterrogate()    throw (){   } 
void    OnShutdown()    throw (){   } 
void    OnUnknownRequest(DWORD    /* dwOpcode */ )    throw (){   ...   } 
void    Handler(DWORD   dwOpcode)    throw (){   ...   } 
BOOL   IsInstalled()   
throw (){   ...   } 
BOOL   Install()   
throw (){   ...   } 
BOOL   Uninstall()   
throw (){   ...   } 
LONG   Unlock()   
throw (){   ...   } 
void    LogEventEx( int    id,   LPCTSTR   pszMessage = NULL,   WORD   type    =    EVENTLOG_INFORMATION_TYPE)    throw (){   ...   } 
void    __cdecl   LogEvent(LPCTSTR   pszFormat,   ...)    throw (){   ...   } 
void    SetServiceStatus(DWORD   dwState)    throw (){   ...   } 

// Implementation 
protected
static     void    WINAPI   _ServiceMain(DWORD   dwArgc,   LPTSTR *    lpszArgv)    throw (){   ...   } 
static     void    WINAPI   _Handler(DWORD   dwOpcode)    throw (){   ...   } 

//    data   members 
public
TCHAR   m_szServiceName[
256 ]; 
SERVICE_STATUS_HANDLE   m_hServiceStatus; 
SERVICE_STATUS   m_status; 
BOOL   m_bService; 
DWORD   m_dwThreadID; 
}; 

CAtlServiceModuleT也重新实现了自己的Unlock
LONG   Unlock()   throw()
{
       LONG   lRet;
       if   (m_bService)
      {
            //   We   are   running   as   a   service,   therefore   transition   to   zero   does   not
            //   unload   the   process
           lRet   =   CAtlModuleT <T> ::Unlock();
      }
      else
      {
          //   We   are   running   as   EXE,   use   MonitorShutdown   logic   provided   by   CExeModule
          lRet   =   CAtlExeModuleT <T> ::Unlock();
      }
      return   lRet;
}

在CAtlServiceModuleT中实现了InitializeSecurity,   LogEventEx和SetServiceStatus
//   This   function   provides   the   default   security   settings   for   your   service,
//   you   should   overide   this   in   your   specific   service   module   class   to   change
//   as   appropriate.     By   default,   this   will   allow   any   caller   and   calls   will   be
//   on   the   callers   security   token   (impersonated).
HRESULT   InitializeSecurity()   throw()
{
        return   CoInitializeSecurity(NULL,   -1,   NULL,   NULL,   RPC_C_AUTHN_LEVEL_PKT,   RPC_C_IMP_LEVEL_IMPERSONATE,   NULL,   EOAC_NONE,   NULL);
}

void   LogEventEx(int   id,   LPCTSTR   pszMessage=NULL,   WORD   type   =   EVENTLOG_INFORMATION_TYPE)   throw()
{
       HANDLE   hEventSource; 
       if   (m_szServiceName)
       {
              /*   Get   a   handle   to   use   with   ReportEvent().   */
              hEventSource   =   RegisterEventSource(NULL,   m_szServiceName); 
              if   (hEventSource   !=   NULL)
              {
                    /*   Write   to   event   log.   */
                   ReportEvent(hEventSource,  
                   type,
                   (WORD)0,
                   id,
                   NULL,
                   (WORD)(pszMessage   !=   NULL   ?   1   :   0),
                   0,
                   pszMessage   !=   NULL   ?   &pszMessage   :   NULL,
                   NULL);
                   DeregisterEventSource(hEventSource);
             }
      }
}

void   __cdecl   LogEvent(LPCTSTR   pszFormat,   ...)   throw()
{
       TCHAR   chMsg[256]; 
       HANDLE   hEventSource;
       LPTSTR   lpszStrings[1];
       va_list   pArg;

       va_start(pArg,   pszFormat);
       _vstprintf(chMsg,   pszFormat,   pArg);
       va_end(pArg);

       lpszStrings[0]   =   chMsg;

       if   (!m_bService)
       {
             //   Not   running   as   a   service,   so   print   out   the   error   message  
             //   to   the   console   if   possible
             _putts(chMsg);
       }

       /*   Get   a   handle   to   use   with   ReportEvent().   */
       hEventSource   =   RegisterEventSource(NULL,   m_szServiceName); 
       if   (hEventSource   !=   NULL)
       {
              /*   Write   to   event   log.   */
              ReportEvent(hEventSource,   EVENTLOG_INFORMATION_TYPE,   0,   0,   NULL,   1,   0,   (LPCTSTR*)   &lpszStrings[0],   NULL);
              DeregisterEventSource(hEventSource);
       }
}
void   SetServiceStatus(DWORD   dwState)   throw()
{
       m_status.dwCurrentState   =   dwState;
       ::SetServiceStatus(m_hServiceStatus,   &m_status);
}

你可能感兴趣的:(struct,service,Module,null,Class,winapi)