?? stdevs.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.
\******************************************************************************/
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
stdevs.cpp
Abstract:
Implementation the Stock Portfolio device ActiveSync module for Windows CE Services
--*/
#include <windows.h>
#include <cesync.h>
#include "..\..\common.h"
#include "stdevs.h"
#pragma warning(disable : 4995)
// GUID for the database volume
CEGUID v_guid;
TCHAR v_szDBVol[ MAX_PATH ];
BOOL WINAPI DllMain( HANDLE hInstDll, ULONG ulReason, LPVOID lpReserved )
{
switch( ulReason )
{
case DLL_PROCESS_ATTACH :
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
// Current partner bit (1 or 2)
UINT v_uPartnerBit;
// OID of the database we synchronize
CEOID v_oidDb;
/*++
BOOL IsVolMatched
Return TRUE if the given BLOB matches the GUID we are currently using
--*/
BOOL IsVolMatched( LPBYTE lpbVol, UINT cbVol )
{
if ( CHECK_SYSTEMGUID( &v_guid ) )
return lpbVol == NULL || cbVol == sizeof( v_guid ) && CHECK_SYSTEMGUID( (CEGUID *)lpbVol );
return cbVol == sizeof( v_guid ) && !memcmp( lpbVol, &v_guid, sizeof( v_guid ) );
}
/*++
BOOL Open
Search/open the database we synchronize
--*/
BOOL Open( HANDLE *phDatabase, CEOID *pOid = NULL )
{
// search for the database we want to replicate, create one if not found
HANDLE hFind;
CEOID oid;
CEOIDINFO oidInfo;
oid = 0;
hFind = CeFindFirstDatabaseEx( &v_guid, DBTYPE_STOCKPOR );
if ( hFind != INVALID_HANDLE_VALUE )
{
for ( ;; )
{
oid = CeFindNextDatabase( hFind );
if ( !oid ||
CeOidGetInfoEx( &v_guid, oid, &oidInfo ) && oidInfo.wObjType == OBJTYPE_DATABASE &&
!wcscmp( oidInfo.infDatabase.szDbaseName, SZ_DEFAULT_PORTFILE ) )
break;
}
CloseHandle( hFind );
}
if ( !oid )
{
CEDBASEINFO info;
memset( &info, 0, sizeof( info ) );
info.dwFlags = CEDB_VALIDNAME | CEDB_VALIDTYPE;
lstrcpy( info.szDbaseName, SZ_DEFAULT_PORTFILE );
info.dwDbaseType = DBTYPE_STOCKPOR;
oid = CeCreateDatabaseEx( &v_guid, &info );
}
if ( oid && phDatabase )
*phDatabase = CeOpenDatabaseEx( &v_guid, &oid, 0, 0, 0, NULL );
if ( pOid )
*pOid = oid;
return oid && ( !phDatabase || *phDatabase != INVALID_HANDLE_VALUE );
}
/*++
EXTERN_C BOOL InitObjType
Initialize/Un-initialize the moudle. lpszObjType is NULL if un-initializing.
--*/
EXTERN_C BOOL InitObjType( LPWSTR lpszObjType, IReplObjHandler **ppObjHandler, UINT uPartnerBit )
{
if ( lpszObjType == NULL )
{
// terminating the module
// free up all resources used
if ( CHECK_SYSTEMGUID( &v_guid ) )
CeUnmountDBVol( &v_guid );
return TRUE;
}
// find out what database volume we are sync'ing
HKEY hKey;
DWORD dw, cb;
v_szDBVol[0] = 0;
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, SZ_REG_ROOT, 0, KEY_READ, &hKey ) == ERROR_SUCCESS )
{
cb = sizeof( v_szDBVol );
RegQueryValueEx( hKey, SZ_REG_DBVOL, NULL, &dw, (LPBYTE)v_szDBVol, &cb );
RegCloseKey( hKey );
}
if ( v_szDBVol[0] )
CeMountDBVol( &v_guid, v_szDBVol, OPEN_EXISTING );
else
{
CREATE_SYSTEMGUID( &v_guid );
}
*ppObjHandler = new CDataHandler;
v_uPartnerBit = uPartnerBit;
return TRUE;
}
/*++
EXTERN_C HRESULT FindObjects
Enumerate all objects in the database volume currently used
--*/
EXTERN_C HRESULT FindObjects( PFINDOBJINFO pfi )
{
DWORD dwIndex, ix, jx, cOid, cbProps;
CEPROPVAL *rgProps = NULL;
WORD cProps;
CEOID oid;
CEOIDINFO oidInfo;
HANDLE hDatabase;
int nChanged = 0, nUnChanged = 0;
static CEGUID ceGuid;
if ( pfi->uFlags & FO_DONE_ONE_VOL )
{
if ( pfi->poid )
LocalFree( pfi->poid );
return NOERROR;
}
if ( !CeOidGetInfoEx( &v_guid, v_oidDb, &oidInfo ) || oidInfo.wObjType != OBJTYPE_DATABASE )
return E_UNEXPECTED;
// must return the DB GUID as the volume ID, even if there may not be object in the store yet
if ( !CHECK_SYSTEMGUID( &v_guid ) )
{
pfi->cbVolumeID = sizeof( CEGUID );
pfi->lpbVolumeID = (LPBYTE)&v_guid;
}
cOid = oidInfo.infDatabase.wNumRecords;
if ( cOid == 0 )
return NOERROR;
if ( !Open( &hDatabase ) )
return E_POINTER;
// NOTE: for sake of simplicity, we are not checking memory allocation error here
// for real world application, out of memory case must be taken care of.
pfi->poid = (PUINT)LocalAlloc( LPTR, cOid * sizeof( UINT ) );
oid = CeSeekDatabase( hDatabase, CEDB_SEEK_BEGINNING, 0, &dwIndex );
for ( ix = 0; ix < cOid && oid != 0; ix++ )
{
if ( oid == CeReadRecordProps( hDatabase, CEDB_ALLOWREALLOC, &cProps, NULL, (LPBYTE *)&rgProps, &cbProps ) )
{
for ( jx = 0; jx < cProps; jx++ )
if ( rgProps[jx].propid == HHPR_FLAGS )
{
if ( rgProps[ jx ].val.uiVal & v_uPartnerBit )
{
// Yes, this one did change -- tack it on to the end of our array
pfi->poid[cOid - nChanged - 1] = oid;
nChanged++;
if ( rgProps[ jx ].val.uiVal & SF_CHG_IN_SYNC )
{
rgProps[ jx ].val.uiVal &= ~SF_CHG_IN_SYNC;
if ( CeSeekDatabase( hDatabase, CEDB_SEEK_CEOID, oid, &dwIndex ) == oid )
CeWriteRecordProps( hDatabase, oid, 1, rgProps + jx );
}
}
else
{
// No, this one did not change -- tack it on to the beginning of our array
pfi->poid[nUnChanged] = oid;
nUnChanged++;
}
break;
}
LocalFree( rgProps );
}
oid = CeSeekDatabase( hDatabase, CEDB_SEEK_CURRENT, 1, &dwIndex );
}
pfi->cChg = nChanged;
pfi->cUnChg = nUnChanged;
CloseHandle( hDatabase );
return NOERROR;
}
/*++
EXTERN_C BOOL ObjectNotify
Respond to change/delete of a file system object
--*/
EXTERN_C BOOL ObjectNotify( POBJNOTIFY pNotify )
{
CEPROPVAL *rgProps = NULL;
HANDLE hDatabase = INVALID_HANDLE_VALUE;
UINT uixFlags = 0, ix;
BOOL fRet = FALSE, fSave = FALSE;
DWORD dwIndex, cbProps;
WORD cProps;
if ( pNotify->cbStruct < sizeof( OBJNOTIFY ) )
{
// stop if strucuture size is smaller
goto Exit;
}
// quick check on ONF_* flags
// to see if we're interested in this notification
if ( !( pNotify->uFlags & ( ONF_RECORD | ONF_CLEAR_CHANGE ) ) )
goto Exit;
if ( !( pNotify->uFlags & ONF_DELETED ) )
{
// make sure we are dealing with the records in our database
if ( ( pNotify->uFlags & ONF_RECORD ) &&
( pNotify->oidInfo.wObjType != OBJTYPE_RECORD || pNotify->oidInfo.infRecord.oidParent != v_oidDb ||
!IsVolMatched( pNotify->lpbVolumeID, pNotify->cbVolumeID ) ) )
goto Exit;
if ( !Open( &hDatabase ) )
goto Exit;
CEOID oid = CeSeekDatabase( hDatabase, CEDB_SEEK_CEOID, pNotify->oidObject, &dwIndex );
if ( oid != pNotify->oidObject )
goto Exit;
oid = CeReadRecordProps( hDatabase, CEDB_ALLOWREALLOC, &cProps, NULL, (LPBYTE *)&rgProps, &cbProps );
if ( oid != pNotify->oidObject )
goto Exit;
for ( ix = 0; ix < cProps; ix++ )
if ( rgProps[ix].propid == HHPR_FLAGS )
{
uixFlags = ix;
break;
}
if ( ix >= cProps )
goto Exit;
}
if ( pNotify->uFlags & ONF_CLEAR_CHANGE )
{
fSave = TRUE;
// did object got changed again during sync?
if ( rgProps[ uixFlags ].val.uiVal & SF_CHG_IN_SYNC )
{
// clear this bit now but keep the dirty bit
rgProps[ uixFlags ].val.uiVal &= ~SF_CHG_IN_SYNC;
fRet = TRUE;
}
else
{
// clear the dirty bit now
rgProps[ uixFlags ].val.uiVal &= ~v_uPartnerBit;
fRet = FALSE;
}
goto Exit;
}
pNotify->poid = (UINT *)&pNotify->oidObject;
// determine what object ID to be returned
// if you store one object per file/record, you simply need to return the file system object ID given
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -