ABCTBL1.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:27k
源码类别:
Windows编程
开发平台:
Visual C++
- /***********************************************************************
- *
- * ABCTBL1.C
- *
- * Contents Table
- *
- * The contents table associated with this provider. It's file based.
- * The format of the .SAB file is in ABP.H.
- *
- * This implementation of IMAPITable is retrieved by calling the
- * GetContentsTable() method of the sample ABP's single directory (see
- * abcont.c).
- *
- * There are a few interesting features in this implementation. First
- * it's implemented on a flat file (.SAB). Second, it actually supports
- * an implementation of ANR (Ambiguous Name Resolution). And lastly, it
- * supports FindRow (limited to prefix searching on display names).
- *
- * This is the minimum set of restrictions that your provider MUST support.
- * It MUST have an ANR implementation and support prefix (downward) searching
- * on whatever your table is sorted on (in this case PR_DISPLAY_NAME).
- *
- * The browsing of a flat file is done a record at a time. It's never
- * completely read into memory. It only reads records from the file when
- * it absolutely has to (like in QueryRows). The advantage to this is
- * a low memory footprint and the ability to browse rather large files
- * with decent performance.
- */
- /*
- * ANR is also supported in this implementation. In the code will often
- * be 'if' statements making two different code paths between the restricted
- * and unrestricted version. The restrictions rely on a couple of
- * bit arrays. Each bit corresponds (in order) to the records in the .SAB
- * file. One bit array, rgChecked, says whether or not a record in the
- * .SAB file has actually been compared to the restriction. It's initially
- * set to all 0s - which means that none of the records have been checked.
- * The second bit array, rgMatched, says whether or not the particular
- * record matches the current restriction. This array is initialized to all
- * 1s - which says that all the records in the .SAB file match the current
- * restriction. The reason for this is for the fraction returned in
- * QueryPosition--By assuming that all the rows match and only updating
- * the array when something doesn't match, the fraction returned in
- * QueryPosition will get larger and has the effect of making the thumb-bar
- * on a listbox implemented on top of this table to scroll down as you go
- * down the list.
- *
- * As a row is about to be read it is checked to see if it's been compared
- * to the current restriction. If it has then to determine whether or not
- * to actually read the record and build the row we just look at the matched
- * bit array. If it doesn't match we go on to the next record and check
- * again. If it does match we read the record and build the row.
- *
- * Only if it hasn't been checked do we actually go and read the row and
- * compare it to the current restriction, setting the rgChecked and
- * rgMatched bits accordingly.
- *
- * In this implementation the ANR comparison rules are as follows:
- * (See FNameMatch for the actual code to do this)
- *
- * A 'word' is defined as any substring separated by separators.
- * The separators are defined as ',', ' ', and '-'.
- * A restriction is said to match a display name iff all the words
- * in the restriction are all prefixes of words in the display name.
- *
- * For example, a restriction of "b d" will match:
- * "Barney Donovan"
- * "Donovan, Barney"
- * "Danielle Blumenthal"
- * But will not match:
- * "Darby Opal"
- * "Ben Masters"
- *
- * Other providers can do whatever matching they want with the ANR
- * restriction. For example, soundex or additional field comparisons (like
- * email addresses). A good (and fast) implementation will differentiate
- * your provider from others in a positive way.
- *
- * FindRow's implementation effectively handles prefix searching on display
- * names (PR_DISPLAY_NAME). It does this by binary searching the .SAB file.
- * The only tricky part is knowing when to stop. Basically you want to stop
- * on the first name in the list that matches the restriction. It's easy to
- * do linearly, but a little more trick with a binary search. This
- * implementation is a reasonable example.
- *
- *
- * This table has only the following columns:
- */
- #include "abp.h"
- #include "abctbl.h"
- #include "sampabp.rh"
- const SizedSPropTagArray(cvalvtMax, tagaivtabcColSet) =
- {
- cvalvtMax,
- {
- PR_DISPLAY_NAME_A,
- PR_ENTRYID,
- PR_ADDRTYPE_A,
- PR_EMAIL_ADDRESS_A,
- PR_OBJECT_TYPE,
- PR_DISPLAY_TYPE,
- PR_INSTANCE_KEY
- }
- };
- const LPSPropTagArray ptagaivtabcColSet = (LPSPropTagArray) &tagaivtabcColSet;
- /*
- *
- * The following routines are implemented in the files abctbl2.c and abctbl3.c:
- *
- *
- * IVTABC_Release
- * IVTABC_GetStatus
- * IVTABC_SetColumns
- * IVTABC_QueryColumns
- * IVTABC_GetRowCount
- * IVTABC_SeekRow
- * IVTABC_SeekRowApprox
- * IVTABC_QueryPosition
- * IVTABC_FindRow
- * IVTABC_Restrict
- * IVTABC_CreateBookmark
- * IVTABC_FreeBookmark
- * IVTABC_SortTable
- * IVTABC_QuerySortOrder
- * IVTABC_QueryRows
- * IVTABC_Abort
- * IVTABC_ExpandRow
- * IVTABC_CollapseRow
- * IVTABC_WaitForCompletion
- * IVTABC_GetCollapseState
- * IVTABC_SetCollapseState
- *
- *
- * This file (abctbl1.c) has all the utility functions used throughout this
- * objects methods. They are the following:
- *
- * HrNewIVTAbc()
- * HrValidateEntry()
- * FChecked()
- * FMatched()
- * FNameMatch()
- * HrOpenFile()
- * fIVTAbcIdleRoutine()
- * FreeANRBitmaps()
- *
- *
- * Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
- *
- ***********************************************************************/
- /*
- * vtbl filled in here.
- */
- const IVTABC_Vtbl vtblIVTABC =
- {
- IVTABC_QueryInterface,
- (IVTABC_AddRef_METHOD *) ROOT_AddRef,
- IVTABC_Release,
- (IVTABC_GetLastError_METHOD *) ROOT_GetLastError,
- IVTABC_Advise,
- IVTABC_Unadvise,
- IVTABC_GetStatus,
- IVTABC_SetColumns,
- IVTABC_QueryColumns,
- IVTABC_GetRowCount,
- IVTABC_SeekRow,
- IVTABC_SeekRowApprox,
- IVTABC_QueryPosition,
- IVTABC_FindRow,
- IVTABC_Restrict,
- IVTABC_CreateBookmark,
- IVTABC_FreeBookmark,
- IVTABC_SortTable,
- IVTABC_QuerySortOrder,
- IVTABC_QueryRows,
- IVTABC_Abort,
- IVTABC_ExpandRow,
- IVTABC_CollapseRow,
- IVTABC_WaitForCompletion,
- IVTABC_GetCollapseState,
- IVTABC_SetCollapseState
- };
- /* Idle function */
- FNIDLE fIVTAbcIdleRoutine;
- #define IVTABC_IDLE_INTERVAL 300L
- #define IVTABC_IDLE_PRIORITY -2
- #define IVTABC_IDLE_FLAGS FIROINTERVAL
- /*************************************************************************
- *
- - NewIVTAbc
- -
- * Creates a new IMAPITable on the contents of a .SAB file.
- *
- *
- */
- HRESULT
- HrNewIVTAbc(LPMAPITABLE * lppIVTAbc,
- LPABLOGON lpABLogon,
- LPABCONT lpABC,
- HINSTANCE hLibrary,
- LPALLOCATEBUFFER lpAllocBuff,
- LPALLOCATEMORE lpAllocMore,
- LPFREEBUFFER lpFreeBuff,
- LPMALLOC lpMalloc )
- {
- LPIVTABC lpIVTAbc = NULL;
- SCODE scode;
- HRESULT hResult = hrSuccess;
- ULONG ulBK, ulSize, ulSizeHigh;
- /*
- * Allocate space for the IVTABC structure
- */
- scode = lpAllocBuff(sizeof(IVTABC), (LPVOID *) &lpIVTAbc);
- if (FAILED(scode))
- {
- hResult = ResultFromScode(scode);
- goto err;
- }
- lpIVTAbc->lpVtbl = &vtblIVTABC;
- lpIVTAbc->lcInit = 1;
- lpIVTAbc->hResult = hrSuccess;
- lpIVTAbc->idsLastError = 0;
- lpIVTAbc->hLibrary = hLibrary;
- lpIVTAbc->lpAllocBuff = lpAllocBuff;
- lpIVTAbc->lpAllocMore = lpAllocMore;
- lpIVTAbc->lpFreeBuff = lpFreeBuff;
- lpIVTAbc->lpMalloc = lpMalloc;
- lpIVTAbc->lpABLogon = lpABLogon;
- lpIVTAbc->lpszFileName = NULL;
- hResult = HrLpszGetCurrentFileName(lpABLogon, &(lpIVTAbc->lpszFileName));
- if (HR_FAILED(hResult))
- {
- goto err;
- }
- lpIVTAbc->lpPTAColSet = (LPSPropTagArray) &tagaivtabcColSet;
- /*
- * Open the .SAB file associated with this logged in session.
- * Currently it's opened with FILE_SHARED_READ. This has an
- * unpleasant side-effect of not being able to modify the .SAB
- * file while this table is active.
- *
- * It should be OF_SHARE_DENY_NONE. I don't have the code to
- * handle this in this version.
- */
- if ((lpIVTAbc->hFile = CreateFile(
- lpIVTAbc->lpszFileName,
- GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL)) == INVALID_HANDLE_VALUE)
- {
- /*
- * The file didn't open...
- */
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpABC, hResult, IDS_CANT_OPEN_SAB);
- goto err;
- }
- /*
- * Get the time and date stamp
- *
- */
- (void)GetFileTime(lpIVTAbc->hFile, NULL, NULL, &(lpIVTAbc->filetime));
- /* Get the size of the file */
- if ((ulSize = GetFileSize(lpIVTAbc->hFile, &ulSizeHigh)) == 0xFFFFFFFF)
- {
- /*
- * MAYBE I have an error
- */
- if (GetLastError() != NO_ERROR)
- {
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpABC, hResult, IDS_SAB_FILE_ATTRIB);
- goto err;
- }
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpABC, hResult, IDS_SAB_TOO_LARGE);
- goto err;
- }
- /*
- * Actual number of valid positions
- */
- lpIVTAbc->ulMaxPos = (ulSize / sizeof(ABCREC));
- /*
- * Check to see if it's an exact multiple of sizeof(ABCREC)
- */
- if (lpIVTAbc->ulMaxPos * sizeof(ABCREC) != ulSize)
- {
- /*
- * Nope.
- */
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpABC, hResult, IDS_SAB_CORRUPT);
- goto err;
- }
- lpIVTAbc->ulPosition = 0;
- /* Setup bookmarks */
- for (ulBK = 0; ulBK < MAX_BOOKMARKS; lpIVTAbc->rglpABCBK[ulBK++] = NULL);
- /*
- * Restriction stuff
- */
- lpIVTAbc->rgChecked = NULL;
- lpIVTAbc->rgMatched = NULL;
- lpIVTAbc->lpszPartialName = NULL;
- /*
- * Registered notification stuff
- */
- lpIVTAbc->cAdvise = 0;
- lpIVTAbc->parglpAdvise = NULL;
- lpIVTAbc->ulConnectMic = (ULONG) lpIVTAbc & 0xffffff;
- InitializeCriticalSection(&lpIVTAbc->cs);
- /*
- * Register the idle function
- */
- lpIVTAbc->ftg = FtgRegisterIdleRoutine(
- fIVTAbcIdleRoutine,
- lpIVTAbc,
- IVTABC_IDLE_PRIORITY,
- IVTABC_IDLE_INTERVAL,
- IVTABC_IDLE_FLAGS);
- InitializeCriticalSection(&lpIVTAbc->cs);
- /* We must AddRef the lpABLogon object since we will be using it
- */
- lpABLogon->lpVtbl->AddRef(lpABLogon);
- *lppIVTAbc = (LPVOID) lpIVTAbc;
- out:
- DebugTraceResult(HrNewIVTAbc, hResult);
- return hResult;
- err:
- if (lpIVTAbc)
- {
- if (lpIVTAbc->hFile != INVALID_HANDLE_VALUE)
- {
- /*
- * Must've opened the file
- */
- CloseHandle(lpIVTAbc->hFile);
- }
- /* Free the current .SAB file name */
- lpFreeBuff(lpIVTAbc->lpszFileName);
- /* Free the mem */
- lpFreeBuff( lpIVTAbc );
- }
- goto out;
- }
- /*************************************************************************
- *
- - HrValidateEntry
- -
- *
- * Used in restricted lists
- * Checks to see if a given entry at a particular location matches
- * the active restriction. It always modifies rgChecked, and may
- * modify rgMatched.
- */
- HRESULT
- HrValidateEntry(LPIVTABC lpIVTAbc, ULONG ulNewPos)
- {
- ABCREC abcrec;
- ULONG cbRead;
- HRESULT hResult;
- /*
- * Open the file
- */
- hResult = HrOpenFile(lpIVTAbc);
- if (HR_FAILED(hResult))
- {
- DebugTraceResult(HrValidateEntry, hResult);
- return hResult;
- }
- /*
- * Set the file position to lNewPos
- */
- (void) SetFilePointer(lpIVTAbc->hFile, ulNewPos * sizeof(ABCREC),
- NULL, FILE_BEGIN);
- /*
- * Read in the record from the file
- */
- if (!ReadFile(lpIVTAbc->hFile, (LPVOID) &abcrec,
- sizeof(ABCREC), &cbRead, NULL))
- {
- DebugTraceSc(HrValidateEntry, MAPI_E_DISK_ERROR);
- return ResultFromScode(MAPI_E_DISK_ERROR);
- }
- /* Second check */
- if (cbRead != sizeof(ABCREC))
- {
- DebugTraceSc(HrValidateEntry, MAPI_E_DISK_ERROR);
- return ResultFromScode(MAPI_E_DISK_ERROR);
- }
- /*
- * Always set the Checked flag
- */
- lpIVTAbc->rgChecked[ulNewPos / 8] |= (((unsigned char)0x80) >> (ulNewPos % 8));
- /*
- * See if the rgchDisplayName matches the restriction
- */
- if (!FNameMatch(lpIVTAbc, abcrec.rgchDisplayName))
- {
- /*
- * Apparently not. Reset the Matched flag
- */
- lpIVTAbc->ulRstrDenom--;
- lpIVTAbc->rgMatched[ulNewPos / 8] &= ~(((unsigned char)0x80) >> (ulNewPos % 8));
- }
- return hrSuccess;
- }
- /*************************************************************************
- *
- - FChecked
- -
- *
- * Returns whether or not an entry has ever been checked
- * Just looks at the bit in the rgChecked array that corresponds with
- * lNewPos
- *
- */
- BOOL
- FChecked(LPIVTABC lpIVTAbc, ULONG ulNewPos)
- {
- ULONG ulT = (ULONG) (lpIVTAbc->rgChecked[ulNewPos / 8] & (((unsigned char)0x80) >> (ulNewPos % 8)));
- return (BOOL) !!ulT;
- }
- /*************************************************************************
- *
- - FMatched
- -
- *
- * Returns whether or not an entry has been matched
- * Just checks the bit in the rgMatched array corresponding with
- * lNewPos
- *
- */
- BOOL
- FMatched(LPIVTABC lpIVTAbc, ULONG ulNewPos)
- {
- ULONG ulT = (lpIVTAbc->rgMatched[ulNewPos / 8] & (((unsigned char)0x80) >> (ulNewPos % 8)));
- return (BOOL) !!ulT;
- }
- /*************************************************************************
- *
- - FNameMatch
- -
- * Tries to match the rgchDisplayName with the partial name of the
- * restriction.
- * It tries to prefix match each partial name component (i.e. word) with
- * each rgchDisplayName name component (i.e. word). Only if all of them
- * match (from the partial name) does this return TRUE.
- */
- BOOL
- FCharInString(LPSTR lpsz, CHAR ch);
- BOOL
- FNameMatch(LPIVTABC lpIVTAbc, LPSTR rgchDisplayName)
- {
- LPSTR szANRSep = ", -";
- LPSTR szANR = lpIVTAbc->lpszPartialName;
- LPSTR pchEndSzANR = szANR + lstrlenA(szANR);
- ULONG cchANRName;
- ULONG cchFullNameName;
- LPSTR szFullNameT;
- LPSTR szT;
- /* If someone tries to match more than an iwMOMax-part name, the function
- * will return fFalse. But then if someone is trying to match a name
- * with iwMOMax parts, chances are they weren't going to get it right
- * anyway....
- */
- #define iwMOMax 50
- WORD rgwMO[iwMOMax];
- int iwMOMac = 0;
- while (TRUE)
- {
- /* Find the end of the partial name we're pointing at */
- szT = szANR;
- while (!FCharInString(szANRSep, *szT))
- ++szT;
- cchANRName = szT - szANR;
- /* Check if it matches any name in the full name */
- szFullNameT = rgchDisplayName;
- while (TRUE)
- {
- szT = szFullNameT;
- /* Find the length of the name in the full name */
- /* we're checking against. */
- while (!FCharInString(szANRSep, *szT))
- ++szT;
- cchFullNameName = szT - szFullNameT;
- if (cchANRName <= cchFullNameName &&
- CompareStringA( lcidUser,
- NORM_IGNORECASE,
- szANR,
- (int) cchANRName,
- szFullNameT,
- (int) cchANRName) == 2 )
- {
- int iwMO;
- for (iwMO = 0; iwMO < iwMOMac; iwMO++)
- if (rgwMO[iwMO] == (WORD) (szFullNameT - rgchDisplayName))
- break;
- /* We found the partial name so check the next ANR part */
- if (iwMO == iwMOMac)
- {
- if (iwMOMac == iwMOMax - 1)
- {
- /* If some user wants to match an iwMOMax part
- * name, chances are it wasn't going to match
- * anyway...
- */
- return FALSE;
- }
- rgwMO[iwMOMac++] = szFullNameT - rgchDisplayName;
- break;
- }
- }
- /* We didn't find the partial name this time around, so
- * try to check the next name in the full name.
- */
- szFullNameT += cchFullNameName;
- while (*szFullNameT && FCharInString(szANRSep, *szFullNameT))
- ++szFullNameT;
- if (*szFullNameT == ' ')
- return FALSE; /* We never found the partial name. */
- }
- /* We found the partial name, so check the next ANR part */
- szANR += cchANRName;
- while (*szANR && FCharInString(szANRSep, *szANR))
- ++szANR;
- if (*szANR == ' ')
- return TRUE; /* No more ANR to check, so we found `em all */
- }
- /* Not reached (we hope...) */
- return FALSE;
- }
- /*
- - HrOpenFile
- -
- * Opens the .SAB file associated with the table and
- * checks whether the .SAB file has changed.
- * If it has changed, the table bookmarks and ANR bitmaps
- * are updated and everyone on the advise list is notified.
- */
- HRESULT
- HrOpenFile(LPIVTABC lpIVTAbc)
- {
- HRESULT hResult = hrSuccess;
- FILETIME filetime;
- ULONG ulSize, ulSizeHigh, ulMaxPos;
- LPSTR lpszFileName = NULL;
- /*
- * If file is not open, open it
- */
- if (lpIVTAbc->hFile == INVALID_HANDLE_VALUE)
- {
- if (!FEqualSABFiles(lpIVTAbc->lpABLogon, lpIVTAbc->lpszFileName))
- {
- /*
- * Get the new file name
- */
- hResult = HrLpszGetCurrentFileName(lpIVTAbc->lpABLogon, &lpszFileName);
- if (HR_FAILED(hResult))
- {
- goto err;
- }
- /*
- * Replace the old one with this
- */
- lpIVTAbc->lpFreeBuff(lpIVTAbc->lpszFileName);
- lpIVTAbc->lpszFileName = lpszFileName;
- lpszFileName = NULL;
- }
- /*
- * File is not open so lets try to open it
- */
- lpIVTAbc->hFile = CreateFile(
- lpIVTAbc->lpszFileName,
- GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (lpIVTAbc->hFile == INVALID_HANDLE_VALUE)
- {
- /*
- * The file didn't open...
- */
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpIVTAbc, hResult, IDS_CANT_OPEN_SAB_FILE);
- goto err;
- }
- }
- /*
- * Get the time and date stamp
- */
- if (!GetFileTime(lpIVTAbc->hFile, NULL, NULL, &filetime))
- {
- if (GetLastError() != NO_ERROR)
- {
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_FILE_ATTRIB);
- }
- goto err;
- }
- /* Get the size of the file */
- if ((ulSize = GetFileSize(lpIVTAbc->hFile, &ulSizeHigh)) == 0xFFFFFFFF)
- {
- /*
- * MAYBE I have an error
- */
- if (GetLastError() != NO_ERROR)
- {
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_FILE_ATTRIB);
- goto err;
- }
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_TOO_LARGE);
- goto err;
- }
- /*
- * Actual number of valid positions
- */
- ulMaxPos = (ulSize / sizeof(ABCREC));
- /*
- * Check to see if it's an exact multiple of sizeof(ABCREC)
- */
- if (ulMaxPos * sizeof(ABCREC) != ulSize)
- {
- hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
- SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_CORRUPT);
- goto err;
- }
- /*
- * if the file has changed set new position, reset bookmarks etc and
- * notify everybody one the advise list
- */
- if (CompareFileTime(&filetime, &lpIVTAbc->filetime) || ulMaxPos != lpIVTAbc->ulMaxPos)
- {
- ULONG ulBK;
- ABCREC abcrec;
- ULONG cbT;
- LPMAPIADVISESINK *ppadvise;
- ULONG cAdvises;
- NOTIFICATION notif;
- /* save new max position and filetime */
- lpIVTAbc->filetime = filetime;
- lpIVTAbc->ulMaxPos = ulMaxPos;
- /* if current position is past the end of file set it to the end */
- if (lpIVTAbc->ulPosition > lpIVTAbc->ulMaxPos)
- lpIVTAbc->ulPosition = lpIVTAbc->ulMaxPos;
- if (ulMaxPos)
- {
- SetFilePointer(lpIVTAbc->hFile, (ulMaxPos - 1)*sizeof(ABCREC), NULL, FILE_BEGIN);
- /* Read in the record at that location */
- if (!ReadFile(lpIVTAbc->hFile, (LPVOID) &abcrec,
- sizeof(ABCREC), &cbT, NULL))
- {
- hResult = ResultFromScode(MAPI_E_DISK_ERROR);
- SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_NO_READ);
- goto err;
- }
- /* if any of the bookmarks are past the end of file
- * set the file time to current file time, the position to last
- * record and record to last record
- */
- for (ulBK = 0; ulBK < MAX_BOOKMARKS; ulBK++)
- if (lpIVTAbc->rglpABCBK[ulBK] &&
- lpIVTAbc->rglpABCBK[ulBK]->ulPosition > lpIVTAbc->ulMaxPos)
- {
- lpIVTAbc->rglpABCBK[ulBK]->ulPosition = ulMaxPos - 1;
- lpIVTAbc->rglpABCBK[ulBK]->filetime = filetime;
- lpIVTAbc->rglpABCBK[ulBK]->abcrec = abcrec;
- }
- /*
- * Reallocate the checked&matched arrays
- */
- cbT = (lpIVTAbc->ulMaxPos) / 8 + 1; /* Number of bytes in both arrays */
- /* Reallocate ANR bitmaps */
- if (lpIVTAbc->rgChecked)
- {
- lpIVTAbc->rgChecked = lpIVTAbc->lpMalloc->lpVtbl->Realloc(
- lpIVTAbc->lpMalloc,
- lpIVTAbc->rgChecked,
- cbT);
- }
- if (lpIVTAbc->rgMatched)
- {
- lpIVTAbc->rgMatched = lpIVTAbc->lpMalloc->lpVtbl->Realloc(
- lpIVTAbc->lpMalloc,
- lpIVTAbc->rgMatched,
- cbT);
- }
- }
- else
- {
- /* if any of the bookmarks are past the end of file
- * set the file time to current file time, the position to the
- * beginning of the file.
- */
- for (ulBK = 0; ulBK < MAX_BOOKMARKS; ulBK++)
- if (lpIVTAbc->rglpABCBK[ulBK] &&
- lpIVTAbc->rglpABCBK[ulBK]->ulPosition > lpIVTAbc->ulMaxPos)
- {
- lpIVTAbc->rglpABCBK[ulBK]->ulPosition = 0;
- lpIVTAbc->rglpABCBK[ulBK]->filetime = filetime;
- }
- /* free the ANR bitmaps */
- FreeANRBitmaps(lpIVTAbc);
- }
- /* initialize the notification */
- ZeroMemory(¬if, sizeof(NOTIFICATION));
- notif.ulEventType = fnevTableModified;
- notif.info.tab.ulTableEvent = TABLE_RELOAD;
- /* notify everyone that the table has changed */
- for (ppadvise = lpIVTAbc->parglpAdvise, cAdvises = 0;
- cAdvises < lpIVTAbc->cAdvise;
- ++ppadvise, ++cAdvises)
- {
- Assert(*ppadvise);
- if (ppadvise)
- (void)(*ppadvise)->lpVtbl->OnNotify(*ppadvise, 1, ¬if);
- }
- }
- out:
- DebugTraceResult(NewIVTAbc, hResult);
- return hResult;
- err:
- lpIVTAbc->lpFreeBuff(lpszFileName);
- goto out;
- }
- /*************************************************************************
- *
- - fIVTAbcIdleRoutine
- -
- * This function called during idle time closes the .SAB file and notifies
- * everyone on the advise list if the file name has changed
- *
- */
- BOOL STDAPICALLTYPE
- fIVTAbcIdleRoutine(LPVOID lpv)
- {
- LPIVTABC lpIVTAbc = (LPIVTABC) lpv;
- Assert(lpv);
- /* if file is open close it */
- if (lpIVTAbc->hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(lpIVTAbc->hFile);
- lpIVTAbc->hFile = INVALID_HANDLE_VALUE;
- }
- /* has file name has changed? */
- if (!FEqualSABFiles(lpIVTAbc->lpABLogon, lpIVTAbc->lpszFileName))
- {
- /* file name has changed so call HrOpenFile to reset bookmarks etc */
- if (!HR_FAILED(HrOpenFile(lpIVTAbc)))
- {
- /* close the file */
- CloseHandle(lpIVTAbc->hFile);
- lpIVTAbc->hFile = INVALID_HANDLE_VALUE;
- }
- }
- return TRUE;
- }
- /*************************************************************************
- *
- - FreeANRBitmaps
- -
- * Frees the two ANR bitmaps associated with this table
- *
- *
- */
- void
- FreeANRBitmaps(LPIVTABC lpIVTAbc)
- {
- if (lpIVTAbc->rgChecked)
- {
- lpIVTAbc->lpMalloc->lpVtbl->Free(lpIVTAbc->lpMalloc, lpIVTAbc->rgChecked);
- lpIVTAbc->rgChecked = NULL;
- }
- if (lpIVTAbc->rgMatched)
- {
- lpIVTAbc->lpMalloc->lpVtbl->Free(lpIVTAbc->lpMalloc, lpIVTAbc->rgMatched);
- lpIVTAbc->rgMatched = NULL;
- }
- }
- /*
- * FCharInString
- *
- * Finds a character in a string
- */
- BOOL
- FCharInString(LPSTR lpsz, CHAR ch)
- {
- while (*lpsz && *lpsz != ch)
- lpsz++;
- return (*lpsz == ch);
- }