CINDEX.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:
Windows编程
开发平台:
Visual C++
- /*
- * CINDEX.C
- *
- * Create and extend PR_CONVERSATION_INDEX
- */
- #include <windows.h>
- #include <mapiwin.h>
- #include <mapix.h>
- #include <mapiutil.h>
- #include <mapidbg.h>
- #include <memory.h>
- #define cbConvIndexHdr 22
- #define cbConvIndexComponent 5
- #define bConvIndexRes (BYTE)1
- /*
- * ExtractLastFileTime()
- *
- * Purpose:
- *
- * Parses an existing covnersation index and extracts the last
- * FILETIME value contained in the index.
- */
- VOID
- ExtractLastFileTime (LPBYTE lpb, ULONG cb, FILETIME FAR * lpft)
- {
- FILETIME ft;
- FILETIME ftCur;
- LPBYTE lpbEnd;
- // Lets do some verification on the key
- //
- Assert (!IsBadReadPtr (lpb, (UINT)cb));
- Assert (!IsBadWritePtr (lpft, sizeof(FILETIME)));
- Assert (*lpb == bConvIndexRes);
- Assert (cb >= cbConvIndexHdr);
- Assert (!((cb - cbConvIndexHdr) % cbConvIndexComponent));
- // Rebuild the header timedate into FILETIME format
- //
- ft.dwHighDateTime = (((DWORD)(lpb[1])) << 16) |
- (((DWORD)(lpb[2])) << 8) |
- ((DWORD)(lpb[3]));
- ft.dwLowDateTime = (((DWORD)(lpb[4])) << 24) |
- (((DWORD)(lpb[5])) << 16);
- // See where the last child chunk ends
- //
- lpbEnd = lpb + cb;
- lpb += cbConvIndexHdr;
- // Now go through the child chunks to compute
- // for the last FILETIME using the delta
- //
- while (lpb < lpbEnd)
- {
- // Convert the delta of the current child
- // chunk into the FILETIME format. Use the
- // delta code in the first bit to get the
- // real delta.
- //
- // Delta code : 1 = mask 10000000 = 0x80
- //
- if ((*lpb & 0x80) == 0x80)
- {
- // Mask out the first bit used for the delta code
- // *lpb | 0x7F;
- //
- ftCur.dwHighDateTime = (((DWORD)(lpb[0] & 0x7F)) << 15) |
- (((DWORD)(lpb[1])) << 7) |
- (((DWORD)(lpb[2])) >> 1);
- ftCur.dwLowDateTime = (((DWORD)(lpb[2])) << 31) |
- (((DWORD)(lpb[3])) << 23);
- ft = FtAddFt (ft, ftCur);
- }
- else
- {
- ftCur.dwHighDateTime = (((DWORD)(lpb[0] & 0x7F)) << 10) |
- (((DWORD)(lpb[1])) << 2) |
- (((DWORD)(lpb[2])) >> 6);
- ftCur.dwLowDateTime = (((DWORD)(lpb[2])) << 26) |
- (((DWORD)(lpb[3])) << 18);
- ft = FtAddFt (ft, ftCur);
- }
- // Advance to next child
- //
- lpb += cbConvIndexComponent;
- }
- // If all went well, we sould have ended up at
- // lpbEnd
- //
- Assert (lpb == lpbEnd);
- *lpft = ft;
- return;
- }
- /*
- * ScFillConvHeader()
- *
- * Purpose:
- *
- * Fills in the header of a conversation index. This function is
- * called when a new conversation index is created.
- *
- * Assumptions:
- *
- * The buffer passed in should be big enough to hold cbConvIndexHdr
- * bytes (22 bytes).
- */
- SCODE
- ScFillConvHeader (LPBYTE rgb, ULONG cb)
- {
- SCODE sc = S_OK;
- SYSTEMTIME st;
- FILETIME ft;
- GUID guid;
- Assert (cb >= cbConvIndexHdr);
- Assert (!IsBadWritePtr (rgb, cbConvIndexHdr));
- // (Ha). Put the reserved byte
- //
- rgb[0] = bConvIndexRes;
- // (Hb). Put the current time
- //
- GetSystemTime (&st);
- SystemTimeToFileTime (&st, &ft);
- // Construct the datetime one byte at a time
- //
- rgb[1] = (BYTE) ((ft.dwHighDateTime & 0x00FF0000) >> 16);
- rgb[2] = (BYTE) ((ft.dwHighDateTime & 0x0000FF00) >> 8);
- rgb[3] = (BYTE) (ft.dwHighDateTime & 0x000000FF);
- // Drop the rightmost least significant 2 bytes
- //
- rgb[4] = (BYTE) ((ft.dwLowDateTime & 0xFF000000) >> 24);
- rgb[5] = (BYTE) ((ft.dwLowDateTime & 0x00FF0000) >> 16);
- // (Hc). Now put the GUID
- // {
- // DWORD Data1;
- // WORD Data2;
- // WORD Data3;
- // BYTE Data4[8];
- // } GUID;
- //
- sc = GetScode (CoCreateGuid (&guid));
- if (!FAILED (sc))
- {
- // Again, lets do it one byte at a time
- //
- rgb[6] = (BYTE) ((guid.Data1 & 0xFF000000) >> 24);
- rgb[7] = (BYTE) ((guid.Data1 & 0x00FF0000) >> 16);
- rgb[8] = (BYTE) ((guid.Data1 & 0x0000FF00) >> 8);
- rgb[9] = (BYTE) ((guid.Data1 & 0x000000FF));
- rgb[10] = (BYTE) ((guid.Data2 & 0xFF00) >> 8);
- rgb[11] = (BYTE) ((guid.Data2 & 0x00FF));
- rgb[12] = (BYTE) ((guid.Data3 & 0xFF00) >> 8);
- rgb[13] = (BYTE) ((guid.Data3 & 0x00FF));
- }
- // Slurp the rest across
- //
- CopyMemory (&rgb[14], &guid.Data4, 8);
- DebugTraceSc (ScFillConvHeader(), sc);
- return sc;
- }
- /*
- * ScAddConversationIndex()
- *
- * Purpose:
- *
- * Given the conversation index to a message, this function will
- * create the conversation of a child message to the original. If
- * the no original is suplied, then an index is created that would
- * signify the start of a new thread.
- */
- SCODE
- ScAddConversationIndex (ULONG cbParent,
- LPBYTE lpbParent,
- ULONG FAR * lpcb,
- LPBYTE FAR * lppb)
- {
- SCODE sc;
- DWORD dwTemp;
- SYSTEMTIME st;
- FILETIME ft;
- FILETIME ftLast;
- FILETIME ftDelta;
- HMODULE hMAPIDll = NULL;
- typedef SCODE (STDAPICALLTYPE FAR *MAPICONVIDX)(ULONG, LPBYTE, ULONG FAR *, LPBYTE FAR *);
- MAPICONVIDX lpfnMAPIConvIdx = NULL;
- #if defined (WIN16)
- #define szScCreateConversationIndex "ScCreateConversationIndex"
- #elif defined (_WIN32) && defined (_X86_)
- #ifndef szScCreateConversationIndex
- #define szScCreateConversationIndex "ScCreateConversationIndex@16"
- #endif
- #elif defined (_ALPHA_) || defined (_MIPS_) || defined (_PPC_)
- #define szScCreateConversationIndex "ScCreateConversationIndex"
- #endif
- #ifdef _WIN32
- #define szMAPIDll "mapi32.dll"
- #else
- #define szMAPIDll "mapi.dll"
- #endif
- /*
- * MAPI is going to export a function that is doing the same thing as this one.
- * So if the function is present we'll use it.
- */
- hMAPIDll = GetModuleHandle(szMAPIDll);
- if(hMAPIDll)
- {
- lpfnMAPIConvIdx = (MAPICONVIDX)GetProcAddress(hMAPIDll,
- szScCreateConversationIndex);
- if(lpfnMAPIConvIdx)
- {
- return (*lpfnMAPIConvIdx)(cbParent, lpbParent, lpcb, lppb);
- }
- }
- // Ensure that the parent is what we think
- // it should be
- //
- if ((cbParent < cbConvIndexHdr) ||
- ((cbParent - cbConvIndexHdr) % cbConvIndexComponent) ||
- (lpbParent[0] != bConvIndexRes))
- {
- cbParent = 0;
- *lpcb = cbConvIndexHdr;
- }
- else
- *lpcb = cbParent + cbConvIndexComponent;
- sc = MAPIAllocateBuffer (*lpcb, (LPVOID FAR *)lppb);
- if (!FAILED (sc))
- {
- if (cbParent == 0)
- {
- // This is a new key, so all it ever contains
- // is a header. Fill it in and we are done
- //
- sc = ScFillConvHeader (*lppb, *lpcb);
- if (FAILED (sc))
- {
- MAPIFreeBuffer (*lppb);
- *lppb = NULL;
- }
- }
- else
- {
- // First copy the old key across
- //
- CopyMemory (*lppb, lpbParent, (UINT)cbParent);
- // (Cb). First get the current time (we'll then get
- // the absolute distance between the current time and
- // the time in the last chunk)
- //
- GetSystemTime (&st);
- SystemTimeToFileTime (&st, &ft);
- // Now get the time of the last chunk
- //
- ExtractLastFileTime (lpbParent, cbParent, &ftLast);
- // Now mask out the bits we don't want from the
- // current time
- //
- ft.dwHighDateTime &= 0x00FFFFFF;
- ft.dwLowDateTime &= 0xFFFF0000;
- // This assert is here to catch how often the
- // 5-byte time can collide and under what scenario,
- // to see if 5 bytes + the next byte suffices to
- // make this child chunk unique.
- //
- Assert (!((ftLast.dwHighDateTime == ft.dwHighDateTime) &&
- (ftLast.dwLowDateTime == ft.dwLowDateTime)));
- // Get the change in time
- //
- if ((ft.dwHighDateTime > ftLast.dwHighDateTime) ||
- ((ft.dwHighDateTime == ftLast.dwHighDateTime) &&
- (ft.dwLowDateTime > ftLast.dwLowDateTime)))
- {
- ftDelta = FtSubFt (ft, ftLast);
- }
- else
- ftDelta = FtSubFt (ftLast, ft);
- // If the delta is less than 1.7 yrs, use 0
- //
- if (!(ftDelta.dwHighDateTime & 0x00FE0000))
- {
- // Just mask out the 31 bits that we
- // want from the ftDelta
- //
- dwTemp = ((DWORD)(ftDelta.dwHighDateTime & 0x0001FFFF)) << 14 |
- ((DWORD)(ftDelta.dwLowDateTime & 0xFFFC0000)) >> 18;
- // Only the first byte is different
- //
- (*lppb)[cbParent] = (BYTE)((dwTemp & 0xFF000000) >> 24 );
- }
- else
- {
- // Just mask out the 31 bits that we
- // want from the ftDelta
- //
- dwTemp = ((DWORD)(ftDelta.dwHighDateTime & 0x003FFFFF)) << 9 |
- ((DWORD)(ftDelta.dwLowDateTime & 0xFF800000)) >> 23;
- // Only the first byte is different
- //
- (*lppb)[cbParent] = (BYTE)(HIBYTE(HIWORD(dwTemp)) | 0x080);
- }
- // The remaining delta bytes are the same
- //
- (*lppb)[cbParent + 1] = (BYTE) ((dwTemp & 0x00FF0000) >> 16);
- (*lppb)[cbParent + 2] = (BYTE) ((dwTemp & 0x0000FF00) >> 8);
- (*lppb)[cbParent + 3] = (BYTE) ((dwTemp & 0x000000FF) );
- // (Cc). Next get the random number
- // (Cd). Next get the sequence count
- // -- we are going to use part of the tick count
- //
- (*lppb)[cbParent + 4] = (BYTE) (GetTickCount() & 0x000000FF);
- }
- }
- DebugTraceSc (ScAddConversationIndex(), sc);
- return sc;
- }