Windows2000/private/shell/shell32/netfind.c
2020-09-30 17:12:32 +02:00

1528 lines
43 KiB
C

// Copyright (c) Microsoft Corporation 1991-1993
// File: netfind.c
// Description: This file contains the net specific search code that is
// needed for the find computer code.
#include "shellprv.h"
#pragma hdrstop
#include "shellids.h" // new help ids are stored here
#include "docfind.h"
#include "netview.h"
#include "prop.h"
#define NET_TIMINGS
#ifdef NET_TIMINGS
int NTF_cNoPEnum = 0;
int NTF_dtNoPEnum = 0;
int NTF_cNextItem = 0;
int NTF_dtNextItem = 0;
int NTF_dtTime = 0;
#endif
STDAPI GetDomainWorkgroupIDList(LPITEMIDLIST *ppidl);
STDAPI CNetFindInDS_CreateInstance(LPCTSTR pszCompName, IShellFolder *psf, IDFEnum **ppdfe);
enum
{
INFCOL_NAME = 0,
INFCOL_PATH,
INFCOL_COMMENT,
};
const COL_DATA c_findcomp_cols[] = {
{INFCOL_NAME, IDS_NAME_COL, 20, LVCFMT_LEFT, &SCID_NAME},
{INFCOL_PATH, IDS_WORKGROUP_COL, 20, LVCFMT_LEFT, &SCID_DIRECTORY},
{INFCOL_COMMENT, IDS_COMMENT_COL, 20, LVCFMT_LEFT, &SCID_Comment}
};
#define DFM_DEFERINIT (WM_USER+42)
// REVIEW:: The recursive code in this module has been totally neutered to
// make the ITG group happy. IE we mad this functional mostly usless and
// wasted a lot of time doing so... The ifdefs are under #ifdef CASTRATED
// Define the Default data filter data structures
// From netviewx.c
STDMETHODIMP CNETDetails_GetDetailsOf(IShellDetails * psd, LPCITEMIDLIST pidl, UINT iCol, LPSHELLDETAILS lpDetails);
// Define the internal structure of our default filter
typedef struct _CNETFilter // fff
{
IDocFindFileFilter dfff;
UINT cRef;
HWND hwndTabs;
HANDLE hMRUSpecs;
LPITEMIDLIST pidlStart; // Where to start the search from.
// Data associated with the file name.
LPTSTR pszCompName; // the one we do compares with
TCHAR szUserInputCompName[MAX_PATH]; // User input
} CNETFilter;
// Define common page data for each of our pages
// WARNING the fields in this must align the same as the definition
// in docfind2.c
typedef struct { // dfpsp
PROPSHEETPAGE psp;
HANDLE hThreadInit;
HWND hwndDlg;
CNETFilter * pdff;
DWORD dwState;
} DOCFINDPROPSHEETPAGE, * LPDOCFINDPROPSHEETPAGE;
#define DFPAGE_INIT 0x0001 /* This page has been initialized */
#define DFPAGE_CHANGE 0x0002 /* The user has modified the page */
// Prototypes of some of the internal functions.
BOOL_PTR CALLBACK DocFind_CCOMPFNameLocDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
// Define some other module global data
const DFPAGELIST s_CCOMPFplComp[] =
{
{DLG_NFNAMELOC, DocFind_CCOMPFNameLocDlgProc},
};
// Some global strings...
const TCHAR s_szCompSpecMRU[] = REGSTR_PATH_EXPLORER TEXT("\\FindComputerMRU");
// Create the default filter for our find code... They should be completly
// self contained...
// CNETFilter : member prototype
STDMETHODIMP CNETFilter_QueryInterface(IDocFindFileFilter *pnetf, REFIID riid, void **ppvObj);
STDMETHODIMP_(ULONG) CNETFilter_AddRef(IDocFindFileFilter *pnetf);
STDMETHODIMP_(ULONG) CNETFilter_Release(IDocFindFileFilter *pnetf);
STDMETHODIMP CNETFilter_GetIconsAndMenu (IDocFindFileFilter *pdfff,
HWND hwndDlg, HICON *phiconSmall, HICON *phiconLarge, HMENU *phmenu);
STDMETHODIMP CNETFilter_GetStatusMessageIndex (IDocFindFileFilter *pdfff,
UINT uContext, UINT *puMsgIndex);
STDMETHODIMP CNETFilter_GetFolderMergeMenuIndex (IDocFindFileFilter *pdfff,
UINT *puBGMainMergeMenu, UINT *puBGPopupMergeMenu);
STDMETHODIMP CNETFilter_AddPages(IDocFindFileFilter *pnetf, HWND hwndTabs,
LPITEMIDLIST pidlStart);
STDMETHODIMP CNetFilter_FFilterChanged(IDocFindFileFilter *pdfff);
STDMETHODIMP CNETFilter_GenerateTitle(IDocFindFileFilter *pnetf,
LPTSTR *ppszTitle, BOOL fFileName);
STDMETHODIMP CNETFilter_ClearSearchCriteria(IDocFindFileFilter *pnetf);
STDMETHODIMP CNETFilter_PrepareToEnumObjects(IDocFindFileFilter *pnetf, DWORD *pdwFlags);
STDMETHODIMP CNETFilter_GetDetails(IDocFindFileFilter *pnetf, HDPA hdpaPidf, int iItem, UINT iCol, PDETAILSINFO pdi);
STDMETHODIMP CNETFilter_ColumnClick(IDocFindFileFilter *pnetf, HWND hwndDlg, UINT iColumn);
STDMETHODIMP CNETFilter_EnumObjects (IDocFindFileFilter *pnetf, IShellFolder *psf, LPITEMIDLIST pidl,
DWORD grfFlags, int iCOlSort, LPTSTR pszProgressText, IRowsetWatchNotify *prwn, IDFEnum **ppdfenum) PURE;
STDMETHODIMP CNETFilter_GetDetailsOf(IDocFindFileFilter *pnetf, HDPA hdpaPidf, LPCITEMIDLIST pidl, UINT *piColumn, LPSHELLDETAILS pdi);
STDMETHODIMP CNETFilter_FDoesItemMatchFilter(IDocFindFileFilter *pnetf,
LPTSTR pszFolder, WIN32_FIND_DATA * pfinddata,
IShellFolder *psf, LPITEMIDLIST pidl);
STDMETHODIMP CNETFilter_SaveCriteria(IDocFindFileFilter *pnetf, IStream *pstm, WORD fCharType);
STDMETHODIMP CNETFilter_RestoreCriteria(IDocFindFileFilter *pnetf,
IStream * pstm, int cCriteria, WORD fCharType);
STDMETHODIMP CNETFilter_DeclareFSNotifyInterest(IDocFindFileFilter *pnetf, HWND hwndDlg, UINT uMsg);
STDMETHODIMP CNETFilter_GetColSaveStream(IDocFindFileFilter *pnetf, WPARAM wparam, LPSTREAM *ppstm);
STDMETHODIMP CNETFilter_GenerateQueryRestrictions(IDocFindFileFilter *pnetf, LPWSTR *ppwszQuery, DWORD *pdwGQRFlags);
STDMETHODIMP CNETFilter_ReleaseQuery(IDocFindFileFilter *pnetf);
STDMETHODIMP CNetFilter_UpdateField(IDocFindFileFilter *pdfff, BSTR szField, VARIANT vValue);
STDMETHODIMP CNetFilter_ResetFieldsToDefaults(IDocFindFileFilter *pdfff);
STDMETHODIMP CNetFilter_GetItemContextMenu(IDocFindFileFilter *pdfff, HWND hwndOwner, IDocFindFolder* pdfFolder, IContextMenu **ppcm);
STDMETHODIMP CNetFilter_GetDefaultSearchGUID(IDocFindFileFilter *pdfff, IShellFolder2 *psf2, LPGUID lpGuid);
STDMETHODIMP CNetFilter_EnumSearches(IDocFindFileFilter *pdfff, IShellFolder2 *psf2, LPENUMEXTRASEARCH *ppenum);
STDMETHODIMP CNetFilter_GetSearchFolderClassId(IDocFindFileFilter *pdfff, LPGUID lpGuid);
STDMETHODIMP CNetFilter_GetNextConstraint(IDocFindFileFilter *pdfff, VARIANT_BOOL fReset, BSTR *pName, VARIANT *pValue, VARIANT_BOOL *pfFound);
STDMETHODIMP CNetFilter_GetQueryLanguageDialect(IDocFindFileFilter *pdfff, ULONG * pulDialect) ;
IDocFindFileFilterVtbl c_CCOMPFFilterVtbl =
{
CNETFilter_QueryInterface, CNETFilter_AddRef, CNETFilter_Release,
CNETFilter_GetIconsAndMenu,
CNETFilter_GetStatusMessageIndex,
CNETFilter_GetFolderMergeMenuIndex,
CNetFilter_FFilterChanged,
CNETFilter_GenerateTitle,
CNETFilter_PrepareToEnumObjects,
CNETFilter_ClearSearchCriteria,
CNETFilter_EnumObjects,
CNETFilter_GetDetailsOf,
CNETFilter_FDoesItemMatchFilter,
CNETFilter_SaveCriteria,
CNETFilter_RestoreCriteria,
CNETFilter_DeclareFSNotifyInterest,
CNETFilter_GetColSaveStream,
CNETFilter_GenerateQueryRestrictions,
CNETFilter_ReleaseQuery,
CNetFilter_UpdateField,
CNetFilter_ResetFieldsToDefaults,
CNetFilter_GetItemContextMenu,
CNetFilter_GetDefaultSearchGUID,
CNetFilter_EnumSearches,
CNetFilter_GetSearchFolderClassId,
CNetFilter_GetNextConstraint,
CNetFilter_GetQueryLanguageDialect,
};
// Creation function to create default find filter...
IDocFindFileFilter * CreateDefaultComputerFindFilter()
{
CNETFilter *pfff = (void*)LocalAlloc(LPTR, SIZEOF(CNETFilter));
if (pfff == NULL)
return NULL;
pfff->dfff.lpVtbl = &c_CCOMPFFilterVtbl;
pfff->cRef = 1;
// We should now simply return the filter
return &pfff->dfff;
}
// Query interface for the docfind filter interface...
STDMETHODIMP CNETFilter_QueryInterface(IDocFindFileFilter *pnetf, REFIID riid, LPVOID FAR* ppvObj)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDocFindFileFilter))
{
*ppvObj = pnetf;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
CNETFilter_AddRef(pnetf);
return NOERROR;
}
// IDocFindFileFilter::AddRef
STDMETHODIMP_(ULONG) CNETFilter_AddRef(IDocFindFileFilter *pnetf)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
this->cRef++;
return(this->cRef);
}
// IDocFindFileFilter::Release
STDMETHODIMP_(ULONG) CNETFilter_Release(IDocFindFileFilter *pnetf)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
this->cRef--;
if (this->cRef>0)
{
return(this->cRef);
}
// Destroy the MRU Lists...
if (this->hMRUSpecs)
FreeMRUList(this->hMRUSpecs);
// unless we do not have a combobox
if (this->pidlStart)
ILFree(this->pidlStart);
Str_SetPtr(&(this->pszCompName), NULL);
LocalFree((HLOCAL)this);
return(0);
}
// IDocFindFileFilter::GetIconsAndMenu
STDMETHODIMP CNETFilter_GetIconsAndMenu (IDocFindFileFilter *pdfff,
HWND hwndDlg, HICON *phiconSmall, HICON *phiconLarge, HMENU *phmenu)
{
*phiconSmall = LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDI_COMPFIND),
IMAGE_ICON, g_cxSmIcon, g_cySmIcon, LR_DEFAULTCOLOR);
*phiconLarge = LoadIcon(HINST_THISDLL, MAKEINTRESOURCE(IDI_COMPFIND));
// Now for the menu
*phmenu = LoadMenu(HINST_THISDLL, MAKEINTRESOURCE(MENU_FINDCOMPDLG));
// BUGBUG:: Still menu to process!
return NOERROR;
}
// Function to get the string resource index number that is proper for the
// current type of search.
STDMETHODIMP CNETFilter_GetStatusMessageIndex (IDocFindFileFilter *pdfff,
UINT uContext, UINT *puMsgIndex)
{
// Currently context is not used
*puMsgIndex = IDS_COMPUTERSFOUND;
return NOERROR;
}
// Function to let find know which menu to load to merge for the folder
STDMETHODIMP CNETFilter_GetFolderMergeMenuIndex (IDocFindFileFilter *pdfff,
UINT *puBGMainMergeMenu, UINT *puBGPopupMergeMenu)
{
*puBGPopupMergeMenu = POPUP_NETFIND_POPUPMERGE;
return NOERROR;
}
STDMETHODIMP CNetFilter_GetItemContextMenu(IDocFindFileFilter *pdfff, HWND hwndOwner, IDocFindFolder* pdfFolder, IContextMenu **ppcm)
{
*ppcm = CDFFolderContextMenuItem_Create(hwndOwner, pdfFolder);
return (*ppcm) ? S_OK : E_OUTOFMEMORY;
}
STDMETHODIMP CNetFilter_GetDefaultSearchGUID(IDocFindFileFilter *pdfff, IShellFolder2 *psf2, LPGUID lpGuid)
{
*lpGuid = SRCID_SFindComputer;
return S_OK;
}
STDMETHODIMP CNetFilter_EnumSearches(IDocFindFileFilter *pdfff, IShellFolder2 *psf2, LPENUMEXTRASEARCH *ppenum)
{
return CNetwork_EnumSearches(psf2, ppenum);
}
STDMETHODIMP CNetFilter_GetSearchFolderClassId(IDocFindFileFilter *pdfff, LPGUID lpGuid)
{
*lpGuid = CLSID_ComputerFindFolder;
return S_OK;
}
STDMETHODIMP CNetFilter_GetNextConstraint(IDocFindFileFilter *pdfff, VARIANT_BOOL fReset, BSTR *pName, VARIANT *pValue, VARIANT_BOOL *pfFound)
{
*pName = NULL;
*pfFound = FALSE;
VariantClear(pValue);
return E_NOTIMPL;
}
STDMETHODIMP CNetFilter_GetQueryLanguageDialect(IDocFindFileFilter *pdfff, ULONG * pulDialect)
{
if( pulDialect )
*pulDialect = 0 ;
return E_NOTIMPL ;
}
// IDocFindFileFilter::FFilterChanged - Returns S_OK if nothing changed.
STDMETHODIMP CNetFilter_FFilterChanged(IDocFindFileFilter *pdfff)
{
// Currently not saving so who cares?
return S_FALSE;
}
// IDocFindFileFilter::GenerateTitle - Generates the title given the current
// search criteria.
STDMETHODIMP CNETFilter_GenerateTitle(IDocFindFileFilter *pnetf,
LPTSTR *ppszTitle, BOOL fFileName)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
// Now lets construct the message from the resource
*ppszTitle = ShellConstructMessageString(HINST_THISDLL,
MAKEINTRESOURCE(IDS_FIND_TITLE_COMPUTER), fFileName ? TEXT(" #") : TEXT(":"));
return *ppszTitle ? S_OK : E_OUTOFMEMORY;
}
// IDocFindFileFilter::ClearSearchCriteria
STDMETHODIMP CNETFilter_ClearSearchCriteria(IDocFindFileFilter *pnetf)
{
int cPages;
HWND hwndMainDlg;
TC_DFITEMEXTRA tie;
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
hwndMainDlg = GetParent(this->hwndTabs);
for (cPages = TabCtrl_GetItemCount(this->hwndTabs) -1; cPages >= 0; cPages--)
{
tie.tci.mask = TCIF_PARAM;
TabCtrl_GetItem(this->hwndTabs, cPages, &tie.tci);
SendNotify(tie.hwndPage, hwndMainDlg, PSN_RESET, NULL);
}
return NOERROR;
}
// IDocFindFileFilter::PrepareToEnumObjects
STDMETHODIMP CNETFilter_PrepareToEnumObjects(IDocFindFileFilter *pnetf, DWORD *pdwFlags)
{
int cPages;
HWND hwndMainDlg;
TC_DFITEMEXTRA tie;
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
if (this->hwndTabs)
{
hwndMainDlg = GetParent(this->hwndTabs);
for (cPages = TabCtrl_GetItemCount(this->hwndTabs) -1; cPages >= 0; cPages--)
{
tie.tci.mask = TCIF_PARAM;
TabCtrl_GetItem(this->hwndTabs, cPages, &tie.tci);
SendNotify(tie.hwndPage, hwndMainDlg, PSN_APPLY, NULL);
}
}
// Update the flags and buffer strings
*pdwFlags &= ~FFLT_INCLUDESUBDIRS;
// Also lets convert the Computer name pattern into the strings
// will do the compares against.
if ((this->szUserInputCompName[0] == TEXT('\\')) &&
(this->szUserInputCompName[1] == TEXT('\\')))
{
Str_SetPtr(&(this->pszCompName), this->szUserInputCompName);
}
else
{
DocFind_SetupWildCardingOnFileSpec(this->szUserInputCompName,
&this->pszCompName);
}
return NOERROR;
}
// IDocFindFileFilter::GetDetails
STDMETHODIMP CNETFilter_GetDetailsOf(IDocFindFileFilter *pnetf, HDPA hdpaPidf,
LPCITEMIDLIST pidl, UINT *piColumn, SHELLDETAILS *pdi)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
HRESULT hr = S_OK;
if (*piColumn >= ARRAYSIZE(c_findcomp_cols))
return E_NOTIMPL;
pdi->str.uType = STRRET_CSTR;
pdi->str.cStr[0] = 0;
if (!pidl)
{
pdi->fmt = c_findcomp_cols[*piColumn].iFmt;
pdi->cxChar = c_findcomp_cols[*piColumn].cchCol;
hr = ResToStrRet(c_findcomp_cols[*piColumn].ids, &pdi->str);
}
else
{
// We need to now get to the idlist of the items folder.
DFFolderListItem *pdffli = DPA_GetPtr(hdpaPidf, DF_IFOLDER(pidl));
hr = E_FAIL;
if (pdffli)
{
if (*piColumn == INFCOL_PATH)
{
TCHAR szName[MAX_PATH];
if (SUCCEEDED(SHGetNameAndFlags(&pdffli->idl, SHGDN_NORMAL, szName, SIZECHARS(szName), NULL)))
hr = StringToStrRet(szName, &pdi->str);
}
else if (*piColumn < ARRAYSIZE(c_findcomp_cols))
{
IShellFolder2 *psf;
if (SUCCEEDED(SHBindToObject(NULL, &IID_IShellFolder2, &pdffli->idl, (void **)&psf)))
{
hr = MapSCIDToDetailsOf(psf, pidl, c_findcomp_cols[*piColumn].pscid, pdi);
psf->lpVtbl->Release(psf);
}
}
}
}
return hr;
}
// IDocFindFileFilter::FDoesItemMatchFilter
STDMETHODIMP CNETFilter_FDoesItemMatchFilter(IDocFindFileFilter *pnetf,
LPTSTR pszFolder, WIN32_FIND_DATA * pfinddata,
IShellFolder *psf, LPITEMIDLIST pidl)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
// Make sure that we only return computers...
BYTE bType = SIL_GetType(pidl);
// First pass dont push anything that is below a computer...
if ((bType & (SHID_NET | SHID_INGROUPMASK)) != SHID_NET_SERVER)
return NOERROR; // does not match
// Here is where I start getting in bed with the network enumerator
// format of IDLists.
if (this->pszCompName && this->pszCompName[0])
{
// Although for now not much...
STRRET str;
TCHAR szPath[MAX_PATH];
if (FAILED(psf->lpVtbl->GetDisplayNameOf(psf, pidl, SHGDN_NORMAL, &str)) ||
FAILED(StrRetToBuf(&str, pidl, szPath, ARRAYSIZE(szPath))) ||
!PathMatchSpec(szPath, this->pszCompName))
{
return NOERROR; // does not match
}
}
return S_FALSE; // return TRUE to imply yes!
}
// IDocFindFileFilter::SaveCriteria
STDMETHODIMP CNETFilter_SaveCriteria(IDocFindFileFilter *pnetf, IStream *pstm, WORD fCharType)
{
#ifdef NOT_DONE_YET
#endif
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
int cCriteria = 0;
return (MAKE_SCODE(0, 0, cCriteria));
}
// IDocFindFileFilter::RestoreCriteria
STDMETHODIMP CNETFilter_RestoreCriteria(IDocFindFileFilter *pnetf,
IStream *pstm, int cCriteria, WORD fCharType)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
#ifdef NOT_DONE_YET
#endif
return NOERROR;
}
// IDocFindFileFilter::GetColSaveStream
STDMETHODIMP CNETFilter_GetColSaveStream(IDocFindFileFilter *pnetf, WPARAM wparam, LPSTREAM *ppstm)
{
*ppstm = NULL;
return E_NOTIMPL;
}
STDMETHODIMP CNETFilter_GenerateQueryRestrictions(IDocFindFileFilter *pnetf, LPWSTR *ppszQuery, DWORD *pdwGQR_Flags)
{
if (ppszQuery)
*ppszQuery = NULL;
*pdwGQR_Flags = 0;
return E_NOTIMPL;
}
STDMETHODIMP CNETFilter_ReleaseQuery(IDocFindFileFilter *pnetf)
{
return S_OK;
}
HRESULT CNetFilter_UpdateField(IDocFindFileFilter *pnetf, BSTR szField, VARIANT vValue)
{
// BUGBUG:: Coppied from Docfind2, can combine and simplify
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
HRESULT hr;
VARIANT vConvertedValue;
int iField;
LPTSTR pszValue = NULL;
typedef enum
{
CNFFUFE_SearchFor = 0,
CNFFUFE_LookIn,
} CNFFUFE;
static const CDFFUF s_cdffuf[] = // Warning: index of fields is used below in case...
{
{L"SearchFor", VT_BSTR, CNFFUFE_SearchFor},
{L"LookIn", VT_BSTR, CNFFUFE_LookIn},
{NULL, VT_EMPTY, 0}
};
hr = E_FAIL;
if ((iField = CDFFilter_UpdateFieldChangeType(szField, vValue, s_cdffuf, &vConvertedValue, &pszValue)) < 0)
return E_FAIL;
switch (iField)
{
case CNFFUFE_SearchFor:
StrNCpy(this->szUserInputCompName, pszValue, ARRAYSIZE(this->szUserInputCompName));
break;
case CNFFUFE_LookIn:
break;
}
VariantClear(&vConvertedValue);
if (pszValue)
LocalFree(pszValue);
return S_OK;
}
HRESULT CNetFilter_ResetFieldsToDefaults(IDocFindFileFilter *pnetf)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
this->szUserInputCompName[0] = TEXT('\0');
return S_OK;
}
STDMETHODIMP CNETFilter_DeclareFSNotifyInterest(IDocFindFileFilter *pnetf, HWND hwndDlg, UINT uMsg)
{
CNETFilter *this = IToClass(CNETFilter, dfff, pnetf);
SHChangeNotifyEntry fsne;
fsne.fRecursive = TRUE;
fsne.pidl = this ->pidlStart;
if (fsne.pidl)
{
SHChangeNotifyRegister(hwndDlg, SHCNRF_NewDelivery | SHCNRF_ShellLevel, SHCNE_DISKEVENTS, uMsg, 1, &fsne);
}
return NOERROR;
}
// Now starting the code for the name and location page
// Process the WM_SIZE of the details page
void DocFind_CCOMPFNameLocOnSize(HWND hwndDlg, UINT state, int cx, int cy)
{
RECT rc;
int cxMargin;
if (state == SIZE_MINIMIZED)
return; // don't bother when we are minimized...
// Get the location of first static to calculate margin
GetWindowRect(GetDlgItem(hwndDlg, IDD_STATIC), &rc);
MapWindowPoints(HWND_DESKTOP, hwndDlg, (POINT *)&rc, 2);
cxMargin = rc.left;
cx -= cxMargin;
DocFind_SizeControl(hwndDlg, IDD_FILESPEC, cx, TRUE);
}
// Helper to helper to add an item to the combobox.
HRESULT _GetDisplayName(IShellFolder *psfGP, LPCITEMIDLIST pidl, LPTSTR pszRet, UINT cchMax)
{
LPITEMIDLIST pidlParent = ILClone(pidl);
HRESULT hres;
VDATEINPUTBUF(pszRet, TCHAR, cchMax);
if (pidlParent)
{
IShellFolder *psfParent;
ILRemoveLastID(pidlParent);
hres = SHBindToObject(psfGP, &IID_IShellFolder, pidlParent, &psfParent);
if (SUCCEEDED(hres))
{
STRRET str;
pidl = ILFindLastID(pidl);
hres = psfParent->lpVtbl->GetDisplayNameOf(psfParent, pidl, SHGDN_NORMAL, &str);
if (SUCCEEDED(hres))
hres = StrRetToBuf(&str, pidl, pszRet, cchMax);
psfParent->lpVtbl->Release(psfParent);
}
ILFree(pidlParent);
}
else
{
hres = E_OUTOFMEMORY;
}
return hres;
}
int DocFind_LocCBAddItem(HWND hwndCtl, LPCITEMIDLIST pidlAbs,
int iIndex, int iIndent, int iImage, LPTSTR lpszText)
{
COMBOBOXEXITEM cei;
cei.mask = CBEIF_TEXT|CBEIF_IMAGE|CBEIF_SELECTEDIMAGE
|CBEIF_LPARAM|CBEIF_INDENT;
cei.pszText = lpszText;
cei.lParam = (LPARAM)pidlAbs;
cei.iImage = iImage;
cei.iSelectedImage = iImage;
cei.iItem = iIndex;
cei.iIndent = iIndent;
return (int) SendMessage(hwndCtl, CBEM_INSERTITEM, 0, (LPARAM)&cei);
}
int DocFind_LocCBAddPidl(HWND hwndCtl, IShellFolder *psf,
LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidl, LPITEMIDLIST *ppidlAbs,
BOOL fFullName, UINT iIndent)
{
TCHAR szPath[MAX_PATH];
int iItem = -1;
int iImage;
LPITEMIDLIST pidlAbs;
pidlAbs = ILCombine(pidlParent, pidl);
if (!pidlAbs)
return(-1);
if (fFullName)
{
if (!SHGetPathFromIDList(pidlAbs, szPath))
{
ILFree(pidlAbs);
return(-1);
}
}
else if (FAILED(_GetDisplayName(psf, pidl, szPath, ARRAYSIZE(szPath))))
{
ILFree(pidlAbs);
return(-1);
}
iImage = SHMapPIDLToSystemImageListIndex(psf, pidl, NULL);
iItem = DocFind_LocCBAddItem(hwndCtl, pidlAbs,
-1, // At the end...
iIndent, iImage, szPath);
if (ppidlAbs)
*ppidlAbs = pidlAbs;
return(iItem);
}
// Helper function to see if an Pidl is aready in the list...
int DocFind_LocCBFindPidl(HWND hwnd, LPITEMIDLIST pidl)
{
int i;
LPITEMIDLIST pidlT;
for (i = (int) SendMessage(hwnd, CB_GETCOUNT, 0, 0); i >= 0; i--)
{
pidlT = (LPITEMIDLIST)SendMessage(hwnd, CB_GETITEMDATA, i, 0);
if ((pidlT != NULL) && (pidlT != (LPITEMIDLIST)CB_ERR) &&
ILIsEqual(pidl, pidlT))
break;
}
return(i);
}
// Initialize the Name and loacation page
void DocFind_CCOMPFNameLocInit(LPDOCFINDPROPSHEETPAGE pdfpsp)
{
CNETFilter *pdff = pdfpsp->pdff;
TCHAR szPath[MAX_PATH];
LPITEMIDLIST pidlWindows;
// We want to set the default search drive to the windows drive.
// I am going to be a bit slimmy, but...
GetWindowsDirectory(szPath, ARRAYSIZE(szPath));
if (szPath[1] == TEXT(':'))
szPath[3] = TEXT('\0');
pidlWindows = ILCreateFromPath(szPath);
if ((pdfpsp->dwState & DFPAGE_INIT) == 0)
{
pdff->hMRUSpecs = DocFind_UpdateMRUItem(NULL, pdfpsp->hwndDlg, IDD_FILESPEC,
s_szCompSpecMRU, pdff->szUserInputCompName, szNULL);
// Update our state to let us know that we have already initialized...
pdfpsp->dwState |= DFPAGE_INIT;
}
ILFree(pidlWindows);
}
// Validate the page to make sure that the data is valid. If it is not
// we need to display a message to the user and also set the focus to
// the invalid field.
void DocFind_CCOMPFNameLocValidatePage(LPDOCFINDPROPSHEETPAGE pdfpsp)
{
// No validation is needed here (At least not now).
}
// Apply any changes that happened in the name loc page to the filter
void DocFind_CCOMPFNameLocApply(LPDOCFINDPROPSHEETPAGE pdfpsp)
{
CNETFilter *pdff = pdfpsp->pdff;
GetDlgItemText(pdfpsp->hwndDlg, IDD_FILESPEC, pdff->szUserInputCompName,
ARRAYSIZE(pdff->szUserInputCompName));
DocFind_UpdateMRUItem(pdff->hMRUSpecs, pdfpsp->hwndDlg, IDD_FILESPEC,
s_szCompSpecMRU, pdff->szUserInputCompName, NULL);
}
// DocFind_OnCommand - Process the WM_COMMAND messages
void DocFind_CCOMPFNameLocOnCommand(HWND hwndDlg, UINT id, HWND hwndCtl, UINT code)
{
}
// This function is the dialog (or property sheet page) for the name and
// location page.
const static TCHAR szHelpFile[] = TEXT("network.hlp");
const static DWORD aGeneralHelpIds[] = { // Context Help IDs
IDD_STATIC, IDH_FINDCOMP_NAME,
IDD_FILESPEC, IDH_FINDCOMP_NAME,
0, 0
};
BOOL_PTR CALLBACK DocFind_CCOMPFNameLocDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPDOCFINDPROPSHEETPAGE pdfpsp = (LPDOCFINDPROPSHEETPAGE)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (msg) {
HANDLE_MSG(hwndDlg, WM_COMMAND, DocFind_CCOMPFNameLocOnCommand);
HANDLE_MSG(hwndDlg, WM_SIZE, DocFind_CCOMPFNameLocOnSize);
case WM_INITDIALOG:
SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
pdfpsp = (LPDOCFINDPROPSHEETPAGE)lParam;
pdfpsp->hwndDlg = hwndDlg;
break;
case WM_NCDESTROY:
LocalFree(pdfpsp);
SetWindowLongPtr(hwndDlg, DWLP_USER, 0);
return FALSE; // We MUST return FALSE to avoid mem-leak
case DFM_ENABLECHANGES:
EnableWindow(GetDlgItem(hwndDlg, IDD_FILESPEC), (BOOL)wParam);
break;
case WM_HELP:
WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle, szHelpFile, HELP_WM_HELP,
(ULONG_PTR) (LPTSTR) aGeneralHelpIds);
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, szHelpFile, HELP_CONTEXTMENU,
(ULONG_PTR) (LPTSTR) aGeneralHelpIds);
break;
case WM_NOTIFY:
switch (((NMHDR *)lParam)->code) {
case PSN_KILLACTIVE:
DocFind_CCOMPFNameLocValidatePage(pdfpsp);
break;
case PSN_SETACTIVE:
DocFind_CCOMPFNameLocInit(pdfpsp);
break;
case PSN_APPLY:
if ((pdfpsp->dwState & DFPAGE_INIT) != 0)
DocFind_CCOMPFNameLocApply(pdfpsp);
break;
case PSN_RESET:
if ((pdfpsp->dwState & DFPAGE_INIT) != 0)
{
// Null the filespec
SetDlgItemText(hwndDlg, IDD_FILESPEC, c_szNULL);
}
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
// CNETFEnum: class definition
typedef struct // Doc find Container
{
IDFEnum dfenum;
UINT cRef;
IShellFolder *psf; // Pointer to shell folder
// Stuff to use in the search
DWORD grfFlags; // Flags that control things like recursion
// filter info...
LPTSTR pszDisplayText; // Place to write feadback text into
CNETFilter * pnetf; // Pointer to the net filter...
// enumeration state
IShellFolder * psfEnum; // Pointer to shell folder for the object.
LPENUMIDLIST penum; // Enumerator in use.
LPITEMIDLIST pidl; // The idlist of the currently processing
LPITEMIDLIST pidlStart; // Pointer to the starting point.
int iFolder; // Which folder are we adding items for?
BOOL fAddedSubDirs;
BOOL fObjReturnedInDir; // Has an object been returned in this dir?
BOOL fFindUNC; // Find UNC.
int iPassCnt; // Used to control when to reiterat...
} CNETFEnum;
// CNETFEnum : member prototype - Docfind Folder implementation
STDMETHODIMP CNETFEnum_QueryInterface(IDFEnum * pdfenum, REFIID riid, LPVOID FAR* ppvObj);
STDMETHODIMP_(ULONG) CNETFEnum_AddRef(IDFEnum * pdfenum);
STDMETHODIMP_(ULONG) CNETFEnum_Release(IDFEnum * pdfenum);
STDMETHODIMP CNETFEnum_Next(IDFEnum * pdfenum, LPITEMIDLIST *ppidl,
int *pcObjectSearched, int *pcFoldersSearched, volatile BOOL *pfContinue, int *pState, HWND hwnd);
STDMETHODIMP CDefDFEnum_Skip(IDFEnum * pdfenum, int celt);
STDMETHODIMP CDefDFEnum_Reset(IDFEnum * pdfenum);
STDMETHODIMP CDefDFEnum_StopSearch(IDFEnum * pdfenum);
STDMETHODIMP_(BOOL) CDefDFEnum_FQueryIsAsync(IDFEnum * pdfenum);
STDMETHODIMP CDefDFEnum_GetAsyncCount(IDFEnum * pdfenum, DBCOUNTITEM *pdwTotalAsync, int *pnPercentComplete, BOOL *pfQueryDone);
STDMETHODIMP CDefDFEnum_GetItemIDList(IDFEnum * pdfenum, UINT iItem, LPITEMIDLIST *ppidl);
STDMETHODIMP CDefDFEnum_GetExtendedDetailsOf(IDFEnum * pdfenum, LPCITEMIDLIST pidl, UINT iCol, LPSHELLDETAILS pdi);
STDMETHODIMP CDefDFEnum_GetExtendedDetailsULong(IDFEnum *pdfenum, LPCITEMIDLIST pidl, UINT iCol, ULONG *pul);
STDMETHODIMP CDefDFEnum_GetItemID(IDFEnum * pdfenum, UINT iItem, DWORD *puWorkID);
STDMETHODIMP CDefDFEnum_SortOnColumn(IDFEnum * pdfenum, UINT iCOl, BOOL fAscending);
// CNETFEnum : Vtable
IDFEnumVtbl c_CCOMPFFIterVtbl =
{
CNETFEnum_QueryInterface, CNETFEnum_AddRef, CNETFEnum_Release,
CNETFEnum_Next,
CDefDFEnum_Skip,
CDefDFEnum_Reset,
CDefDFEnum_StopSearch,
CDefDFEnum_FQueryIsAsync,
CDefDFEnum_GetAsyncCount,
CDefDFEnum_GetItemIDList,
CDefDFEnum_GetExtendedDetailsOf,
CDefDFEnum_GetExtendedDetailsULong,
CDefDFEnum_GetItemID,
CDefDFEnum_SortOnColumn
};
// CNETFEnum::QueryInterface
STDMETHODIMP CNETFEnum_QueryInterface(IDFEnum * pdfenum, REFIID riid, LPVOID FAR* ppvObj)
{
return E_NOTIMPL;
}
// IDFEnum::AddRef
STDMETHODIMP_(ULONG) CNETFEnum_AddRef(IDFEnum * pdfenum)
{
CNETFEnum *this = IToClass(CNETFEnum, dfenum, pdfenum);
this->cRef++;
return this->cRef;
}
// CNETFilter_EnumObjects - Get The real recursive filtered enumerator...
STDMETHODIMP CNETFilter_EnumObjects(IDocFindFileFilter * pdfff,
IShellFolder *psf, LPITEMIDLIST pidlStart,
DWORD grfFlags, int iColSort,
TCHAR szDisplayText[MAX_PATH],
IRowsetWatchNotify *prsn,
IDFEnum **ppdfenum)
{
CNETFilter *pnetf = (CNETFilter *)pdfff;
CNETFEnum *pdfenum;
#ifdef USE_DS_TO_FIND
// try searching the DS if we can
HRESULT hres = CNetFindInDS_CreateInstance(pnetf->szUserInputCompName, psf, ppdfenum);
if ( FAILED(hres) || (hres == S_OK) )
return hres;
#endif
// We need to construct the iterator
pdfenum = LocalAlloc(LPTR, SIZEOF(CNETFEnum));
*ppdfenum = NULL;
if (pdfenum == NULL)
return (E_OUTOFMEMORY);
// Now initialize the data structures.
pdfenum->dfenum.lpVtbl = &c_CCOMPFFIterVtbl;
pdfenum->cRef = 1;
pdfenum->psf = psf;
pdfenum->pszDisplayText = szDisplayText;
pdfenum->grfFlags = grfFlags;
pdfenum->pnetf = pnetf;
if (pnetf->pidlStart)
pdfenum->pidlStart = ILClone(pnetf->pidlStart);
else
GetDomainWorkgroupIDList(&pdfenum->pidlStart);
pdfenum->iPassCnt = 0;
// See if this is a UNC Search
if (pdfenum->pidlStart)
{
if (pnetf->pszCompName && (pnetf->pszCompName[0] == TEXT('\\')))
pdfenum->fFindUNC = TRUE;
// Save away the filter pointer
pnetf->dfff.lpVtbl->AddRef(pdfff);
// The rest of the fields should be zero/NULL
#ifdef NET_TIMINGS
// Reset Counters
NTF_cNoPEnum = NTF_dtNoPEnum = 0;
NTF_cNextItem = NTF_dtNextItem = 0;
#endif
*ppdfenum = &pdfenum->dfenum; // Return the appropriate value;
return NOERROR;
}
else
{
LocalFree((HLOCAL)pdfenum);
return (E_OUTOFMEMORY);
}
}
// CNETFEnum::Release
STDMETHODIMP_(ULONG) CNETFEnum_Release(IDFEnum * pdfenum)
{
CNETFEnum *this = IToClass(CNETFEnum, dfenum, pdfenum);
this->cRef--;
if (this->cRef > 0)
{
return this->cRef;
}
// Release any open enumerator and open IShell folder we may have.
if (this->psfEnum != NULL)
this->psfEnum->lpVtbl->Release(this->psfEnum);
if (this->penum != NULL)
this->penum->lpVtbl->Release(this->penum);
// Release our use of the filter
if (this->pnetf)
this->pnetf->dfff.lpVtbl->Release(&this->pnetf->dfff);
if (this->pidlStart)
ILFree(this->pidlStart);
if (this->pidl)
ILFree(this->pidl);
LocalFree((HLOCAL)this);
#ifdef NET_TIMINGS
// Output some timings.
if (!this->fFindUNC)
{
DebugMsg(DM_TRACE, TEXT("CNETFEnum:: Start Enums(%d), Time(%d), Per item(%d)"),
NTF_cNoPEnum, NTF_dtNoPEnum, NTF_cNoPEnum ? NTF_dtNoPEnum/NTF_cNoPEnum : 0);
DebugMsg(DM_TRACE, TEXT("CNETFEnum:: Count Next(%d), Time(%d), Per item(%d)"),
NTF_cNextItem, NTF_dtNextItem, NTF_cNextItem ? NTF_dtNextItem/NTF_cNextItem : 0);
}
#endif
return(0);
}
// _UNCExtractServer
// Helper function to chop off all of an UNC path except the
// \\server portion
void _UNCExtractServer(LPTSTR pszUNC)
{
for (pszUNC += 2; *pszUNC; pszUNC = CharNext(pszUNC))
{
if (*pszUNC == TEXT('\\'))
{
// found something after server name, so get rid of it
*pszUNC = TEXT('\0');
break;
}
}
}
// _FindCompByUNCName -
// Helper function to the next function to help process find computer
// on returning computers by UNC names...
STDMETHODIMP _FindCompByUNCName(CNETFEnum * this, LPITEMIDLIST *ppidl,
int *piState)
{
LPTSTR pszT;
LPITEMIDLIST pidl;
// Two cases, There is a UNC name entered. If so we need to process
// this by extracting everythign off after the server name...
pszT = this->pnetf->pszCompName;
if ((pszT==NULL) || (*pszT == TEXT('\0')))
{
*piState = GNF_DONE;
return NOERROR;
}
if (PathIsUNC(pszT))
{
_UNCExtractServer(pszT);
}
else
{
// They did not enter a unc name, but lets try to convert to
// unc name
LPTSTR pszTmp = LocalReAlloc(pszT,(3 + lstrlen(pszT))*SIZEOF(TCHAR),
LMEM_MOVEABLE );
if (pszTmp)
{
pszT = pszTmp;
this->pnetf->pszCompName = pszT;
*pszT++ = TEXT('\\');
*pszT++ = TEXT('\\');
lstrcpy(pszT, this->pnetf->szUserInputCompName);
_UNCExtractServer(pszT);
}
else
return E_OUTOFMEMORY;
}
// Now parse the displayname - Argh we convert to Unicode, such
// that we can uncovert at the other side.
pidl = ILCreateFromPath(this->pnetf->pszCompName);
if (pidl != NULL)
{
// clone the child to transform into a DocFind pidl
LPITEMIDLIST pidlChild = ILClone(ILFindLastID(pidl));
if (pidlChild)
{
IDocFindFolder *pdfFolder;
ILRemoveLastID(pidl); // Remove the last id (computer)
if (SUCCEEDED(this->psf->lpVtbl->QueryInterface(this->psf, &IID_IDocFindFolder, (void **)&pdfFolder)))
{
pdfFolder->lpVtbl->AddFolderToFolderList(pdfFolder, pidl, FALSE, &this->iFolder);
pdfFolder->lpVtbl->Release(pdfFolder);
}
*ppidl = DocFind_AppendIFolder(pidlChild, this->iFolder);
*piState = GNF_MATCH;
}
ILFree(pidl);
}
else
*piState = GNF_DONE;
// And Return;
return NOERROR;
}
// CNETFEnum::Next Recursive Iterator that is very special to the docfind.
// It will walk each directory, breath first, it will call the
// defined callback function to determine if it is an
// interesting file to us. It will also return additional
// information, such as: The number of folders and files
// searched, so we can give results back to the user. It
// will return control to the caller whenever:
// a) Finds a match.
// b) runs out of things to search.
// c) Starts searching in another directory
// d) when the callback says to...
STDMETHODIMP CNETFEnum_Next(IDFEnum * pdfenum, LPITEMIDLIST *ppidl,
int *pcObjectSearched, int *pcFoldersSearched,
volatile BOOL *pfContinue, int *piState, HWND hwnd)
{
// If we aren't enumerating a directory, then get the next directory
// name from the dir list, and begin enumerating its contents...
CNETFEnum * this = IToClass(CNETFEnum, dfenum, pdfenum);
BOOL fContinue = TRUE;
STRRET strret;
IShellFolder *psfDesktop;
SHGetDesktopFolder(&psfDesktop);
// Special case to find UNC Names quickly. It will ignore all other
// things.
if (this->fFindUNC)
{
// If not the first time through return that we are done!
if (this->iPassCnt)
{
*piState = GNF_DONE;
return NOERROR;
}
this->iPassCnt = 1;
return _FindCompByUNCName(this, ppidl, piState);
}
do
{
if (this->penum)
{
LPITEMIDLIST pidl;
#ifdef NET_TIMINGS
NTF_dtTime = GetTickCount();
#endif
NextIDL(this->penum, &pidl);
#ifdef NET_TIMINGS
NTF_cNextItem++;
NTF_dtNextItem += GetTickCount() - NTF_dtTime;
#endif
if (pidl)
{
// Now see if this is someone we might want to return.
// Our Match function take esither find data or idlist...
// for networks we work off of the idlist,
fContinue = FALSE; // We can exit the loop;
(*pcObjectSearched)++;
if (this->pnetf->dfff.lpVtbl->FDoesItemMatchFilter(&this->pnetf->dfff,
this->pszDisplayText, NULL, this->psfEnum, pidl) != 0)
{
*piState = GNF_MATCH;
// Now see if we have to add this folder to our
// list.
if (!this->fObjReturnedInDir)
{
IDocFindFolder *pdfFolder;
this->fObjReturnedInDir = TRUE;
if (SUCCEEDED(this->psf->lpVtbl->QueryInterface(this->psf, &IID_IDocFindFolder, (void **)&pdfFolder)))
{
pdfFolder->lpVtbl->AddFolderToFolderList(pdfFolder, this->pidl, FALSE, &this->iFolder);
pdfFolder->lpVtbl->Release(pdfFolder);
}
}
// Now lets muck up the IDList to put ur index number
// onto the end of the idlist.
pidl = DocFind_AppendIFolder(pidl, this->iFolder);
if (pidl)
{
*ppidl = pidl;
if ((this->iPassCnt == 1) && this->pnetf->pszCompName && *this->pnetf->pszCompName)
{
// See if this is an exact match of the name
// we are looking for. If it is we set pass=2
// as to not add the item twice.
STRRET str;
TCHAR szName[MAX_PATH];
if (SUCCEEDED(this->psf->lpVtbl->GetDisplayNameOf(this->psf, pidl, SHGDN_NORMAL, &str)) &&
SUCCEEDED(StrRetToBuf(&str, pidl, szName, ARRAYSIZE(szName))) &&
(0 == lstrcmpi(szName, this->pnetf->szUserInputCompName)))
{
this->iPassCnt = 2;
}
}
break;
}
}
else
{
// Release the IDList that did not match
ILFree(pidl);
*piState = GNF_NOMATCH;
}
}
else
{
// Close out the shell folder and the enumeration function.
this->penum->lpVtbl->Release(this->penum);
this->penum = NULL;
this->psfEnum->lpVtbl->Release(this->psfEnum);
this->psfEnum = NULL;
}
}
if (!this->penum)
{
switch (this->iPassCnt)
{
case 1:
// We went through all of the items see if there is
// an exact match...
this->iPassCnt = 2;
return _FindCompByUNCName(this, ppidl, piState);
case 2:
// We looped through everything so return done!
*piState = GNF_DONE;
return NOERROR;
case 0:
// This is the main pass through here...
// Need to clone the idlist
this->pidl = ILClone(this->pidlStart);
if (this->pidl == NULL)
{
*piState = GNF_ERROR;
return (E_OUTOFMEMORY);
}
this->iPassCnt = 1;
// We will do the first on in our own thread.
if (SUCCEEDED(psfDesktop->lpVtbl->BindToObject(psfDesktop,
this->pidl, NULL, &IID_IShellFolder,
&this->psfEnum)))
{
// BUGBUG:: Need more flags to control this!
if (FAILED(this->psfEnum->lpVtbl->EnumObjects(this->psfEnum,
(HWND)NULL, // BUGBUG: hwndOwner
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &this->penum)))
{
// Failed to get iterator so release folder.
this->psfEnum->lpVtbl->Release(this->psfEnum);
this->psfEnum = NULL;
this->penum = NULL;
}
}
break;
}
// We are now read to get the IShellfolder for this guy!
(*pcFoldersSearched)++;
// Need to put something here to show what is being searched!
strret.uType = STRRET_OFFSET;
if (SUCCEEDED(psfDesktop->lpVtbl->GetDisplayNameOf(psfDesktop,
this->pidl, SHGDN_NORMAL, &strret)))
{
StrRetToBuf(&strret, this->pidl, this->pszDisplayText, MAX_PATH);
}
#ifdef NET_TIMINGS
NTF_cNoPEnum++;
#endif
}
} while (fContinue && *pfContinue);
return NOERROR;
}
// CDefDFEnum::Skip Recursive Iterator that is very special to the docfind.
STDMETHODIMP CDefDFEnum_Skip(IDFEnum * pdfenum, int celt)
{
return (E_NOTIMPL);
}
// CDefDFEnum::Reset
STDMETHODIMP CDefDFEnum_Reset(IDFEnum * pdfenum)
{
return (E_NOTIMPL);
}
// CDefDFEnum::StopSearch
STDMETHODIMP CDefDFEnum_StopSearch(IDFEnum * pdfenum)
{
return (E_NOTIMPL);
}
// CDefDFEnum::GetAsyncCount
STDMETHODIMP_(BOOL) CDefDFEnum_FQueryIsAsync(IDFEnum * pdfenum)
{
return FALSE;
}
// CDefDFEnum::GetAsyncCount
STDMETHODIMP CDefDFEnum_GetAsyncCount(IDFEnum * pdfenum, DBCOUNTITEM *pdwTotalAsync,
int *pnPercentComplete, BOOL *pfQueryDone)
{
return (E_NOTIMPL);
}
// CDefDFEnum::GetItemIDList
STDMETHODIMP CDefDFEnum_GetItemIDList(IDFEnum * pdfenum, UINT iItem, LPITEMIDLIST *ppidl)
{
return (E_NOTIMPL);
}
// CDefDFEnum::GetExtendedDetailsOf
STDMETHODIMP CDefDFEnum_GetExtendedDetailsOf(IDFEnum * pdfenum, LPCITEMIDLIST pidl, UINT iCol, LPSHELLDETAILS pdi)
{
return (E_NOTIMPL);
}
STDMETHODIMP CDefDFEnum_GetExtendedDetailsULong(IDFEnum *pdfenum, LPCITEMIDLIST pidl, UINT iCol, ULONG *pul)
{
return (E_NOTIMPL);
}
// CDefDFEnum::GetItemID
STDMETHODIMP CDefDFEnum_GetItemID(IDFEnum * pdfenum, UINT iItem, DWORD *puWorkID)
{
*puWorkID = (UINT)-1;
return (E_NOTIMPL);
}
// CDefDFEnum::SortOnColumn
STDMETHODIMP CDefDFEnum_SortOnColumn(IDFEnum * pdfenum, UINT iCOl, BOOL fAscending)
{
return E_NOTIMPL;
}