/****************************************************************************** Takes the fullpath to a Domino directory. Returns the first match to 'name' from the '($Users)' view. Allows case-insensitive & partial match Returns empty string if not found ******************************************************************************/ std::wstring RecipientsHandler::SearchDominoDirectory(char* pszDirectoryPath, const std::wstring &name) { std::wstring result; WORD wABCount = 0; WORD wABBufferLength = 0; WORD wSignalFlags; WORD wItemDataType; DWORD dwMatches = 0; DWORD dwEntriesFound = 0; HANDLE hABBuffer = 0; HANDLE hSummaryBuffer = 0; DBHANDLE hdbDirectory = 0; HCOLLECTION hCollection = 0; NOTEID nidLookupView; COLLECTIONPOSITION cp; ITEM_VALUE_TABLE* pivt; WORD* pItemLengthTable; BYTE* pItem; LIST* plHeader; char szBuffer[MAXUSERNAME] = {0}; STATUS status = NSFDbOpen(pszDirectoryPath, &hdbDirectory); if (NOERROR == status) { status = NIFFindView(hdbDirectory, USERNAMESSPACE_ALT, &nidLookupView); if (NOERROR == status) { status = NIFOpenCollection( hdbDirectory, hdbDirectory, nidLookupView, 0, NULLHANDLE, &hCollection, NULLHANDLE, NULL, NULLHANDLE, NULLHANDLE); if (NOERROR == status) { status = NIFFindByName( hCollection, Workshare::Conversions::W22LMBCS(name).c_str(), FIND_PARTIAL | FIND_CASE_INSENSITIVE, &cp, &dwMatches); if (NOERROR == status && dwMatches > 0) { do { status = NIFReadEntries(hCollection, &cp, NAVIGATE_CURRENT, 0, NAVIGATE_NEXT, dwMatches, READ_MASK_SUMMARYVALUES, &hSummaryBuffer, NULL, NULL, &dwEntriesFound, &wSignalFlags); if (NOERROR == status && hSummaryBuffer != NULLHANDLE) { pivt = OSLock(ITEM_VALUE_TABLE, hSummaryBuffer); if (dwEntriesFound > 0) { if (pivt->Items > 0) { pItemLengthTable = (WORD*)++pivt; pivt--; pItem = (BYTE*)pItemLengthTable; pItem += (pivt->Items * sizeof(WORD)); // at this point pItemLength -> 1st item length // pItem -> 1st item datatype WORD wItemDataType = *((WORD*)pItem); pItem += sizeof(WORD); // pItem -> data switch (wItemDataType) { case TYPE_TEXT: { strncpy_s(szBuffer, sizeof(szBuffer), (char*)pItem, pItemLengthTable[0]); result = Workshare::Conversions::LMBCS22W(szBuffer); break; } case TYPE_TEXT_LIST: { plHeader = (LIST*)pItem; if (plHeader->ListEntries > 0) { pItemLengthTable = (WORD*)++plHeader; plHeader--; pItem = (BYTE*)plHeader; pItem += sizeof(LIST) + plHeader->ListEntries * sizeof(WORD); strncpy_s(szBuffer, sizeof(szBuffer), (char*)pItem, pItemLengthTable[0]); result = Workshare::Conversions::LMBCS22W(szBuffer); } break; } default: { break; } } } } OSUnlock(hSummaryBuffer); OSMemFree(hSummaryBuffer); } wSignalFlags = 0; // to ensure we only go around once } while (wSignalFlags & SIGNAL_MORE_TO_DO); } NIFCloseCollection(hCollection); } } NSFDbClose(hdbDirectory); } return result; }
/** eus_GetDesignNote( *** Obtain the NoteID of the specified database design note. --- parameters & return ------ h_DB_TARGET: handle to the target database us_NOTE_CLASS: The class(es) of design note to be located in the target database. Multiple non-single-instance classes may be specified by ORing them together. pc_NOTENM: Optional. Pointer to the name of the design-element note to be located in the target database. Required if the note class (us_NOTE_CLASS) is not of the unique-note type. If the note class is of the unique-note type, the parameter is ignored. pnid: Output. Address of the variable in which to store the NoteID of the located design note. RETURN: eus_SUCCESS if no error occured !eus_SUCCESS if invalid parameters were passed ERR_NOT_FOUND if specified design note could not be located in the database the Notes API error code otherwise --- suggested enhancement ---- 2/22/00 PR + should not search for aliases in view/folder, agent or page notes as those do aliasing by pipe delimiter in a regular text field (not text-list), and NIFFindDesignNote() finds aliases in such notes correctly + important to allow case-insensitivity when searching aliases, as NIFFindDesignNote() works that way --- revision history --------- 2/22/00 PR: created */ STATUS eus_GetDesignNote( DBHANDLE H, const WORD us_NOTE_CLASS, char *const pc_NOTENM, NOTEID *const pnid) { const BOOL f_SPECIAL_DESIGN_NOTE = !!(us_NOTE_CLASS & NOTE_CLASS_SINGLE_INSTANCE); HCOLLECTION hcl; COLLECTIONPOSITION t_pos; WORD us_flags; NOTEID nid, nid_tentative; STATUS us_err, us_errTemp; if (!( H && us_NOTE_CLASS && (!pc_NOTENM ? f_SPECIAL_DESIGN_NOTE : TRUE) && pnid)) return !eus_SUCCESS; *pnid = nid = nid_tentative = NULL; //if we're looking for a "special" design note (i.e. one-of-a-kind and // therefore not necessary to "name"), try to get ahold of it and return // the result if (f_SPECIAL_DESIGN_NOTE) return NSFDbGetSpecialNoteID( H, (WORD) (SPECIAL_ID_NOTE | us_NOTE_CLASS), pnid); //if the named design note can be located by normal means, do so and // return the result if ((us_err = NIFFindDesignNote( H, pc_NOTENM, us_NOTE_CLASS, pnid)) && ERR( us_err) != ERR_NOT_FOUND) return us_err; if (!us_err) return eus_SUCCESS; //Since the name wasn't found by main title, we will try to to find a // matching alias. First, get ahold of the database's design-note // collection. if (us_err = NIFOpenCollection( H, H, NOTE_CLASS_DESIGN | NOTE_ID_SPECIAL, OPEN_SHARED_VIEW_NOTE, NULLHANDLE, &hcl, NULL, NULL, NULL, NULL)) return us_err; //then for each design note... memset( &t_pos, NULL, sizeof( COLLECTIONPOSITION)); do { const DWORD ul_ALL_ENTRIES = 0xFFFFFFFF; const WORD us_OFFSET_STATIC = sizeof( NOTEID) + sizeof( WORD); HANDLE h; DWORD ul; void * pv_entry; WORD us_entry; if ((us_err = NIFReadEntries( hcl, &t_pos, NAVIGATE_NEXT, 1, NAVIGATE_NEXT, ul_ALL_ENTRIES, READ_MASK_NOTEID | READ_MASK_NOTECLASS | READ_MASK_SUMMARY, &h, NULL, NULL, &ul, &us_flags)) || !ul) goto errJump; pv_entry = OSLockObject( h); for (us_entry = 0; us_entry < ul; us_entry++, (BYTE *) pv_entry += us_OFFSET_STATIC + ((ITEM_TABLE *) ((BYTE *) pv_entry + us_OFFSET_STATIC))->Length) { void * pv; WORD us_typ, us_count, us; //if the note is not of the desired design class, loop for the // next note if (!( *(WORD *) ((NOTEID *) pv_entry + 1) & us_NOTE_CLASS)) continue; //if the note has no alias info, loop for the next note if (!NSFLocateSummaryValue( (ITEM_TABLE *) ((BYTE *) pv_entry + us_OFFSET_STATIC), FIELD_TITLE, &pv, &us, &us_typ) || us_typ != TYPE_TEXT_LIST) continue; //if no alias match is found, loop for the next note if (!ef_TextListContainsEntry( pv, FALSE, pc_NOTENM, &us, &us_count)) continue; _ASSERTE( us && us_count > 1); //if our match is the last alias in the title item, or if the // last alias is also a match, set the output NoteID, then // break out of these loops if (us == us_count - 1 || ef_TextListEntryMatches( pv, FALSE, (WORD) (us_count - 1), pc_NOTENM)) { nid = *(NOTEID *) pv_entry; break; } //if we haven't found another already, note that we've found a // tentative match if (!nid_tentative) nid_tentative = *(NOTEID *) pv_entry; } //for (us_entry = 0; us_entry < ul //free resouces associated with this instance of reading the // design-note collection OSUnlockObject( h); OSMemFree( h); } while (us_flags & SIGNAL_MORE_TO_DO && !nid); //if no "output" NoteID was set... if (!nid) //if a tentative NoteID match was found... if (nid_tentative) //we can now bless it as the actual match, so commit it as the // output NoteID *pnid = nid_tentative; //else set an error that the note was not found else us_err = ERR_NOT_FOUND; //else commit the "output" NoteID as the actual output else *pnid = nid; errJump: if (us_errTemp = NIFCloseCollection( hcl)) if (!us_err) us_err = us_errTemp; return us_err; } //eus_GetDesignNote(
/****************************************************************************** Searches a CONDENSED directory for the specified name Allows case-insensitive & partial match Returns empty string if not found ******************************************************************************/ std::wstring RecipientsHandler::SearchCondensedDirectory(char* pszDirectoryPath, const std::wstring &name) { #define LOOKUP_VIEW "Users" // Column numbers counting from 0 #define SEARCH_COLUMN 1 // lookup column #define RETURN_COLUMN 3 // return column(@Subset(FullName;1) // lookup column must be < return column std::wstring result; std::wstring columnvalue; WORD wABCount = 0; WORD wABBufferLength = 0; WORD wSignalFlags; WORD wItemDataType; WORD wIVTLength; DWORD dwEntriesFound = 0; DWORD dwEntryIndex; HANDLE hABBuffer = 0; HANDLE hSummaryBuffer = 0; DBHANDLE hdbDirectory = 0; HCOLLECTION hCollection = 0; NOTEID nidLookupView; COLLECTIONPOSITION cp; ITEM_VALUE_TABLE* pivt; BYTE* pSummaryBuffer; WORD* pItemLengthTable; BYTE* pItem; int nColumnCount; char szBuffer[MAXUSERNAME] = {0}; STATUS status = NSFDbOpen(pszDirectoryPath, &hdbDirectory); if (NOERROR == status) { status = NIFFindView(hdbDirectory, LOOKUP_VIEW, &nidLookupView); if (NOERROR == status) { status = NIFOpenCollection( hdbDirectory, hdbDirectory, nidLookupView, 0, NULLHANDLE, &hCollection, NULLHANDLE, NULL, NULLHANDLE, NULLHANDLE); if (NOERROR == status) { cp.Level = 0; cp.Tumbler[0] = 0; do { status = NIFReadEntries(hCollection, &cp, NAVIGATE_NEXT, 1, NAVIGATE_NEXT, 0xffffffff, READ_MASK_SUMMARYVALUES, &hSummaryBuffer, NULL, NULL, &dwEntriesFound, &wSignalFlags); if (NOERROR == status && hSummaryBuffer != NULLHANDLE) { pSummaryBuffer = OSLock(BYTE, hSummaryBuffer); wIVTLength = 0; for (dwEntryIndex = 0; dwEntryIndex < dwEntriesFound; dwEntryIndex++) { pSummaryBuffer += wIVTLength; pivt = (ITEM_VALUE_TABLE*)pSummaryBuffer; wIVTLength = pivt->Length; if (pivt->Items > RETURN_COLUMN) { pItemLengthTable = (WORD*)++pivt; pivt--; pItem = (BYTE*)pItemLengthTable; pItem += (pivt->Items * sizeof(WORD)); // at this point pItemLengthTable -> 1st item length // pItem -> 1st item datatype WORD // bump up to the specified COLUMN_NUMBER for (nColumnCount = 0; nColumnCount < SEARCH_COLUMN; nColumnCount++) { pItem += *pItemLengthTable++; } wItemDataType = *((WORD*)pItem); pItem += sizeof(WORD); // pItem -> data if (wItemDataType == TYPE_TEXT) { strncpy_s(szBuffer, sizeof(szBuffer), (char*)pItem, pItemLengthTable[0] - sizeof(WORD)); columnvalue = Workshare::Conversions::LMBCS22W(szBuffer); if (_wcsnicmp(columnvalue.c_str(), name.c_str(), name.length()) == 0) { pItem -= sizeof(WORD); // bump up to the column to be returned for (nColumnCount = SEARCH_COLUMN; nColumnCount < RETURN_COLUMN; nColumnCount++) { pItem += *pItemLengthTable++; } wItemDataType = *((WORD*)pItem); pItem += sizeof(WORD); // pItem -> data if (wItemDataType == TYPE_TEXT) { strncpy_s(szBuffer, sizeof(szBuffer), (char*)pItem, pItemLengthTable[0] - sizeof(WORD)); result = Workshare::Conversions::LMBCS22W(szBuffer); wSignalFlags = 0; // exits do - while break; // exits for } } } } } // end for OSUnlock(hSummaryBuffer); OSMemFree(hSummaryBuffer); } } while (wSignalFlags & SIGNAL_MORE_TO_DO); NIFCloseCollection(hCollection); } } NSFDbClose(hdbDirectory); } return result; }
_declspec ( dllexport ) WORD GetServerNamesEx(char retServerNames[MAX_SERVERS][MAXPATH]) { BOOL status = NOERROR; char szLocation[MAXENVVALUE]; char szPAB[MAXENVVALUE]; HANDLE db; char full_netpath[MAXPATH-1]; NOTEID view_id; HCOLLECTION hCollection; COLLECTIONPOSITION pCollPosition; HANDLE hBuffer; DWORD NumberReturned = 0; NOTEID *IdList; NOTEHANDLE note; char szFieldName[80] = { 0 }; char szFieldType[80] = { 0 }; WORD retServerCount = 0; bool bUseLocal = false; // first, get the name of the current location status = OSGetEnvironmentString("Location", szLocation, MAXENVVALUE); if (status == TRUE) { char *pb = strchr(szLocation, ','); if (pb != NULL) *pb = 0 ; } status = OSGetEnvironmentString("MAILSERVER", szPAB, MAXENVVALUE); if (status == TRUE) { char *pb = strchr(szPAB, ','); if (pb != NULL) *pb = 0 ; } if (status = OSPathNetConstruct(NULL, szPAB, _T("names.nsf"), full_netpath)) { printf("unable to open the public NAB %s!!names.nsf\n", szFieldName); return 0; } if (status = NSFDbOpen (full_netpath, &db)) return 0; if (bUseLocal) { // choose local PAB view if (status = NIFFindView(db, _T("Connections"), &view_id)) { NSFDbClose(db); return 0; } } else { // choose server list from server Directory if (status = NIFFindView(db, _T("Servers"), &view_id)) { NSFDbClose(db); return 0; } } if (status = NIFOpenCollection( db, db, view_id, 0, NULLHANDLE, &hCollection, NULL, NULL, NULL, NULL )) { NSFDbClose(db); return 0; } pCollPosition.Level = 0; pCollPosition.Tumbler[0] = 1; if (status = NIFReadEntries(hCollection, &pCollPosition, NAVIGATE_CURRENT, 1L, NAVIGATE_NEXT, 0xFFFFFFFF, READ_MASK_NOTEID, &hBuffer, NULL, NULL, &NumberReturned, NULL)) { NIFCloseCollection(hCollection); NSFDbClose(db); return 0; } strcpy_s(retServerNames[retServerCount++], MAXPATH, _T("Local")); if (NumberReturned != 0) { if (hBuffer != NULLHANDLE) { IdList = (NOTEID far *)OSLockObject(hBuffer); for (DWORD i=0; i<(DWORD)NumberReturned; i++) { if (status = NSFNoteOpen( db, IdList[i], 0, ¬e)) { // skip categories } else { // scan documents WORD lenFieldName = NSFItemGetText(note, (bUseLocal) ? _T("Destination") : _T("ServerName"), szFieldName, sizeof(szFieldName)); strcpy_s(retServerNames[retServerCount++], MAXPATH, szFieldName); status = NSFNoteClose(note); } } OSUnlockObject(hBuffer); OSMemFree(hBuffer); } } if (status) { NIFCloseCollection(hCollection); NSFDbClose(db); return 0; } if (status = NIFCloseCollection(hCollection)) { NSFDbClose(db); return 0; } if (status = NSFDbClose(db)) return 0; return retServerCount; }