3737#include < gromox/util.hpp>
3838#include " common_util.hpp"
3939#include " nsp_interface.hpp"
40+ #include " repr.cpp"
4041
4142using namespace std ::string_literals;
4243using namespace gromox ;
@@ -904,6 +905,9 @@ ec_error_t nsp_interface_seek_entries(NSPI_HANDLE handle, uint32_t reserved,
904905{
905906 *pprows = nullptr ;
906907 nsp_trace (__func__, 0 , pstat);
908+ if (g_nsp_trace >= 2 && ptarget != nullptr )
909+ fprintf (stderr, " seek_entries target={%xh,%s}\n " ,
910+ ptarget->proptag , ptarget->repr ().c_str ());
907911 if (handle.handle_type != HANDLE_EXCHANGE_NSP)
908912 return ecError;
909913 if (pstat == nullptr || pstat->codepage == CP_WINUNICODE ||
@@ -1172,6 +1176,22 @@ static std::unordered_set<std::string> delegates_for(const char *dir) try
11721176 return {};
11731177}
11741178
1179+ /* *
1180+ * Used to search the address book based on certain criteria (like a display
1181+ * name prefix), and returns a list of matching entries.
1182+ *
1183+ * (Also see resolve_namesw for differences.)
1184+ *
1185+ * Outlook uses get_matches(container=PR_EMS_AB_MEMBER, cur_rec=<minid of an
1186+ * mlist>, filter=nullptr) to obtain the members of an address list.
1187+ *
1188+ * Outlook uses get_matches(container=0 <gal>, cur_rec=0, filter={PR_ANR,
1189+ * "needle"}) as an alternative to resolve_names().
1190+ *
1191+ * Also note that get_matches(container=0, filter=RES_EXIST{PR_ENTRYID}) yields
1192+ * the same as iterating the GAL with query_rows(container=0). We need to be
1193+ * wary of HIDE flag testing.
1194+ */
11751195ec_error_t nsp_interface_get_matches (NSPI_HANDLE handle, uint32_t reserved1,
11761196 STAT *pstat, const MID_ARRAY *ptable, uint32_t reserved2,
11771197 const NSPRES *pfilter, const NSP_PROPNAME *ppropname,
@@ -1181,6 +1201,8 @@ ec_error_t nsp_interface_get_matches(NSPI_HANDLE handle, uint32_t reserved1,
11811201 *ppoutmids = nullptr ;
11821202 *pprows = nullptr ;
11831203 nsp_trace (__func__, 0 , pstat);
1204+ if (g_nsp_trace >= 2 && pfilter != nullptr )
1205+ mlog (LV_DEBUG, " get_matches filter: %s" , pfilter->repr ().c_str ());
11841206 if (handle.handle_type != HANDLE_EXCHANGE_NSP)
11851207 return ecError;
11861208 PROPERTY_VALUE prop_val;
@@ -1236,7 +1258,6 @@ ec_error_t nsp_interface_get_matches(NSPI_HANDLE handle, uint32_t reserved1,
12361258 return ecServerOOM;
12371259 *pproptag = node.mid ;
12381260 }
1239- goto FETCH_ROWS;
12401261 } else if (pstat->container_id == PR_EMS_AB_PUBLIC_DELEGATES) {
12411262 ab_tree::ab_node node (base, pstat->cur_rec );
12421263 if (!node.exists ())
@@ -1264,9 +1285,8 @@ ec_error_t nsp_interface_get_matches(NSPI_HANDLE handle, uint32_t reserved1,
12641285 return ecServerOOM;
12651286 *pproptag = node.mid ;
12661287 }
1267- goto FETCH_ROWS;
1268- }
1269- if (pfilter == nullptr ) {
1288+ } else if (pfilter == nullptr ) {
1289+ /* OXNSPI v14 §3.1.4.1.10 pg. 56 item 8 */
12701290 char temp_buff[1024 ];
12711291 ab_tree::ab_node node = {base, pstat->cur_rec };
12721292 if (node.exists () && nsp_interface_fetch_property (node,
@@ -1278,15 +1298,19 @@ ec_error_t nsp_interface_get_matches(NSPI_HANDLE handle, uint32_t reserved1,
12781298 *pproptag = node.mid ;
12791299 }
12801300 } else if (pstat->container_id == 0 ) {
1301+ /* Alternative attempt by OL to do resolvenames */
12811302 uint32_t start_pos, total;
12821303 nsp_interface_position_in_list (pstat, base.get (), &start_pos, &total);
1283- for (auto it = base->ubegin () + start_pos; it != base->uend () && it-base->ubegin () < total; ++it)
1284- if (nsp_interface_match_node ({base, *it}, pstat->codepage , pfilter)) {
1285- auto pproptag = common_util_proptagarray_enlarge (outmids);
1286- if (pproptag == nullptr )
1287- return ecServerOOM;
1288- *pproptag = *it;
1289- }
1304+ for (auto it = base->ubegin () + start_pos; it != base->uend () && it-base->ubegin () < total; ++it) {
1305+ ab_tree::ab_node node (base, *it);
1306+ if (node.hidden () & (AB_HIDE_RESOLVE | AB_HIDE_FROM_GAL) ||
1307+ !nsp_interface_match_node (node, pstat->codepage , pfilter))
1308+ continue ;
1309+ auto pproptag = common_util_proptagarray_enlarge (outmids);
1310+ if (pproptag == nullptr )
1311+ return ecServerOOM;
1312+ *pproptag = *it;
1313+ }
12901314 } else {
12911315 ab_tree::ab_node node (base, pstat->container_id );
12921316 if (!node.exists ())
@@ -1301,18 +1325,19 @@ ec_error_t nsp_interface_get_matches(NSPI_HANDLE handle, uint32_t reserved1,
13011325 nsp_trace (__func__, 1 , pstat, nullptr , rowset);
13021326 return ecSuccess;
13031327 }
1304- for (auto it = node.begin () + start_pos; it != node.end (); ++it)
1305- if (!(node.hidden () & AB_HIDE_FROM_AL) && nsp_interface_match_node ({base, *it}, pstat->codepage , pfilter)) {
1306- auto pproptag = common_util_proptagarray_enlarge (outmids);
1307- if (pproptag == nullptr )
1308- return ecServerOOM;
1309- *pproptag = *it;
1310- if (outmids->cvalues >= requested)
1311- break ;
1312- }
1328+ for (auto it = node.begin () + start_pos; it != node.end (); ++it) {
1329+ if (node.hidden () & (AB_HIDE_RESOLVE | AB_HIDE_FROM_AL) ||
1330+ !nsp_interface_match_node ({base, *it}, pstat->codepage , pfilter))
1331+ continue ;
1332+ auto pproptag = common_util_proptagarray_enlarge (outmids);
1333+ if (pproptag == nullptr )
1334+ return ecServerOOM;
1335+ *pproptag = *it;
1336+ if (outmids->cvalues >= requested)
1337+ break ;
1338+ }
13131339 }
13141340
1315- FETCH_ROWS:
13161341 if (rowset != nullptr ) {
13171342 for (size_t i = 0 ; i < outmids->cvalues ; ++i) {
13181343 auto prow = common_util_proprowset_enlarge (rowset);
@@ -2090,6 +2115,15 @@ static ab_tree::minid nsp_interface_resolve_gal(const ab_tree::ab::const_base_re
20902115 return res;
20912116}
20922117
2118+ /* *
2119+ * Used to resolve a list of names into unique address book entries (or fail if
2120+ * ambiguous).
2121+ *
2122+ * (Also see get_matches for differences.)
2123+ *
2124+ * If Outlook does not get a resolution using this call, it will retry with
2125+ * get_matches()!
2126+ */
20932127ec_error_t nsp_interface_resolve_namesw (NSPI_HANDLE handle, uint32_t reserved,
20942128 const STAT *pstat, LPROPTAG_ARRAY *&pproptags,
20952129 const STRINGS_ARRAY *pstrs, MID_ARRAY **ppmids, NSP_ROWSET **pprows)
0 commit comments