📄 vcard.cxx
字号:
//
// 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.
//
/**************************************************************************/
/* VCard.cxx */
/* */
/* This file contains routines to process VCARDS */
/* */
/* DISCLAIMER!!!: this does not FULLY support the vCard spec */
/* it is intended as an example to the OBEX Inbox and nothing more */
/* I dont believe it will cause harm or behave strangly, but use it */
/* at your own risk! */
/* */
/* */
/* *'ed Functions are DLL entry points */
/* */
/* Functions included: */
/* *OBEXInboxClient -- the entry point from the OBEX inbox */
/* */
/* Other related files: */
/* */
/* */
/**************************************************************************/
#include <windows.h>
#include <tchar.h>
#include <winsock.h>
#include <bldver.h>
#include "..\..\contacts\addrmapi.h"
#include <VUtils.h>
#include <svslog.hxx>
#define OBEX_INBOX_DEBUG_REG L"Software\\Microsoft\\Obex"
#define DEBUG_VCARD_TRACE 0x00000001
/*****************************************************************************/
/* DllMain */
/* just diable thread library calls */
/*****************************************************************************/
BOOL APIENTRY DllMain(HANDLE hInst, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
DisableThreadLibraryCalls((HMODULE)hInst);
return TRUE;
}
/*****************************************************************************/
/* OBEXInboxClient */
/* Handle requests from the Inbox for vCards */
/* */
/* Begin by creating a memory map to the the passed in file name */
/* then open the Contacts Database, parse out all interesting items */
/* from the vCard and insert them into the DB. afterwards clean up and */
/* then close handles before returning */
/*****************************************************************************/
BOOL OBEXInboxClient(LPCTSTR objectName)
{
IFDBG(svslog_DebugInitialize (OBEX_INBOX_DEBUG_REG, L"obex-vcard"));
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] called for object %s\n", objectName));
//SETUP phase] -----------------------------------------------------------
// create a memory map to the file passed in, and open up the
// Contacts Database
LPVOID data;
char *lpDataPtr = NULL;
int retVal = 0;
HANDLE hFileMap, hFileMapping;
hFileMap = CreateFileForMapping(objectName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
//if there was an error opening the file, exit
if(hFileMap == INVALID_HANDLE_VALUE)
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : File open failed (%d)\n", objectName, GetLastError ()));
ASSERT(FALSE);
return TRUE;
}
//create a file mapping object, on error exit
hFileMapping =
CreateFileMapping(hFileMap,
NULL,
PAGE_READONLY,
0,0,
NULL);
if(hFileMapping == NULL) {
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : File map failed (%d)\n", objectName, GetLastError ()));
ASSERT(FALSE);
CloseHandle(hFileMap);
return TRUE;
}
//now that the file as been opened and mapped,
// create the map, and point lpDataPtr to the data
data = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0,0,0);
lpDataPtr = (char *)data;
//open the contacts database
CEOID WceObjID = 0;
HANDLE hDB = CeOpenDatabase(&WceObjID, _T("Contacts Database"), 0, CEDB_AUTOINCREMENT, NULL);
if(INVALID_HANDLE_VALUE == hDB)
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : Database open failed (%d)\n", objectName, GetLastError ()));
ASSERT(FALSE);
UnmapViewOfFile(data);
CloseHandle(hFileMapping);
CloseHandle(hFileMap);
return 1;
}
//PARSE/INSERT phase] -----------------------------------------------------
// from here down start the parsing of the data and place records
// into the database
//
// The core of the parsing is in the functino ParseVCard
// it will parse out one (and only one) vCard. it returns
// a pointer to the end of the vCard entry it just parsed.
// this allows for a loop to be created that parses/inserts
// one record at a time
while(lpDataPtr)
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : parsing the record\n", objectName));
BOOL fAddRecords = TRUE;
VCardStateObj p;
memset(&p, 0, sizeof(VCardStateObj));
CEPROP_LIST *CL = new CEPROP_LIST();
memset(CL, 0, sizeof(CEPROP_LIST));
//process the VCARD
ASSERT(lpDataPtr);
OID_STRUCT pPassStruct;
pPassStruct.uiNumElements = g_ContactSize;
pPassStruct.pTrans = g_sContactOidTranslator;
lpDataPtr = ParseVCard(CL, &pPassStruct, lpDataPtr, &p);
//build a record of the given and surnames
CEPROP_LIST *pCL = CL;
//make a new record using the two names from the vCard
LPWSTR pTitle = NULL;
UINT uiSize = 0;
if(p.pGiven)
uiSize += wcslen(p.pGiven->val.lpwstr);
if(p.pSurName)
uiSize += wcslen(p.pSurName->val.lpwstr);
pTitle = new WCHAR[uiSize + 10];
//combine the info into a string to present the user
if(p.pGiven && !p.pSurName)
swprintf(pTitle, _T("%s"), p.pGiven->val.lpwstr);
else if(!p.pGiven && p.pSurName)
swprintf(pTitle, _T("%s"), p.pSurName->val.lpwstr);
else if(p.pGiven && p.pSurName)
swprintf(pTitle, _T("%s, %s"),
p.pSurName->val.lpwstr, p.pGiven->val.lpwstr);
else
{
fAddRecords = FALSE;
}
#if defined (DEBUG) || defined (_DEBUG) || defined (RELEASELOG)
if (fAddRecords)
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : record will be added, name %s\n", objectName, pTitle));
else
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : record will not be added\n", objectName));
#endif
CEPROPVAL *prop = new CEPROPVAL();
memset(prop, 0, sizeof(CEPROPVAL));
prop->propid = HHPR_FILE_AS;
prop->val.lpwstr = pTitle;
//chain in the new property
pCL=CL;
if(!pCL->prop)
{
pCL->prop = prop;
}
else
{
CEPROP_LIST *newHolder = new CEPROP_LIST();
newHolder->prop = prop;
newHolder->pNext = pCL->pNext;
pCL->pNext = newHolder;
}
int iMsgBox = IDNO;
//confirm with the user that its okay to add this...
if(fAddRecords)
iMsgBox = IDYES;//MessageBox(NULL, pTitle, _T("Okay to insert:"), MB_YESNO);
//INSERT phase] --------------------------------------------------------
// at this point, we have a linked list of CEPROP's that need
// to be placed into the Contacts Database. rather than
// chaining them into one big array (as expected by CeWriteRecordProps
// (that would require more memory... possibly WAY more on big
// records and lots of memory moving) just make multiple calls to
// CeWriteRecordProps sending in one record at a time
pCL = CL;
if(fAddRecords && iMsgBox == IDYES && pCL && pCL->prop)
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : about to write prop. set\n", objectName));
ASSERT(pCL->prop);
if(pCL->prop)
{
CEOID mainRecOID = CeWriteRecordProps(hDB, 0, 1, pCL->prop);
pCL = pCL->pNext;
if(0 != mainRecOID)
{
while(pCL)
{
ASSERT(pCL->prop);
if(pCL->prop)
{
CEOID rOID = CeWriteRecordProps(hDB,
mainRecOID,
1,
pCL->prop);
if(0 == rOID)
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : write (2) failed (%d)!\n", objectName, GetLastError ()));
break;
}
}
pCL=pCL->pNext;
}
}
else
{
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : write (2) failed (%d)!\n", objectName, GetLastError ()));
retVal = 1; //this avoids a goto
}
}
else
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : no props to write!\n", objectName));
}
//clean up memory
pCL=CL;
while(pCL)
{
if(pCL->prop)
{
if(pCL->prop->val.lpwstr)
{
delete [] pCL->prop->val.lpwstr;
}
delete pCL->prop;
}
CEPROP_LIST *pOld = pCL;
pCL = pCL->pNext;
if(pOld)
{
delete pOld;
}
}
}
IFDBG(svslog_DebugOut (DEBUG_VCARD_TRACE, L"[OBEX-VCARD] %s : finished, retval = %d\n", objectName, retVal));
//close up
CloseHandle(hDB);
UnmapViewOfFile(data);
CloseHandle(hFileMapping);
CloseHandle(hFileMap);
//delete the file
DeleteFile(objectName);
return retVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -