main.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 29k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*----------------------------------------------------------------------------
  2. / Title;
  3. /   main.cpp
  4. /
  5. / Authors;
  6. /   David De Vorchik (daviddv)
  7. /
  8. / Notes;
  9. /   Query the DS, put the results into a list view.
  10. /   This code is pretty lax with Trace and error reporting.
  11. /----------------------------------------------------------------------------*/
  12. #include "windows.h"
  13. #include "windowsx.h"
  14. #include "commctrl.h"
  15. #include "resource.h"
  16. #include "shlobj.h"
  17. #include "shlobjp.h"
  18. #include "shlwapi.h"
  19. //
  20. // Private headers from the shell/dsui projects
  21. //
  22. #include "comctrlp.h"
  23. #include "shellapi.h"
  24. #include "shsemip.h"
  25. #include "shlwapip.h"
  26. #include "common.h"
  27. #pragma hdrstop
  28. #define INITGUID
  29. #include "initguid.h"
  30. #include "cmnquery.h"
  31. #include "cmnquryp.h"
  32. #include "dsquery.h"
  33. #include "dsshell.h"
  34. /*-----------------------------------------------------------------------------
  35. / Globals and stuff
  36. /----------------------------------------------------------------------------*/
  37. struct
  38. {
  39.     INT idsForm;
  40.     CLSID const * pFormCLSID;
  41. }
  42. forms[] =
  43. {
  44.     IDS_FORMUSERS,            &CLSID_DsFindPeople,
  45.     IDS_FORMCOMPUTERS,        &CLSID_DsFindComputer,
  46.     IDS_FORMPRINT,            &CLSID_DsFindPrinter,
  47.     IDS_FORMFILEFOLDERS,      &CLSID_DsFindVolume,
  48.     IDS_FORMDSFOLDERS,        &CLSID_DsFindContainer,
  49.     IDS_FORMOBJECTS,          &CLSID_DsFindObjects,
  50.     IDS_FORMPWELL,            &CLSID_DsFindAdvanced,
  51.     IDS_FORMDC,               &CLSID_DsFindDomainController,
  52. };
  53. #define INI_FILENAME      TEXT("query.ini")
  54. #define DEFAULT_SCOPE     TEXT("LDAP://ntdev")
  55. #define DEFAULT_SAVELOCN  TEXT("c:\temp")
  56. HINSTANCE g_hInstance = NULL;
  57. UINT g_cfDsObjectNames = 0;
  58. UINT g_cfDsQueryParams = 0;
  59. BOOL CALLBACK Query_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  60. void Query_OnInitDialog(HWND hDlg, LPTSTR pDefaultScope);
  61. void Query_OnDoSearch(HWND hDlg);
  62. void Query_BrowseForScope(HWND hDlg);
  63. void Query_BrowseForSaveLocation(HWND hDlg);
  64. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
  65. struct
  66. {
  67.     UINT ids;
  68.     int  fmt;
  69.     int  cx;
  70. }
  71. columnsResults[] =
  72. {
  73.     IDS_OBJECTNAME,     LVCFMT_LEFT, 192,
  74.     IDS_CLASS,          LVCFMT_LEFT, 64,
  75.     IDS_FLAGS,          LVCFMT_LEFT, 64,
  76.     IDS_PROVIDERFLAGS,  LVCFMT_LEFT, 96,
  77. };
  78. struct
  79. {
  80.     UINT ids;
  81.     int  fmt;
  82.     int  cx;
  83. }
  84. columnsPersistInfo[] =
  85. {
  86.     IDS_SECTION,        LVCFMT_LEFT, 128,
  87.     IDS_TAG,            LVCFMT_LEFT, 128,
  88.     IDS_DATA,           LVCFMT_LEFT, 128,
  89. };
  90. //
  91. // Example persisting iface for poulating the list view
  92. //
  93. class CPersistQuery : public IPersistQuery
  94. {
  95.     private:
  96.         ULONG m_cRefCount;
  97.         HWND m_hwndView;
  98.     public:
  99.         CPersistQuery(HWND hwndView);
  100.         // IUnknown
  101.         STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObject);
  102.         STDMETHOD_(ULONG, AddRef)();
  103.         STDMETHOD_(ULONG, Release)();
  104.         // IPersist
  105.         STDMETHOD(GetClassID)(THIS_ CLSID* pClassID);
  106.         // IPersistQuery
  107.         STDMETHOD(WriteString)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, LPCTSTR pValue);
  108.         STDMETHOD(ReadString)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, LPTSTR pBuffer, INT cchBuffer);
  109.         STDMETHOD(WriteInt)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, INT value);
  110.         STDMETHOD(ReadInt)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, LPINT pValue);
  111.         STDMETHOD(WriteStruct)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, LPVOID pStruct, DWORD cbStruct);
  112.         STDMETHOD(ReadStruct)(THIS_ LPCTSTR pSection, LPCTSTR pValueName, LPVOID pStruct, DWORD cbStruct);
  113.         STDMETHOD(Clear)(THIS);
  114. };
  115. /*-----------------------------------------------------------------------------
  116. / Query_DlgProc
  117. / -------------
  118. /   Handle dialog messages for this window.
  119. /
  120. / In:
  121. /   hDlg -> dialog to be initialized
  122. /
  123. / Out:
  124. /   -
  125. /----------------------------------------------------------------------------*/
  126. BOOL CALLBACK Query_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  127. {
  128.     BOOL fResult = FALSE;
  129.     switch ( uMsg )
  130.     {
  131.         case WM_INITDIALOG:
  132.             Query_OnInitDialog(hDlg, (LPTSTR)lParam);
  133.             break;
  134.         case WM_SHOWWINDOW:
  135.         {
  136. #if 0
  137.             if ( wParam )
  138.                 PostMessage(hDlg, WM_COMMAND, IDC_SEARCH, 0);
  139. #endif
  140.             break;
  141.         }
  142.         case WM_COMMAND:
  143.         {
  144.             switch ( LOWORD(wParam) )
  145.             {
  146.                 case IDOK:
  147.                 case IDCANCEL:
  148.                     EndDialog(hDlg, LOWORD(wParam));
  149.                     break;
  150.                 case IDC_SEARCH:
  151.                     Query_OnDoSearch(hDlg);
  152.                     break;
  153.                 case IDC_SCOPEBROWSE:
  154.                     Query_BrowseForScope(hDlg);
  155.                     break;                                       
  156.                 case IDC_SAVEBROWSE:
  157.                     Query_BrowseForSaveLocation(hDlg);
  158.                     break;                                       
  159.                 case IDC_DEFAULTFORM:
  160.                 {
  161.                     EnableWindow(GetDlgItem(hDlg, IDC_FORMLIST), 
  162.                                     IsDlgButtonChecked(hDlg, IDC_DEFAULTFORM)== BST_CHECKED);
  163.                     break;
  164.                 }
  165.                 case IDC_DEFAULTSCOPE:
  166.                 {
  167.                     EnableWindow(GetDlgItem(hDlg, IDC_SCOPELOCN), 
  168.                                     IsDlgButtonChecked(hDlg, IDC_DEFAULTSCOPE)== BST_CHECKED);
  169.                     EnableWindow(GetDlgItem(hDlg, IDC_SCOPEBROWSE), 
  170.                                     IsDlgButtonChecked(hDlg, IDC_DEFAULTSCOPE)== BST_CHECKED);
  171.                     break;
  172.                 }
  173.                 case IDC_SAVEWHERE:
  174.                 {
  175.                     EnableWindow(GetDlgItem(hDlg, IDC_SAVELOCN), 
  176.                                     IsDlgButtonChecked(hDlg, IDC_SAVEWHERE)== BST_CHECKED);
  177.                     EnableWindow(GetDlgItem(hDlg, IDC_SAVEBROWSE), 
  178.                                     IsDlgButtonChecked(hDlg, IDC_SAVEWHERE)== BST_CHECKED);         
  179.                     break;
  180.                 }
  181.                 
  182.                 case IDC_SAVEONCLOSE:
  183.                 {
  184.                     EnableWindow(GetDlgItem(hDlg, IDC_PERSISTDATA), 
  185.                                     IsDlgButtonChecked(hDlg, IDC_SAVEONCLOSE)== BST_CHECKED);
  186.                     break;
  187.                 }
  188.                 case IDC_GETRESULTS:
  189.                 {
  190.                     EnableWindow(GetDlgItem(hDlg, IDC_RESULTS), 
  191.                                     IsDlgButtonChecked(hDlg, IDC_GETRESULTS)== BST_CHECKED);         
  192.                     break;
  193.                 }
  194.                 default:
  195.                     break;
  196.             }
  197.         }
  198.     }
  199.     return fResult;
  200. }
  201. /*-----------------------------------------------------------------------------
  202. / Query_OnInitDialog
  203. / ------------------
  204. /   Initialize the dialog (the result viewer).
  205. /
  206. / In:
  207. /   hDlg -> dialog to be initialized
  208. /   pDefaultScope -> default scope to use when browsing
  209. /
  210. / Out:
  211. /   -
  212. /----------------------------------------------------------------------------*/
  213. void Query_OnInitDialog(HWND hDlg, LPTSTR pDefaultScope)
  214. {
  215.     TCHAR szBuffer[MAX_PATH];
  216.     LV_COLUMN lvc;
  217.     INT i;
  218.     TCHAR szScopeLocn[MAX_PATH];
  219.     TCHAR szSaveLocn[MAX_PATH];    
  220.     BOOL fSingleSelect = FALSE;
  221.     BOOL fDefaultForm = FALSE;
  222.     BOOL fDefaultScope = FALSE;
  223.     BOOL fNoSave = FALSE;
  224.     BOOL fSaveWhere = FALSE;
  225.     BOOL fShowHidden = FALSE;
  226.     BOOL fRemoveScopes = FALSE;
  227.     BOOL fRemoveForms = FALSE;
  228.     BOOL fIssueOnOpen = FALSE;   
  229.     BOOL fShowOptional = FALSE;
  230.     BOOL fAdminBits = FALSE;
  231.     BOOL fHideSearchPane = FALSE;
  232.     BOOL fPersistOnOK = FALSE;
  233.     BOOL fHideMenus = FALSE;
  234.     BOOL fHideSearchUI = FALSE;
  235.     BOOL fGetResults = TRUE;
  236.     UINT iDefaultForm = ARRAYSIZE(forms);
  237.     
  238.     // Setup the columns within the ListView
  239.     for ( i = 0 ; i < ARRAYSIZE(columnsResults) ; i++ )
  240.     {
  241.         LoadString(g_hInstance, columnsResults[i].ids, szBuffer, ARRAYSIZE(szBuffer));
  242.         lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
  243.         lvc.fmt = columnsResults[i].fmt;
  244.         lvc.cx = columnsResults[i].cx;
  245.         lvc.pszText = szBuffer;
  246.         ListView_InsertColumn(GetDlgItem(hDlg, IDC_RESULTS), i, &lvc);
  247.     }
  248.     ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_RESULTS), LVS_EX_FULLROWSELECT);
  249.     // setup columns in persist window
  250.     for ( i = 0 ; i < ARRAYSIZE(columnsPersistInfo) ; i++ )
  251.     {
  252.         LoadString(g_hInstance, columnsPersistInfo[i].ids, szBuffer, ARRAYSIZE(szBuffer));
  253.         lvc.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
  254.         lvc.fmt = columnsPersistInfo[i].fmt;
  255.         lvc.cx = columnsPersistInfo[i].cx;
  256.         lvc.pszText = szBuffer;
  257.         ListView_InsertColumn(GetDlgItem(hDlg, IDC_PERSISTDATA), i, &lvc);
  258.     }
  259.     ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_PERSISTDATA), LVS_EX_FULLROWSELECT);
  260.     // Setup forms in the form list
  261.     for ( i = 0 ; i < ARRAYSIZE(forms); i++ )
  262.     {
  263.         LoadString(g_hInstance, forms[i].idsForm, szBuffer, ARRAYSIZE(szBuffer));
  264.         ComboBox_AddString(GetDlgItem(hDlg, IDC_FORMLIST), szBuffer);
  265.     }
  266.     // Load settings from the ini file and prep the dialog box with the settings
  267.     GetPrivateProfileStruct(TEXT("Query"), TEXT("SingleSelect"),   &fSingleSelect,   SIZEOF(fSingleSelect),   INI_FILENAME);
  268.     GetPrivateProfileStruct(TEXT("Query"), TEXT("DefaultScope"),   &fDefaultScope,   SIZEOF(fDefaultScope),   INI_FILENAME);
  269.     GetPrivateProfileStruct(TEXT("Query"), TEXT("NoSave"),         &fNoSave,         SIZEOF(fNoSave),         INI_FILENAME);
  270.     GetPrivateProfileStruct(TEXT("Query"), TEXT("SaveWhere"),      &fSaveWhere,      SIZEOF(fSaveWhere),      INI_FILENAME);
  271.     GetPrivateProfileStruct(TEXT("Query"), TEXT("DefaultForm"),    &iDefaultForm,    SIZEOF(iDefaultForm),    INI_FILENAME);
  272.     GetPrivateProfileStruct(TEXT("Query"), TEXT("ShowHidden"),     &fShowHidden,     SIZEOF(fShowHidden),     INI_FILENAME);
  273.     GetPrivateProfileStruct(TEXT("Query"), TEXT("RemoveScope"),    &fRemoveScopes,   SIZEOF(fRemoveScopes),   INI_FILENAME);
  274.     GetPrivateProfileStruct(TEXT("Query"), TEXT("RemoveForms"),    &fRemoveForms,    SIZEOF(fRemoveForms),    INI_FILENAME);
  275.     GetPrivateProfileStruct(TEXT("Query"), TEXT("IssueOnOpen"),    &fIssueOnOpen,    SIZEOF(fIssueOnOpen),    INI_FILENAME);
  276.     GetPrivateProfileStruct(TEXT("Query"), TEXT("ShowOptional"),   &fShowOptional,   SIZEOF(fShowOptional),   INI_FILENAME);
  277.     GetPrivateProfileStruct(TEXT("Query"), TEXT("AdmimnBits"),     &fAdminBits,      SIZEOF(fAdminBits),      INI_FILENAME);
  278.     GetPrivateProfileStruct(TEXT("Query"), TEXT("HideSearchPane"), &fHideSearchPane, SIZEOF(fHideSearchPane), INI_FILENAME);
  279.     GetPrivateProfileStruct(TEXT("Query"), TEXT("PersistOnOK"),    &fPersistOnOK,    SIZEOF(fPersistOnOK),    INI_FILENAME);
  280.     GetPrivateProfileStruct(TEXT("Query"), TEXT("HideMenus"),      &fHideMenus,      SIZEOF(fHideMenus),      INI_FILENAME);
  281.     GetPrivateProfileStruct(TEXT("Query"), TEXT("AsFilterDlg"),    &fHideSearchUI,   SIZEOF(fHideSearchUI),   INI_FILENAME);
  282.     GetPrivateProfileStruct(TEXT("Query"), TEXT("GetResults"),     &fGetResults,     SIZEOF(fGetResults),     INI_FILENAME);
  283.     GetPrivateProfileString(TEXT("Query"), TEXT("ScopeLocn"), DEFAULT_SCOPE, szScopeLocn, ARRAYSIZE(szScopeLocn), INI_FILENAME);
  284.     GetPrivateProfileString(TEXT("Query"), TEXT("SaveLocn"), DEFAULT_SAVELOCN , szSaveLocn, ARRAYSIZE(szSaveLocn), INI_FILENAME);
  285.     if ( iDefaultForm == ARRAYSIZE(forms) )
  286.         iDefaultForm = 0;
  287.     else
  288.         fDefaultForm = TRUE;
  289.     ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_FORMLIST), iDefaultForm);
  290.     if ( pDefaultScope )
  291.     {
  292.         SetDlgItemText(hDlg, IDC_SCOPELOCN, pDefaultScope);
  293.         fDefaultScope = TRUE;
  294.     }
  295.     else
  296.     {
  297.         SetDlgItemText(hDlg, IDC_SCOPELOCN, szScopeLocn);
  298.     }
  299.     SetDlgItemText(hDlg, IDC_SAVELOCN, szSaveLocn);
  300.     CheckDlgButton(hDlg, IDC_SINGLESELECT,   fSingleSelect   ? BST_CHECKED:BST_UNCHECKED);
  301.     CheckDlgButton(hDlg, IDC_DEFAULTFORM,    fDefaultForm    ? BST_CHECKED:BST_UNCHECKED);
  302.     CheckDlgButton(hDlg, IDC_DEFAULTSCOPE,   fDefaultScope   ? BST_CHECKED:BST_UNCHECKED);
  303.     CheckDlgButton(hDlg, IDC_NOSAVE,         fNoSave         ? BST_CHECKED:BST_UNCHECKED);
  304.     CheckDlgButton(hDlg, IDC_SAVEWHERE,      fSaveWhere      ? BST_CHECKED:BST_UNCHECKED);
  305.     CheckDlgButton(hDlg, IDC_SHOWHIDDEN,     fShowHidden     ? BST_CHECKED:BST_UNCHECKED);
  306.     CheckDlgButton(hDlg, IDC_NOSCOPES,       fRemoveScopes   ? BST_CHECKED:BST_UNCHECKED);
  307.     CheckDlgButton(hDlg, IDC_NOFORMS,        fRemoveForms    ? BST_CHECKED:BST_UNCHECKED);
  308.     CheckDlgButton(hDlg, IDC_ISSUEONOPEN,    fIssueOnOpen    ? BST_CHECKED:BST_UNCHECKED);
  309.     CheckDlgButton(hDlg, IDC_SHOWOPTIONAL,   fShowOptional   ? BST_CHECKED:BST_UNCHECKED);
  310.     CheckDlgButton(hDlg, IDC_ADMINBITS,      fAdminBits      ? BST_CHECKED:BST_UNCHECKED);
  311.     CheckDlgButton(hDlg, IDC_HIDESEARCHPANE, fHideSearchPane ? BST_CHECKED:BST_UNCHECKED);
  312.     CheckDlgButton(hDlg, IDC_SAVEONCLOSE,    fPersistOnOK    ? BST_CHECKED:BST_UNCHECKED);
  313.     CheckDlgButton(hDlg, IDC_HIDEMENUS,      fHideMenus      ? BST_CHECKED:BST_UNCHECKED);
  314.     CheckDlgButton(hDlg, IDC_HIDESEARCHUI,   fHideSearchUI   ? BST_CHECKED:BST_UNCHECKED);
  315.     CheckDlgButton(hDlg, IDC_GETRESULTS,     fGetResults     ? BST_CHECKED:BST_UNCHECKED);
  316.     EnableWindow(GetDlgItem(hDlg, IDC_FORMLIST), fDefaultForm);
  317.     EnableWindow(GetDlgItem(hDlg, IDC_SCOPELOCN), fDefaultScope);
  318.     EnableWindow(GetDlgItem(hDlg, IDC_SCOPEBROWSE), fDefaultScope);
  319.     EnableWindow(GetDlgItem(hDlg, IDC_SAVELOCN), fSaveWhere);
  320.     EnableWindow(GetDlgItem(hDlg, IDC_SAVEBROWSE), fSaveWhere);
  321.     EnableWindow(GetDlgItem(hDlg, IDC_PERSISTDATA), fPersistOnOK);
  322.     EnableWindow(GetDlgItem(hDlg, IDC_RESULTS), fGetResults);
  323. }
  324. /*-----------------------------------------------------------------------------
  325. / Query_OnDoSearch
  326. / ----------------
  327. /   Query the DS and populate the specified list view with results we get back.
  328. /
  329. / In:
  330. /   hDlg -> parent of find dialog
  331. /
  332. / Out:
  333. /   -
  334. /----------------------------------------------------------------------------*/
  335. void Query_OnDoSearch(HWND hDlg)
  336. {
  337.     HRESULT hr;
  338.     FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  339.     STGMEDIUM medium = { TYMED_NULL, NULL, NULL };
  340.     DSQUERYINITPARAMS dqip;
  341.     OPENQUERYWINDOW oqw;
  342.     LPTSTR pObjectName, pClass;
  343.     ICommonQuery* pCommonQuery = NULL;
  344.     IDataObject* pDataObject = NULL;
  345.     HWND hwndResults;
  346.     LV_ITEM lvi;
  347.     UINT i;
  348.     TCHAR szBuffer[MAX_PATH];
  349.     TCHAR szScopeLocn[MAX_PATH];
  350.     TCHAR szSaveLocn[MAX_PATH];    
  351.     BOOL fSingleSelect = FALSE;
  352.     BOOL fDefaultForm = FALSE;
  353.     BOOL fDefaultScope = FALSE;
  354.     BOOL fNoSave = FALSE;
  355.     BOOL fSaveWhere = FALSE;
  356.     BOOL fShowHidden = FALSE;
  357.     BOOL fRemoveScopes = FALSE;
  358.     BOOL fRemoveForms = FALSE;
  359.     BOOL fIssueOnOpen = FALSE;   
  360.     BOOL fShowOptional = FALSE;
  361.     BOOL fAdminBits = FALSE;
  362.     BOOL fHideSearchPane = FALSE;
  363.     BOOL fPersistOnOK = FALSE;
  364.     BOOL fHideMenus = FALSE;
  365.     BOOL fHideSearchUI = FALSE;
  366.     BOOL fGetResults = TRUE;
  367.     UINT iDefaultForm = ARRAYSIZE(forms);
  368.     CPersistQuery* pPersistQuery = NULL;
  369.     // Read the state from the dialog and write them out
  370.     fSingleSelect = IsDlgButtonChecked(hDlg, IDC_SINGLESELECT) == BST_CHECKED;
  371.     fDefaultForm = IsDlgButtonChecked(hDlg, IDC_DEFAULTFORM) == BST_CHECKED;
  372.     fDefaultScope = IsDlgButtonChecked(hDlg, IDC_DEFAULTSCOPE) == BST_CHECKED;
  373.     fNoSave = IsDlgButtonChecked(hDlg, IDC_NOSAVE) == BST_CHECKED;
  374.     fSaveWhere = IsDlgButtonChecked(hDlg, IDC_SAVEWHERE) == BST_CHECKED;
  375.     fShowHidden = IsDlgButtonChecked(hDlg, IDC_SHOWHIDDEN) == BST_CHECKED;
  376.     fRemoveScopes = IsDlgButtonChecked(hDlg, IDC_NOSCOPES) == BST_CHECKED;
  377.     fRemoveForms = IsDlgButtonChecked(hDlg, IDC_NOFORMS) == BST_CHECKED;
  378.     fIssueOnOpen = IsDlgButtonChecked(hDlg, IDC_ISSUEONOPEN) == BST_CHECKED;
  379.     fShowOptional = IsDlgButtonChecked(hDlg, IDC_SHOWOPTIONAL) == BST_CHECKED;
  380.     fAdminBits = IsDlgButtonChecked(hDlg, IDC_ADMINBITS) == BST_CHECKED;
  381.     fHideSearchPane = IsDlgButtonChecked(hDlg, IDC_HIDESEARCHPANE) == BST_CHECKED;
  382.     fPersistOnOK = IsDlgButtonChecked(hDlg, IDC_SAVEONCLOSE) == BST_CHECKED;
  383.     fHideMenus = IsDlgButtonChecked(hDlg, IDC_HIDEMENUS) == BST_CHECKED;
  384.     fHideSearchUI = IsDlgButtonChecked(hDlg, IDC_HIDESEARCHUI) == BST_CHECKED;
  385.     fGetResults = IsDlgButtonChecked(hDlg, IDC_GETRESULTS) == BST_CHECKED;
  386.     GetDlgItemText(hDlg, IDC_SCOPELOCN, szScopeLocn, ARRAYSIZE(szScopeLocn));
  387.     GetDlgItemText(hDlg, IDC_SAVELOCN, szSaveLocn, ARRAYSIZE(szSaveLocn));
  388.     if ( fDefaultForm )
  389.         iDefaultForm = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_FORMLIST));
  390.     WritePrivateProfileStruct(TEXT("Query"), TEXT("SingleSelect"),   &fSingleSelect,   SIZEOF(fSingleSelect),   INI_FILENAME);
  391.     WritePrivateProfileStruct(TEXT("Query"), TEXT("DefaultScope"),   &fDefaultScope,   SIZEOF(fDefaultForm),    INI_FILENAME);
  392.     WritePrivateProfileStruct(TEXT("Query"), TEXT("NoSave"),         &fNoSave,         SIZEOF(fNoSave),         INI_FILENAME);
  393.     WritePrivateProfileStruct(TEXT("Query"), TEXT("SaveWhere"),      &fSaveWhere,      SIZEOF(fSaveWhere),      INI_FILENAME);
  394.     WritePrivateProfileStruct(TEXT("Query"), TEXT("DefaultForm"),    &iDefaultForm,    SIZEOF(iDefaultForm),    INI_FILENAME);
  395.     WritePrivateProfileStruct(TEXT("Query"), TEXT("ShowHidden"),     &fShowHidden,     SIZEOF(fShowHidden),     INI_FILENAME);
  396.     WritePrivateProfileStruct(TEXT("Query"), TEXT("RemoveScope"),    &fRemoveScopes,   SIZEOF(fRemoveScopes),   INI_FILENAME);
  397.     WritePrivateProfileStruct(TEXT("Query"), TEXT("RemoveForms"),    &fRemoveForms,    SIZEOF(fRemoveForms),    INI_FILENAME);
  398.     WritePrivateProfileStruct(TEXT("Query"), TEXT("IssueOnOpen"),    &fIssueOnOpen,    SIZEOF(fIssueOnOpen),    INI_FILENAME);
  399.     WritePrivateProfileStruct(TEXT("Query"), TEXT("ShowOptional"),   &fShowOptional,   SIZEOF(fShowOptional),   INI_FILENAME);
  400.     WritePrivateProfileStruct(TEXT("Query"), TEXT("AdmimnBits"),     &fAdminBits,      SIZEOF(fAdminBits),      INI_FILENAME);
  401.     WritePrivateProfileStruct(TEXT("Query"), TEXT("HideSearchPane"), &fHideSearchPane, SIZEOF(fHideSearchPane), INI_FILENAME);
  402.     WritePrivateProfileStruct(TEXT("Query"), TEXT("PersistOnOK"),    &fPersistOnOK,    SIZEOF(fPersistOnOK),    INI_FILENAME);
  403.     WritePrivateProfileStruct(TEXT("Query"), TEXT("HideMenus"),      &fHideMenus,      SIZEOF(fHideMenus),      INI_FILENAME);
  404.     WritePrivateProfileStruct(TEXT("Query"), TEXT("AsFilterDlg"),    &fHideSearchUI,   SIZEOF(fHideSearchUI),   INI_FILENAME);
  405.     WritePrivateProfileStruct(TEXT("Query"), TEXT("GetResults"),     &fGetResults,     SIZEOF(fGetResults),     INI_FILENAME);
  406.     WritePrivateProfileString(TEXT("Query"), TEXT("ScopeLocn"), szScopeLocn, INI_FILENAME);
  407.     WritePrivateProfileString(TEXT("Query"), TEXT("SaveLocn"),  szSaveLocn,  INI_FILENAME);
  408.     // Fix the structures to reflect these options
  409.     if ( FAILED(CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (LPVOID*)&pCommonQuery)) )
  410.         return;
  411.     dqip.cbStruct = SIZEOF(dqip);
  412.     dqip.dwFlags = 0;
  413.     dqip.pDefaultScope = NULL;
  414.     
  415.     oqw.cbStruct = SIZEOF(oqw);
  416.     oqw.dwFlags = 0;
  417.     oqw.clsidHandler = CLSID_DsQuery;
  418.     oqw.pHandlerParameters = &dqip;
  419.     oqw.clsidDefaultForm = CLSID_DsFindObjects;
  420.     if ( fGetResults )
  421.         oqw.dwFlags |= OQWF_OKCANCEL;
  422.     if ( fSingleSelect )
  423.         oqw.dwFlags |= OQWF_SINGLESELECT;
  424.     if ( fDefaultForm )
  425.     {
  426.         oqw.dwFlags |= OQWF_DEFAULTFORM;
  427.         oqw.clsidDefaultForm = *forms[iDefaultForm].pFormCLSID;
  428.     }
  429.     if ( fDefaultScope )
  430.         dqip.pDefaultScope = szScopeLocn;
  431.     if ( fNoSave )
  432.         dqip.dwFlags |= DSQPF_NOSAVE;
  433.     if ( fSaveWhere )
  434.     {
  435.         dqip.dwFlags |= DSQPF_SAVELOCATION;
  436.         dqip.pDefaultSaveLocation = szSaveLocn;
  437.     }
  438.     if ( fShowHidden )
  439.         dqip.dwFlags |= DSQPF_SHOWHIDDENOBJECTS;
  440.     
  441.     if ( fAdminBits )
  442.         dqip.dwFlags |= DSQPF_ENABLEADMINFEATURES|DSQPF_ENABLEADVANCEDFEATURES;
  443.     if ( fRemoveScopes )
  444.         oqw.dwFlags |= OQWF_REMOVESCOPES;
  445.     if ( fRemoveForms )
  446.         oqw.dwFlags |= OQWF_REMOVEFORMS;
  447.     if ( fIssueOnOpen )
  448.         oqw.dwFlags |= OQWF_ISSUEONOPEN;
  449.     if ( fShowOptional )
  450.         oqw.dwFlags |= OQWF_SHOWOPTIONAL;
  451.     if ( fHideSearchPane )
  452.     oqw.dwFlags |= OQWF_HIDESEARCHPANE;
  453.    
  454.     if ( fPersistOnOK )
  455.     {
  456.         pPersistQuery = new CPersistQuery(GetDlgItem(hDlg, IDC_PERSISTDATA));
  457.         if ( pPersistQuery )
  458.         {
  459.             oqw.dwFlags |= OQWF_SAVEQUERYONOK;
  460.             oqw.pPersistQuery = pPersistQuery;
  461.         }
  462.     }
  463.     if ( fHideMenus )
  464.         oqw.dwFlags |= OQWF_HIDEMENUS;
  465.     if ( fHideSearchUI )
  466.         oqw.dwFlags |= OQWF_HIDESEARCHUI;
  467.     // Now display the dialog, and if we succeeded and get an IDataObject then
  468.     // slurp the results into our list view.
  469.     hwndResults = GetDlgItem(hDlg, IDC_RESULTS);
  470.     ListView_DeleteAllItems(hwndResults);
  471.     SetDlgItemText(hDlg, IDC_CLSIDNAMESPACE, TEXT(""));
  472.     SetDlgItemText(hDlg, IDC_ITEMCOUNT, TEXT(""));
  473.     SetDlgItemText(hDlg, IDC_LDAPFILTER, TEXT(""));
  474.     hr = pCommonQuery->OpenQueryWindow(hDlg, &oqw, &pDataObject);
  475.     if ( SUCCEEDED(hr) && pDataObject )
  476.     {
  477.         // get the DSOBJECTNAMES and fill the list view accordingly
  478.         if ( !g_cfDsObjectNames )
  479.             g_cfDsObjectNames = RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  480.         fmte.cfFormat = g_cfDsObjectNames;  
  481.         if ( SUCCEEDED(pDataObject->GetData(&fmte, &medium)) )
  482.         {
  483.             LPDSOBJECTNAMES pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal;
  484.             SHStringFromGUID(pDsObjects->clsidNamespace, szBuffer, ARRAYSIZE(szBuffer));
  485.             SetDlgItemText(hDlg, IDC_CLSIDNAMESPACE, szBuffer);
  486.             wsprintf(szBuffer, TEXT("%d"), pDsObjects->cItems);
  487.             SetDlgItemText(hDlg, IDC_ITEMCOUNT, szBuffer);
  488.             for ( i = 0 ; i != pDsObjects->cItems ; i++ )
  489.             {
  490.                 lvi.mask = LVIF_TEXT;
  491.                 lvi.iItem = i;
  492.                 lvi.iSubItem = 0;
  493.                 lvi.pszText = (LPTSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[i].offsetName);
  494.                 ListView_InsertItem(hwndResults, &lvi);
  495.                 ListView_SetItemText(hwndResults, i, 1, (LPTSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[i].offsetClass));            
  496.                 wsprintf(szBuffer, TEXT("%08x"), pDsObjects->aObjects[i].dwFlags);
  497.                 ListView_SetItemText(hwndResults, i, 2, szBuffer);
  498.                 wsprintf(szBuffer, TEXT("%08x"), pDsObjects->aObjects[i].dwProviderFlags);
  499.                 ListView_SetItemText(hwndResults, i, 3, szBuffer);
  500.             }
  501.             ReleaseStgMedium(&medium);
  502.         }
  503.         // now get the DSQUERYPARAMS and lets get the filter string
  504.         if ( !g_cfDsQueryParams )
  505.             g_cfDsQueryParams = RegisterClipboardFormat(CFSTR_DSQUERYPARAMS);
  506.         fmte.cfFormat = g_cfDsQueryParams;  
  507.         if ( SUCCEEDED(pDataObject->GetData(&fmte, &medium)) )
  508.         {
  509.             LPDSQUERYPARAMS pDsQueryParams = (LPDSQUERYPARAMS)medium.hGlobal;
  510.             LPWSTR pFilter = (LPTSTR)ByteOffset(pDsQueryParams, pDsQueryParams->offsetQuery);
  511.             SetDlgItemText(hDlg, IDC_LDAPFILTER, pFilter);
  512.         }
  513.         pDataObject->Release();
  514.     }
  515.     pCommonQuery->Release();
  516.     if ( pPersistQuery )
  517.         pPersistQuery->Release();
  518. }
  519. /*-----------------------------------------------------------------------------
  520. / Query_BrowseForScope
  521. / --------------------
  522. /   Query the DS and populate the specified list view with results we get back.
  523. /
  524. / In:
  525. /   hDlg -> parent of find dialog
  526. /
  527. / Out:
  528. /   -
  529. /----------------------------------------------------------------------------*/
  530. void Query_BrowseForScope(HWND hDlg)
  531. {
  532.     DSBROWSEINFO dsbi;
  533.     TCHAR szBuffer[MAX_PATH];
  534.     GetDlgItemText(hDlg, IDC_SCOPELOCN, szBuffer, ARRAYSIZE(szBuffer));        
  535.     dsbi.cbStruct = SIZEOF(dsbi);
  536.     dsbi.hwndOwner = hDlg;
  537.     dsbi.pszCaption = TEXT("Browse for default scope");
  538.     dsbi.pszTitle = TEXT("Select a location to start the query from");
  539.     dsbi.pszRoot = NULL;
  540.     dsbi.pszPath = szBuffer;
  541.     dsbi.cchPath = ARRAYSIZE(szBuffer);
  542.     dsbi.dwFlags = DSBI_ENTIREDIRECTORY;
  543.     dsbi.pfnCallback = NULL;
  544.     dsbi.lParam = (LPARAM)0;
  545.     if ( lstrlen(szBuffer) )
  546.         dsbi.dwFlags |= DSBI_EXPANDONOPEN;
  547.     if ( IDOK == DsBrowseForContainer(&dsbi) )
  548.         SetDlgItemText(hDlg, IDC_SCOPELOCN, szBuffer);        
  549. }
  550. /*-----------------------------------------------------------------------------
  551. / Query_BrowseForSaveLocation
  552. / ---------------------------
  553. /   Browse for a new save location setting the IDC_SAVELOCN control
  554. /   to contain the new string.
  555. /
  556. / In:
  557. /   hDlg -> parent of find dialog
  558. /
  559. / Out:
  560. /   -
  561. /----------------------------------------------------------------------------*/
  562. void Query_BrowseForSaveLocation(HWND hDlg)
  563. {
  564.     LPITEMIDLIST pidl;
  565.     BROWSEINFO bi;
  566.     TCHAR szBuffer[MAX_PATH];
  567.     bi.hwndOwner = hDlg;
  568.     bi.pidlRoot = NULL;
  569.     bi.pszDisplayName = NULL;
  570.     bi.lpszTitle = TEXT("Select location to save searches to by default.");
  571.     bi.ulFlags = 0;
  572.     bi.lpfn = NULL;
  573.     bi.lParam = 0;
  574.     bi.iImage = 0;
  575.     pidl = SHBrowseForFolder(&bi);
  576.     if ( pidl )
  577.     {    
  578.         if ( SHGetPathFromIDList(pidl, szBuffer) )
  579.             SetDlgItemText(hDlg, IDC_SAVELOCN, szBuffer);
  580.         ILFree(pidl);
  581.     }
  582. }
  583. /*-----------------------------------------------------------------------------
  584. / Main function for the app - handle initalisation etc.
  585. /----------------------------------------------------------------------------*/
  586. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  587. {
  588.     TCHAR szBuffer[MAX_PATH];
  589.     LPTSTR pDefaultScope = NULL;
  590.     g_hInstance = hInstance;
  591.     InitCommonControls();
  592.     CoInitialize(NULL);    
  593.     if ( lpCmdLine && *lpCmdLine )
  594.     {
  595.         MultiByteToWideChar(CP_ACP, 0, lpCmdLine, -1, szBuffer, ARRAYSIZE(szBuffer));
  596.         pDefaultScope = szBuffer;
  597.     }
  598.     DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SEARCHDS), NULL, Query_DlgProc, (LPARAM)pDefaultScope);
  599.     CoUninitialize();
  600.     return 0;
  601. }
  602. /*-----------------------------------------------------------------------------
  603. / Constructor / IUnknown methods
  604. /----------------------------------------------------------------------------*/
  605. CPersistQuery::CPersistQuery(HWND hwndView)
  606. {
  607.     m_cRefCount = 1;
  608.     m_hwndView = hwndView;
  609. }
  610. //
  611. // IUnknown methods
  612. //
  613. STDMETHODIMP CPersistQuery::QueryInterface(REFIID riid, LPVOID* ppvObject)
  614. {
  615.     if ( IsEqualIID(riid, IID_IPersistQuery) )
  616.     {
  617.         *ppvObject = (LPVOID)(IPersistQuery*)this;
  618.         return S_OK;
  619.     }
  620.     return E_NOTIMPL;
  621. }
  622. STDMETHODIMP_(ULONG) CPersistQuery::AddRef()
  623. {
  624.     return ++m_cRefCount;
  625. }
  626. STDMETHODIMP_(ULONG) CPersistQuery::Release()
  627. {
  628.     if ( --m_cRefCount == 0 )
  629.     {
  630.         delete this;
  631.         return 0;
  632.     }
  633.     return m_cRefCount;
  634. }
  635. /*-----------------------------------------------------------------------------
  636. / IPersist methods
  637. /----------------------------------------------------------------------------*/
  638. STDMETHODIMP CPersistQuery::GetClassID(THIS_ CLSID* pClassID)
  639. {
  640.     return E_NOTIMPL;
  641. }
  642. /*-----------------------------------------------------------------------------
  643. / IPersistQuery methods
  644. /----------------------------------------------------------------------------*/
  645. VOID _AddResultToView(HWND hwndView, LPCTSTR pSection, LPCTSTR pTag, LPCTSTR pValue)
  646. {
  647.     LV_ITEM lvi;
  648.     INT i;
  649.     lvi.mask = LVIF_TEXT;
  650.     lvi.iItem = 0x7fffffff;
  651.     lvi.iSubItem = 0;
  652.     lvi.pszText = (LPTSTR)pSection;
  653.     i = ListView_InsertItem(hwndView, &lvi);
  654.     if ( i >= 0 )
  655.     {
  656.         ListView_SetItemText(hwndView, i, 1, (LPTSTR)pTag);
  657.         ListView_SetItemText(hwndView, i, 2, (LPTSTR)pValue);
  658.     }
  659. }
  660. STDMETHODIMP CPersistQuery::WriteString(THIS_ LPCTSTR pSection, LPCTSTR pKey, LPCTSTR pValue)
  661. {
  662.     _AddResultToView(m_hwndView, pSection, pKey, pValue);
  663.     return S_OK;
  664. }
  665. STDMETHODIMP CPersistQuery::ReadString(THIS_ LPCTSTR pSection, LPCTSTR pKey, LPTSTR pBuffer, INT cchBuffer)
  666. {
  667.     return E_NOTIMPL;
  668. }
  669. STDMETHODIMP CPersistQuery::WriteInt(THIS_ LPCTSTR pSection, LPCTSTR pKey, INT value)
  670. {
  671.     TCHAR szBuffer[64];
  672.     wsprintf(szBuffer, TEXT("%d"), value);
  673.     _AddResultToView(m_hwndView, pSection, pKey, szBuffer);
  674.     return S_OK;
  675. }
  676. STDMETHODIMP CPersistQuery::ReadInt(THIS_ LPCTSTR pSection, LPCTSTR pKey, LPINT pValue)
  677. {
  678.     return E_NOTIMPL;
  679. }
  680. STDMETHODIMP CPersistQuery::WriteStruct(THIS_ LPCTSTR pSection, LPCTSTR pKey, LPVOID pStruct, DWORD cbStruct)
  681. {
  682.     TCHAR szBuffer[128];
  683.     wsprintf(szBuffer, TEXT("Structure (%d byte in size)"), cbStruct);
  684.     _AddResultToView(m_hwndView, pSection, pKey, szBuffer);
  685.     return S_OK;
  686. }
  687. STDMETHODIMP CPersistQuery::ReadStruct(THIS_ LPCTSTR pSection, LPCTSTR pKey, LPVOID pStruct, DWORD cbStruct)
  688. {
  689.     return E_NOTIMPL;
  690. }
  691. STDMETHODIMP CPersistQuery::Clear(THIS)
  692. {
  693.     ListView_DeleteAllItems(m_hwndView);
  694.     return S_OK;
  695. }