Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
13 KiB

  1. // this is really private data to CPrinterFolder
  2. typedef struct
  3. {
  4. USHORT cb;
  5. USHORT uFlags;
  6. #define PRINTER_MAGIC 0xBEBADB00
  7. DWORD dwMagic;
  8. DWORD dwType;
  9. WCHAR cName[MAXNAMELENBUFFER];
  10. USHORT uTerm;
  11. } IDPRINTER;
  12. typedef UNALIGNED IDPRINTER *LPIDPRINTER;
  13. typedef const UNALIGNED IDPRINTER *LPCIDPRINTER;
  14. // W95 IDPrinter structure
  15. typedef struct
  16. {
  17. USHORT cb;
  18. char cName[32]; // Win9x limitation
  19. USHORT uTerm;
  20. } W95IDPRINTER;
  21. typedef const UNALIGNED W95IDPRINTER *LPW95IDPRINTER;
  22. //
  23. // Constants
  24. //
  25. const UINT kDNSMax = INTERNET_MAX_HOST_NAME_LENGTH;
  26. const UINT kServerBufMax = kDNSMax + 2 + 1;
  27. //
  28. // Max printer name should really be MAX_PATH, but if you create
  29. // a max path printer and connect to it remotely, win32spl prepends
  30. // "\\server\" to it, causing it to exceed max path. The new UI
  31. // therefore makes the max path MAX_PATH-kServerLenMax, but we still
  32. // allow the old case to work.
  33. //
  34. const UINT kPrinterBufMax = MAX_PATH + kServerBufMax + 1;
  35. class CPrinterFolder : public IRemoteComputer,
  36. public IPrinterFolder,
  37. public IFolderNotify,
  38. public IShellFolder2,
  39. public IPersistFolder2,
  40. public IContextMenuCB,
  41. public IShellIconOverlay
  42. {
  43. friend class CPrintersEnum;
  44. friend class CPrinterFolderViewCB;
  45. public:
  46. CPrinterFolder();
  47. // IUnknown
  48. STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
  49. STDMETHODIMP_(ULONG) AddRef();
  50. STDMETHODIMP_(ULONG) Release();
  51. // IShellFolder
  52. STDMETHODIMP BindToObject(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut);
  53. STDMETHODIMP BindToStorage(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void** ppvOut);
  54. STDMETHODIMP CompareIDs(LPARAM iCol, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
  55. STDMETHODIMP CreateViewObject(HWND hwnd, REFIID riid, void** ppvOut);
  56. STDMETHODIMP EnumObjects(HWND hwndOwner, DWORD grfFlags, IEnumIDList** ppenum);
  57. STDMETHODIMP GetAttributesOf(UINT cidl, LPCITEMIDLIST* apidl, ULONG* prgfInOut);
  58. STDMETHODIMP GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName);
  59. STDMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST* apidl, REFIID riid, UINT* prgfInOut, void** ppvOut);
  60. STDMETHODIMP ParseDisplayName(HWND hwnd, LPBC pbc, LPOLESTR lpszDisplayName, ULONG* pchEaten, LPITEMIDLIST* ppidl, ULONG* pdwAttributes);
  61. STDMETHODIMP SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD dwReserved, LPITEMIDLIST* ppidlOut);
  62. // IShellFolder2
  63. STDMETHODIMP EnumSearches(IEnumExtraSearch **ppenum);
  64. STDMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG* pSort, ULONG* pDisplay);
  65. STDMETHODIMP GetDefaultColumnState(UINT iColumn, DWORD* pdwState);
  66. STDMETHODIMP GetDefaultSearchGUID(LPGUID pGuid);
  67. STDMETHODIMP GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID* pscid, VARIANT* pv);
  68. STDMETHODIMP GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS* pDetails);
  69. STDMETHODIMP MapColumnToSCID(UINT iCol, SHCOLUMNID* pscid);
  70. // IPersistFolder2
  71. STDMETHODIMP GetCurFolder(LPITEMIDLIST *ppidl);
  72. STDMETHODIMP Initialize(LPCITEMIDLIST pidl);
  73. STDMETHODIMP GetClassID(LPCLSID lpClassID);
  74. // IShellIconOverlay
  75. STDMETHODIMP GetOverlayIndex(LPCITEMIDLIST pidl, int* pIndex);
  76. STDMETHODIMP GetOverlayIconIndex(LPCITEMIDLIST pidl, int *pIndex);
  77. // IRemoteComputer
  78. STDMETHODIMP Initialize(const WCHAR *pszMachine, BOOL bEnumerating);
  79. // IPrinterFolder
  80. STDMETHODIMP_(BOOL) IsPrinter(LPCITEMIDLIST pidl);
  81. // IFolderNotify
  82. STDMETHODIMP_(BOOL) ProcessNotify(FOLDER_NOTIFY_TYPE NotifyType, LPCWSTR pszName, LPCWSTR pszNewName);
  83. // IContextMenuCB
  84. STDMETHODIMP CallBack(IShellFolder *psf, HWND hwnd,IDataObject *pdo, UINT uMsg, WPARAM wParam, LPARAM lParam);
  85. // DUI webview impl.
  86. HRESULT GetWebViewLayout(IUnknown *pv, UINT uViewMode, SFVM_WEBVIEW_LAYOUT_DATA* pData);
  87. HRESULT GetWebViewContent(IUnknown *pv, SFVM_WEBVIEW_CONTENT_DATA* pData);
  88. HRESULT GetWebViewTasks(IUnknown *pv, SFVM_WEBVIEW_TASKSECTION_DATA* pTasks);
  89. // mask passsed to _IsContextMenuVerbEnabled to determine the selection type in which
  90. // this command is applicable
  91. enum
  92. {
  93. // nothing is selected
  94. SEL_NONE = 0x0000, // nothing is selected
  95. // single selection types
  96. SEL_SINGLE_ADDPRN = 0x0001, // the add printer wizard object is selected
  97. SEL_SINGLE_PRINTER = 0x0002, // 1 printer is selected
  98. SEL_SINGLE_LINK = 0x0004, // 1 link is selected
  99. // any single selection type
  100. SEL_SINGLE_ANY = SEL_SINGLE_ADDPRN | SEL_SINGLE_PRINTER | SEL_SINGLE_LINK,
  101. // multi selection types
  102. SEL_MULTI_PRINTER = 0x0010, // 2+ printers are selected
  103. SEL_MULTI_LINK = 0x0020, // 2+ links are selected
  104. SEL_MULTI_MIXED = 0x0040, // 2+ objects of any type are selected
  105. // any link in the selection
  106. SEL_LINK_ANY = SEL_SINGLE_LINK | SEL_MULTI_LINK | SEL_MULTI_MIXED,
  107. // any printer in the selection
  108. SEL_PRINTER_ANY = SEL_SINGLE_ADDPRN | SEL_SINGLE_ADDPRN |
  109. SEL_MULTI_PRINTER | SEL_MULTI_MIXED,
  110. // any multi selection type
  111. SEL_MULTI_ANY = SEL_MULTI_PRINTER | SEL_MULTI_LINK | SEL_MULTI_MIXED,
  112. // any selection type
  113. SEL_ANY = SEL_SINGLE_ANY | SEL_MULTI_ANY,
  114. };
  115. // split the selection into its parts (printers and links) and determine the
  116. // selection type (see the enum above)
  117. HRESULT SplitSelection(IDataObject *pdo, UINT *puSelType, IDataObject **ppdoPrinters, IDataObject **ppdoLinks);
  118. // webview verbs
  119. enum WV_VERB
  120. {
  121. // standard verbs
  122. WVIDM_DELETE,
  123. WVIDM_RENAME,
  124. WVIDM_PROPERTIES,
  125. // common verbs
  126. WVIDM_ADDPRINTERWIZARD,
  127. WVIDM_SERVERPROPERTIES,
  128. WVIDM_SETUPFAXING,
  129. WVIDM_CREATELOCALFAX,
  130. WVIDM_SENDFAXWIZARD,
  131. // special common verbs
  132. WVIDM_TROUBLESHOOTER,
  133. WVIDM_GOTOSUPPORT,
  134. // printer verbs
  135. WVIDM_OPENPRN,
  136. WVIDM_NETPRN_INSTALL,
  137. WVIDM_SETDEFAULTPRN,
  138. WVIDM_DOCUMENTDEFAULTS,
  139. WVIDM_PAUSEPRN,
  140. WVIDM_RESUMEPRN,
  141. WVIDM_PURGEPRN,
  142. WVIDM_SHARING,
  143. WVIDM_WORKOFFLINE,
  144. WVIDM_WORKONLINE,
  145. // special commands
  146. WVIDM_VENDORURL,
  147. WVIDM_PRINTERURL,
  148. WVIDM_COUNT,
  149. };
  150. // webview support - core APIs
  151. HRESULT _WebviewVerbIsEnabled(WV_VERB eVerbID, UINT uSelMask, BOOL *pbEnabled);
  152. HRESULT _WebviewVerbInvoke(WV_VERB eVerbID, IUnknown* pv, IShellItemArray *psiItemArray);
  153. HRESULT _WebviewCheckToUpdateDataObjectCache(IDataObject *pdo);
  154. private:
  155. virtual ~CPrinterFolder();
  156. // data access
  157. LPCTSTR GetServer() { return _pszServer; }
  158. HANDLE GetFolder() { CheckToRegisterNotify(); return _hFolder; }
  159. BOOL GetAdminAccess() { CheckToRegisterNotify(); return _bAdminAccess; }
  160. static LPCTSTR GetStatusString(PFOLDER_PRINTER_DATA pData, LPTSTR pBuff, UINT uSize);
  161. static INT GetCompareDisplayName(LPCTSTR pName1, LPCTSTR pName2);
  162. INT CompareData(LPCIDPRINTER pidp1, LPCIDPRINTER pidp2, LPARAM iCol);
  163. static ReduceToLikeKinds(UINT *pcidl, LPCITEMIDLIST **papidl, BOOL fPrintObjects);
  164. DWORD SpoolerVersion();
  165. void CheckToRegisterNotify();
  166. void CheckToRefresh();
  167. void RequestRefresh();
  168. HRESULT _GetFullIDList(LPCWSTR pszPrinter, LPITEMIDLIST *ppidl);
  169. static HRESULT _Parse(LPCWSTR pszPrinter, LPITEMIDLIST *ppidl, DWORD dwType = 0, USHORT uFlags = 0);
  170. static void _FillPidl(LPIDPRINTER pidl, LPCTSTR szName, DWORD dwType = 0, USHORT uFlags = 0);
  171. LPCTSTR _BuildPrinterName(LPTSTR pszFullPrinter, LPCIDPRINTER pidp, LPCTSTR pszPrinter);
  172. void _MergeMenu(LPQCMINFO pqcm, LPCTSTR pszPrinter);
  173. HRESULT _InvokeCommand(HWND hwnd, LPCIDPRINTER pidp, WPARAM wParam, LPARAM lParam, LPBOOL pfChooseNewDefault);
  174. HRESULT _InvokeCommandRunAs(HWND hwnd, LPCIDPRINTER pidp, WPARAM wParam, LPARAM lParam, LPBOOL pfChooseNewDefault);
  175. BOOL _PurgePrinter(HWND hwnd, LPCTSTR pszFullPrinter, UINT uAction, BOOL bQuietMode);
  176. LPTSTR _FindIcon(LPCTSTR pszPrinterName, LPTSTR pszModule, ULONG cbModule, int *piIcon, int *piShortcutIcon);
  177. static HRESULT CALLBACK _DFMCallBack(IShellFolder *psf, HWND hwnd,
  178. IDataObject *pdo, UINT uMsg, WPARAM wParam, LPARAM lParam);
  179. HRESULT _PrinterObjectsCallBack(HWND hwnd, UINT uSelType,
  180. IDataObject *pdo, UINT uMsg, WPARAM wParam, LPARAM lParam);
  181. static LPTSTR _ItemName(LPCIDPRINTER pidp, LPTSTR pszName, UINT cch);
  182. static BOOL _IsAddPrinter(LPCIDPRINTER pidp);
  183. HRESULT _UpdateDataObjectCache();
  184. HRESULT _AssocCreate(REFIID riid, void **ppv);
  185. HRESULT _OnRefresh(BOOL bPriorRefresh);
  186. LONG _cRef; // ref count
  187. LPITEMIDLIST _pidl; // the PIDL of this folder
  188. LPTSTR _pszServer; // the print server this folder is browsing (NULL means local PF)
  189. DWORD _dwSpoolerVersion; // the spooler version
  190. HANDLE _hFolder; // handle to the printer folder cache (in printui)
  191. BOOL _bAdminAccess; // TRUE if you have admin access to this print server
  192. BOOL _bReqRefresh; // whether we should request a full refresh during the next enum
  193. // our webview get command state cache. we have 35+ commands and unpacking
  194. // the same data object each time we need to verify the state of a command
  195. // can be very expensive! we are going to maintain a cache with each command
  196. // state and update the cache each time the data object gets changed, so
  197. // the get state callbacks will finish very quickly just by consulting
  198. // the cache.
  199. IDataObject *_pdoCache; // current data object
  200. UINT _uSelCurrent; // current selection type
  201. BOOL _aWVCommandStates[WVIDM_COUNT]; // commands state cache
  202. // the folder has to be MT safe
  203. CCSLock _csLock;
  204. // slow data. this members below should refresh every time the selection changes,
  205. // but we should do this in a separate thread since updating them can take a while
  206. enum ESlowWebviewDataType
  207. {
  208. WV_SLOW_DATA_OEM_SUPPORT_URL,
  209. WV_SLOW_DATA_PRINTER_WEB_URL,
  210. WV_SLOW_DATA_COUNT,
  211. };
  212. enum
  213. {
  214. // in miliseconds
  215. WV_SLOW_DATA_CACHE_TIMEOUT = 5000,
  216. };
  217. class CSlowWVDataCacheEntry
  218. {
  219. public:
  220. CSlowWVDataCacheEntry(CPrinterFolder *ppf):
  221. _ppf(ppf),
  222. _bDataPending(TRUE),
  223. _nLastTimeUpdated(0)
  224. {}
  225. HRESULT Initialize(LPCTSTR pszPrinterName)
  226. {
  227. HRESULT hr = S_OK;
  228. if (pszPrinterName)
  229. {
  230. _bstrPrinterName = pszPrinterName;
  231. hr = _bstrPrinterName ? S_OK : E_OUTOFMEMORY;
  232. }
  233. else
  234. {
  235. hr = E_INVALIDARG;
  236. }
  237. return hr;
  238. }
  239. CPrinterFolder *_ppf;
  240. BOOL _bDataPending;
  241. DWORD _nLastTimeUpdated;
  242. CComBSTR _bstrPrinterName;
  243. CComBSTR _arrData[WV_SLOW_DATA_COUNT];
  244. };
  245. static DWORD WINAPI _SlowWebviewData_WorkerProc(LPVOID lpParameter);
  246. static HRESULT _SlowWVDataRetrieve(LPCTSTR pszPrinterName, BSTR *pbstrSupportUrl, BSTR *pbstrPrinterWebUrl);
  247. static int _CompareSlowWVDataCacheEntries(CSlowWVDataCacheEntry *p1,
  248. CSlowWVDataCacheEntry *p2, LPARAM lParam);
  249. HRESULT _GetSelectedPrinter(BSTR *pbstrVal);
  250. HRESULT _GetSlowWVDataForCurrentPrinter(ESlowWebviewDataType eType, BSTR *pbstrVal);
  251. HRESULT _GetSlowWVData(LPCTSTR pszPrinterName, ESlowWebviewDataType eType, BSTR *pbstrVal);
  252. HRESULT _UpdateSlowWVDataCacheEntry(CSlowWVDataCacheEntry *pCacheEntry);
  253. HRESULT _SlowWVDataUpdateWebviewPane();
  254. HRESULT _SlowWVDataCacheResetUnsafe();
  255. HRESULT _GetCustomSupportURL(BSTR *pbstrVal);
  256. CComBSTR _bstrSelectedPrinter;
  257. CDPA<CSlowWVDataCacheEntry> _dpaSlowWVDataCache;
  258. // fax support...
  259. static HRESULT _GetFaxControl(IDispatch **ppDisp);
  260. static HRESULT _GetFaxCommand(UINT_PTR *puCmd);
  261. static HRESULT _InvokeFaxControlMethod(LPCTSTR pszMethodName);
  262. static DWORD WINAPI _ThreadProc_InstallFaxService(LPVOID lpParameter);
  263. static DWORD WINAPI _ThreadProc_InstallLocalFaxPrinter(LPVOID lpParameter);
  264. };
  265. STDAPI CPrinterFolderDropTarget_CreateInstance(HWND hwnd, IDropTarget **ppdropt);