?? mainmod.cpp
字號:
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*++
Module Name:
mainmod.cpp
Abstract:
Implementation of IReplStore
--*/
#include <windows.h>
#include "mainmod.h"
#define EXIT_ON_FAIL(hr) \
if (FAILED (hr)) \
{ \
goto Exit; \
} \
else
HINSTANCE v_hInst;
static char v_szStockFile[ MAX_PATH ];
static char v_szDBVol[ MAX_PATH ];
static UINT v_uSyncOpt;
static CStore *v_pStore;
BOOL WINAPI DllMain ( HANDLE hInstDll, ULONG ulReason, LPVOID lpReserved )
{
switch( ulReason )
{
case DLL_PROCESS_ATTACH :
v_hInst = (HINSTANCE)hInstDll;
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
//
// ============ Required OLE implementation for InProc servers ======================
//
// CClassFactory object creates CStore objects
class CClassFactory : public IClassFactory
{
private:
LONG m_cRef;
public:
CClassFactory( void ) : m_cRef( 0 ) {};
virtual STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppv);
virtual STDMETHODIMP_(ULONG) AddRef();
virtual STDMETHODIMP_(ULONG) Release();
// IClassFactory members
virtual STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID*);
virtual STDMETHODIMP LockServer(BOOL);
};
// Count number of objects and number of locks
static LONG v_cObj = 0;
static LONG v_cLock = 0;
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory))
return CLASS_E_CLASSNOTAVAILABLE;
//return our IClassFactory for CStore objects
*ppv = (LPVOID)new CClassFactory();
if ( NULL == *ppv )
return E_OUTOFMEMORY;
//AddRef the object through any interface we return
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
STDAPI DllCanUnloadNow(void)
{
return ResultFromScode( 0L == v_cObj && 0 == v_cLock? S_OK : S_FALSE );
}
HRESULT CreateValue (HKEY hkeyParent, char * szKey, char * szValueName, DWORD dwType,
void * pValue, DWORD dwLength)
{
HRESULT hr = E_UNEXPECTED;
LONG lResult;
HKEY hkey = NULL;
// create or open hkeyParent\szKey
lResult = ::RegCreateKeyEx (hkeyParent, szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hkey, NULL);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// create hkeyParent\szKey\szValueName = pValue
lResult = ::RegSetValueEx (hkey, szValueName, 0, dwType, reinterpret_cast <BYTE *> (pValue), dwLength);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// success
hr = S_OK;
Exit:
// close key
lResult = ::RegCloseKey (hkey);
if (SUCCEEDED (hr)) // only overwrite hr if we haven't already failed above
{
hr = HRESULT_FROM_WIN32 (lResult);
}
return hr;
}
//
// DllRegisterServer
// Called to register the provider with desktop sync
//
STDAPI DllRegisterServer (void)
{
LONG lResult;
HRESULT hr = E_UNEXPECTED;
HKEY hkey = NULL;
char szKey[1024];
char szTemp[1024];
HKEY hkeyGuidProvider = NULL;
char szFilename[_MAX_PATH];
DWORD dwDisabled;
DWORD dwVersion;
// open HKCR\CLSID
lResult = ::RegOpenKeyEx (HKEY_CLASSES_ROOT, "CLSID", 0, KEY_ALL_ACCESS, &hkey);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// create HKCR\CLSID\{guid}
lResult = ::RegCreateKeyEx (hkey, SZ_GUID_SYNCSAMPLE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hkeyGuidProvider, NULL);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// close HKCR\CLSID
lResult = ::RegCloseKey (hkey);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// create HKCR\CLSID\{guid}, default value = store name
lResult = ::RegSetValueEx (hkeyGuidProvider, NULL, 0, REG_SZ, (BYTE *) SZ_NAME, ::strlen (SZ_NAME) + 1);
hr = HRESULT_FROM_WIN32 (lResult);
EXIT_ON_FAIL (hr);
// create HKCR\CLSID\{guid}\InprocServer32, default value = (path to this DLL)
lResult = ::GetModuleFileName (v_hInst, szFilename, _MAX_PATH);
if (lResult == 0)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
hr = ::CreateValue (hkeyGuidProvider, "InprocServer32", NULL, REG_SZ, szFilename, ::strlen (szFilename) + 1);
EXIT_ON_FAIL (hr);
// create HKCR\CLSID\{our guid}\ProgID, default value = (progid)
hr = ::CreateValue (hkeyGuidProvider, "ProgID", NULL, REG_SZ, SZ_STORE_PROG_ID, ::strlen (SZ_STORE_PROG_ID) + 1);
EXIT_ON_FAIL (hr);
// create HKCR\(prog id), default value = (SZ_NAME)
// create HKCR\(prog id), "Display Name" =
// create HKCR\(prog id), "Version" = 0x00030000 // version 3 or better allows settings
// to be configured during partnership wiz
hr = ::CreateValue (HKEY_CLASSES_ROOT, SZ_STORE_PROG_ID, NULL, REG_SZ, SZ_NAME, ::strlen (SZ_NAME) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_CLASSES_ROOT, SZ_STORE_PROG_ID, "Display Name", REG_SZ, SZ_DISPLAY_NAME, ::strlen(SZ_DISPLAY_NAME) + 1);
EXIT_ON_FAIL (hr);
dwVersion = 0x00030000;
hr = ::CreateValue (HKEY_CLASSES_ROOT, SZ_STORE_PROG_ID, "Version", REG_DWORD, &dwVersion, sizeof (dwVersion));
EXIT_ON_FAIL (hr);
// create HKCR\(prog id)\CLSID, default value = (GUID)
::wsprintf (szKey, "%s\\CLSID", SZ_STORE_PROG_ID);
hr = ::CreateValue (HKEY_CLASSES_ROOT, szKey, NULL, REG_SZ, SZ_GUID_SYNCSAMPLE, ::strlen (SZ_GUID_SYNCSAMPLE) + 1);
EXIT_ON_FAIL (hr);
//
// Available on PocketPC and Smartphone only
// create HKLM\SOFTWARE\Microsoft\Windows CE Services\SpecialDefaults\PocketPC\
// Services\Synchronization\Objects\(SZ_NAME), (multiple values)
::wsprintf (szKey, "SOFTWARE\\Microsoft\\Windows CE Services\\SpecialDefaults\\PocketPC\\"
"Services\\Synchronization\\Objects\\%s", SZ_NAME);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, NULL, REG_SZ, SZ_NAME, ::strlen (SZ_NAME) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Store", REG_SZ, SZ_STORE_PROG_ID, ::strlen (SZ_STORE_PROG_ID) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Display Name", REG_SZ, SZ_DISPLAY_NAME, ::strlen (SZ_DISPLAY_NAME) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Plural Name", REG_SZ, SZ_PLURAL_NAME, ::strlen (SZ_PLURAL_NAME) + 1);
EXIT_ON_FAIL (hr);
dwDisabled = 0;
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Disabled", REG_DWORD, &dwDisabled, sizeof (dwDisabled));
EXIT_ON_FAIL (hr);
::wsprintf (szTemp, "%s,-%d", szFilename, IDI_ICON);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "DefaultIcon", REG_SZ, szTemp, ::strlen (szTemp) + 1);
EXIT_ON_FAIL (hr);
// create HKLM\SOFTWARE\Microsoft\Windows CE Services\SpecialDefaults\SmartPhone\
// Services\Synchronization\Objects\(SZ_NAME), (multiple values)
::wsprintf (szKey, "SOFTWARE\\Microsoft\\Windows CE Services\\SpecialDefaults\\SmartPhone\\"
"Services\\Synchronization\\Objects\\%s", SZ_NAME);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, NULL, REG_SZ, SZ_NAME, ::strlen (SZ_NAME) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Store", REG_SZ, SZ_STORE_PROG_ID, ::strlen (SZ_STORE_PROG_ID) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Display Name", REG_SZ, SZ_DISPLAY_NAME, ::strlen (SZ_DISPLAY_NAME) + 1);
EXIT_ON_FAIL (hr);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Plural Name", REG_SZ, SZ_PLURAL_NAME, ::strlen (SZ_PLURAL_NAME) + 1);
EXIT_ON_FAIL (hr);
dwDisabled = 0;
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "Disabled", REG_DWORD, &dwDisabled, sizeof (dwDisabled));
EXIT_ON_FAIL (hr);
::wsprintf (szTemp, "%s,-%d", szFilename, IDI_ICON);
hr = ::CreateValue (HKEY_LOCAL_MACHINE, szKey, "DefaultIcon", REG_SZ, szTemp, ::strlen (szTemp) + 1);
EXIT_ON_FAIL (hr);
hr = S_OK;
Exit:
return hr;
}
STDAPI DllUnregisterServer (void)
{
char szKey[1024];
::wsprintf (szKey, "CLSID\\%s\\ProgID", SZ_GUID_SYNCSAMPLE);
::RegDeleteKey (HKEY_CLASSES_ROOT, szKey);
::wsprintf (szKey, "CLSID\\%s\\InprocServer32", SZ_GUID_SYNCSAMPLE);
::RegDeleteKey (HKEY_CLASSES_ROOT, szKey);
::wsprintf (szKey, "CLSID\\%s", SZ_GUID_SYNCSAMPLE);
::RegDeleteKey (HKEY_CLASSES_ROOT, szKey);
::wsprintf (szKey, "%s\\CLSID", SZ_STORE_PROG_ID);
::RegDeleteKey (HKEY_CLASSES_ROOT, szKey);
::RegDeleteKey (HKEY_CLASSES_ROOT, SZ_STORE_PROG_ID);
::wsprintf (szKey, "SOFTWARE\\Microsoft\\Windows CE Services\\SpecialDefaults\\PocketPC\\"
"Services\\Synchronization\\Objects\\%s", SZ_NAME);
::RegDeleteKey (HKEY_LOCAL_MACHINE, szKey);
::wsprintf (szKey, "SOFTWARE\\Microsoft\\Windows CE Services\\SpecialDefaults\\SmartPhone\\"
"Services\\Synchronization\\Objects\\%s", SZ_NAME);
::RegDeleteKey (HKEY_LOCAL_MACHINE, szKey);
return S_OK;
}
STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)
{
*ppv=NULL;
if ( IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_IClassFactory ) )
*ppv=(LPVOID)this;
if( NULL != *ppv )
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CClassFactory::AddRef( void )
{
ULONG urc;
urc = (ULONG)InterlockedIncrement( &m_cRef );
return(urc);
}
STDMETHODIMP_(ULONG) CClassFactory::Release()
{
ULONG urc;
urc = (ULONG)InterlockedDecrement( &m_cRef );
if (urc == 0 )
delete this;
return urc;
}
STDMETHODIMP CClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppvObj )
{
CStore *pObj;
HRESULT hr;
DWORD dwLastError = 0;
*ppvObj = NULL;
hr = E_OUTOFMEMORY;
if ( NULL != pUnkOuter && !IsEqualIID( riid, IID_IUnknown ) )
return E_NOINTERFACE;
pObj = new CStore( pUnkOuter );
if ( NULL == pObj )
return E_OUTOFMEMORY;
hr = pObj->QueryInterface( riid, ppvObj );
InterlockedIncrement( &v_cObj );
if ( FAILED( hr ) )
{
delete pObj; // <-- this destroys LastError
if( dwLastError )
SetLastError( dwLastError );
}
return hr;
}
STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
{
if (fLock)
InterlockedIncrement( &v_cLock );
else
InterlockedDecrement( &v_cLock );
return NOERROR;
}
//
// ================== Basic Implementation of IReplStore ====================
//
/*++
--*/
CStore::CStore( LPUNKNOWN pUnkOuter )
{
m_cRef = 0;
m_pUnkOuter = pUnkOuter;
m_uFlags = 0;
m_pObjHandler = new CDataHandler( this );
m_rgpItems = NULL;
m_ixCurrItem = 0;
m_cItems = 0;
lstrcpy( m_szStockFile, SZ_DEFAULT_PORTFILE );
m_hFile = INVALID_HANDLE_VALUE;
m_hMapObj = NULL;
m_hMutex = NULL;
m_pStocks = NULL;
m_hListen = NULL;
m_hKillListen = CreateEvent( NULL, FALSE, FALSE, NULL );
m_hStockChg = CreateEvent( NULL, FALSE, FALSE, SZ_CHANGE_EVENT );
}
/*++
--*/
CStore::~CStore()
{
CloseHandle( m_hKillListen );
CloseHandle( m_hStockChg );
delete m_pObjHandler;
InterlockedDecrement( &v_cObj );
}
//
// ==================== IUnknown Implementation ===========================
//
/*++
--*/
STDMETHODIMP CStore::QueryInterface( REFIID iid, LPVOID *ppvObj )
{
*ppvObj = NULL; // set to NULL, in case we fail.
if ( IsEqualIID( iid, IID_IUnknown ) )
*ppvObj = (void*)this;
else if ( IsEqualIID( iid, IID_IReplStore ) )
*ppvObj = (void*)(IReplStore *)this;
else if ( IsEqualIID( iid, IID_IReplStore2 ) )
*ppvObj = (void*)(IReplStore2 *)this;
else if ( m_pUnkOuter )
return m_pUnkOuter->QueryInterface( iid, ppvObj );
if ( *ppvObj )
{
((IUnknown *)(*ppvObj))->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
/*++
--*/
STDMETHODIMP_(ULONG) CStore::AddRef()
{
ULONG urc;
if ( m_pUnkOuter )
urc = m_pUnkOuter->AddRef();
else
urc = (ULONG)InterlockedIncrement( &m_cRef );
return urc;
}
/*++
--*/
STDMETHODIMP_(ULONG) CStore::Release()
{
ULONG urc;
if ( m_pUnkOuter )
urc = m_pUnkOuter->Release();
else
{
urc =(ULONG)InterlockedDecrement( &m_cRef );
if ( urc == 0 )
delete this;
}
return urc;
}
//
// ================= thread listening to the changes/deletes in the Stock Portfolio app
//
DWORD WINAPI Listen( LPVOID pvStore )
{
CStore *pStore = (CStore *)pvStore;
DWORD dwObj;
HANDLE rgHandles[] = { pStore->m_hKillListen, pStore->m_hStockChg };
UINT ix, jx;
for ( ;; )
{
dwObj = WaitForMultipleObjects( 2, rgHandles, FALSE, INFINITE );
// will quit this thread for any other value
if ( dwObj != WAIT_OBJECT_0 + 1 )
break;
if ( !pStore->m_pNotify ) continue;
// get the change/delete log from the Stock Portfolio app
pStore->Lock();
for ( ix = 0; ix < pStore->m_pStocks->cChg; ix++ )
{
// check if this change is deleted too
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -