Leaked source code of windows server 2003
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.

436 lines
10 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. All rights reserved.
  4. Module Name:
  5. spllibex.cxx
  6. Abstract:
  7. spllib extentions
  8. Author:
  9. Lazar Ivanov (LazarI) 29-Mar-2000
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "spllibex.hxx"
  15. ////////////////////////////////////////////////
  16. //
  17. // class CMsgBoxCounter
  18. //
  19. // this class counts the popups which have come up
  20. // during it's lifetime.
  21. //
  22. static DWORD g_dwTlsMsgsCounterCookie = -1;
  23. CMsgBoxCounter::CMsgBoxCounter(UINT uFlags)
  24. : m_uCount(0),
  25. m_uFlags(uFlags),
  26. m_uMsgID(0)
  27. {
  28. if( IsInitialized() )
  29. {
  30. // Only one instance of CMsgBoxCounter at a time can use
  31. // the TLS cookie
  32. ASSERT(NULL == TlsGetValue(g_dwTlsMsgsCounterCookie));
  33. TlsSetValue(g_dwTlsMsgsCounterCookie, reinterpret_cast<LPVOID>(this));
  34. }
  35. }
  36. CMsgBoxCounter::~CMsgBoxCounter()
  37. {
  38. if( IsInitialized() )
  39. {
  40. ASSERT(this == TlsGetValue(g_dwTlsMsgsCounterCookie));
  41. TlsSetValue(g_dwTlsMsgsCounterCookie, NULL);
  42. }
  43. }
  44. BOOL CMsgBoxCounter::Initialize()
  45. {
  46. // allocate TLS cookies
  47. if( !IsInitialized() )
  48. {
  49. g_dwTlsMsgsCounterCookie = TlsAlloc();
  50. }
  51. return IsInitialized();
  52. }
  53. BOOL CMsgBoxCounter::Uninitialize()
  54. {
  55. // free up the TLS cookies
  56. if( -1 != g_dwTlsMsgsCounterCookie )
  57. {
  58. VERIFY(TlsFree(g_dwTlsMsgsCounterCookie));
  59. g_dwTlsMsgsCounterCookie = -1;
  60. }
  61. return TRUE;
  62. }
  63. UINT CMsgBoxCounter::GetCount()
  64. {
  65. UINT uReturn = INVALID_COUNT;
  66. if( IsInitialized() )
  67. {
  68. // lookup the value in the TLS
  69. CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
  70. uReturn = pThis->m_uCount;
  71. }
  72. return uReturn;
  73. }
  74. BOOL CMsgBoxCounter::IsInitialized()
  75. {
  76. // the TLS cookie should be valid to assume success
  77. return (-1 != g_dwTlsMsgsCounterCookie);
  78. }
  79. void CMsgBoxCounter::LogMessage(UINT uFlags)
  80. {
  81. if( IsInitialized() )
  82. {
  83. CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
  84. if( pThis && (pThis->m_uFlags & uFlags) )
  85. {
  86. // increment the message box counter
  87. pThis->m_uCount++;
  88. }
  89. }
  90. }
  91. void CMsgBoxCounter::SetMsg(UINT uMsgID)
  92. {
  93. if( IsInitialized() )
  94. {
  95. CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
  96. if( pThis )
  97. {
  98. pThis->m_uMsgID = uMsgID;
  99. }
  100. }
  101. }
  102. UINT CMsgBoxCounter::GetMsg()
  103. {
  104. UINT uMsgID = 0;
  105. if( IsInitialized() )
  106. {
  107. CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
  108. if( pThis )
  109. {
  110. uMsgID = pThis->m_uMsgID;
  111. }
  112. }
  113. return uMsgID;
  114. }
  115. ////////////////////////////////////////////////
  116. //
  117. // class CPrintNotify
  118. //
  119. // printer notifications listener
  120. //
  121. CPrintNotify::CPrintNotify(
  122. IPrinterChangeCallback *pClient,
  123. DWORD dwCount,
  124. const PPRINTER_NOTIFY_OPTIONS_TYPE arrNotifications,
  125. DWORD dwFlags
  126. ):
  127. m_bRegistered(FALSE),
  128. m_uCookie(0),
  129. m_dwCount(dwCount),
  130. m_arrNotifications(arrNotifications),
  131. m_dwFlags(dwFlags)
  132. {
  133. SINGLETHREADRESET(TrayUIThread)
  134. ASSERT(pClient);
  135. m_spClient.CopyFrom(pClient);
  136. }
  137. CPrintNotify::~CPrintNotify()
  138. {
  139. SINGLETHREAD(TrayUIThread)
  140. // make sure we uninitialize here
  141. Uninitialize();
  142. }
  143. HRESULT CPrintNotify::Initialize(LPCTSTR pszPrinter)
  144. {
  145. SINGLETHREAD(TrayUIThread)
  146. ASSERT(!m_shPrinter);
  147. ASSERT(!m_shNotify);
  148. ASSERT(pszPrinter);
  149. HRESULT hr = E_FAIL;
  150. SetLastError(0);
  151. if( NULL == m_pPrintLib.pGet() )
  152. {
  153. // aquire a reference to the printui lib object. this will be used
  154. // to register/unregister notification handles in the folder cache.
  155. TPrintLib::bGetSingleton(m_pPrintLib);
  156. }
  157. if( m_pPrintLib.pGet() )
  158. {
  159. hr = m_strPrinter.bUpdate(pszPrinter) ? S_OK : E_OUTOFMEMORY;
  160. if( SUCCEEDED(hr) )
  161. {
  162. DWORD dwAccess = 0;
  163. DWORD dwErr = TPrinter::sOpenPrinter(m_strPrinter, &dwAccess, &m_shPrinter);
  164. hr = HRESULT_FROM_WIN32(dwErr);
  165. }
  166. if( SUCCEEDED(hr) )
  167. {
  168. ASSERT(m_dwFlags);
  169. PRINTER_NOTIFY_OPTIONS opt = {2, 0, m_dwCount, m_arrNotifications};
  170. m_shNotify = FindFirstPrinterChangeNotification(m_shPrinter, m_dwFlags, 0, &opt);
  171. // setup the HRESULT here
  172. hr = m_shNotify ? S_OK : CreateHRFromWin32();
  173. }
  174. }
  175. else
  176. {
  177. // build an appropriate HRESULT
  178. hr = CreateHRFromWin32();
  179. }
  180. if( FAILED(hr) )
  181. {
  182. // if something has failed we don't want to
  183. // keep the handles around in this case
  184. m_shNotify = NULL;
  185. m_shPrinter = NULL;
  186. m_strPrinter.bUpdate(NULL);
  187. }
  188. return hr;
  189. }
  190. HRESULT CPrintNotify::Uninitialize()
  191. {
  192. SINGLETHREAD(TrayUIThread)
  193. // make sure we don't listen anymore
  194. HRESULT hr = StopListen();
  195. // clear the handles
  196. m_shNotify = NULL;
  197. m_shPrinter = NULL;
  198. m_strPrinter.bUpdate(NULL);
  199. return hr;
  200. }
  201. // this is just wrappers around _NotifyRegister
  202. HRESULT CPrintNotify::StartListen()
  203. {
  204. SINGLETHREAD(TrayUIThread)
  205. ASSERT(m_shNotify);
  206. ASSERT(m_spClient);
  207. // register ourselves in the wait list
  208. return _NotifyRegister(TRUE);
  209. }
  210. HRESULT CPrintNotify::Refresh(LPVOID lpCookie, PFN_PrinterChange pfn)
  211. {
  212. SINGLETHREAD(TrayUIThread)
  213. ASSERT(m_shNotify);
  214. ASSERT(m_spClient);
  215. ASSERT(m_dwFlags);
  216. HRESULT hr = S_OK;
  217. DWORD dwChange = 0;
  218. CAutoPtrPrinterNotify pInfo;
  219. PRINTER_NOTIFY_OPTIONS opt = {2, PRINTER_NOTIFY_OPTIONS_REFRESH, m_dwCount, m_arrNotifications };
  220. if( FindNextPrinterChangeNotification(m_shNotify, &dwChange, &opt, pInfo.GetPPV()) )
  221. {
  222. // we hope the client callback will process this call quickly as there shouldn't
  223. // be any delays here if we don't want to loose notifications.
  224. // we don't really care what the retirn value is here.
  225. if( pfn )
  226. {
  227. pfn(lpCookie, m_uCookie, dwChange, pInfo);
  228. }
  229. else
  230. {
  231. m_spClient->PrinterChange(m_uCookie, dwChange, pInfo);
  232. }
  233. }
  234. else
  235. {
  236. hr = HRESULT_FROM_WIN32(GetLastError());
  237. }
  238. return hr;
  239. }
  240. // this is just wrappers around _NotifyRegister
  241. HRESULT CPrintNotify::StopListen()
  242. {
  243. SINGLETHREAD(TrayUIThread)
  244. // unregister ourselves from the wait list
  245. return _NotifyRegister(FALSE);
  246. }
  247. HRESULT CPrintNotify::SetCookie(ULONG_PTR uCookie)
  248. {
  249. SINGLETHREAD(TrayUIThread)
  250. m_uCookie = uCookie;
  251. return S_OK;
  252. }
  253. LPCTSTR CPrintNotify::GetPrinter() const
  254. {
  255. // !!MT NOTES!!
  256. // this function can be invoked only from the bkgnd threads,
  257. // but it never touches the object state.
  258. return (0 == m_strPrinter.uLen() ? NULL : m_strPrinter);
  259. }
  260. HANDLE CPrintNotify::GetPrinterHandle() const
  261. {
  262. SINGLETHREAD(TrayUIThread)
  263. return m_shPrinter;
  264. }
  265. HRESULT CPrintNotify::_NotifyRegister(BOOL bRegister)
  266. {
  267. SINGLETHREAD(TrayUIThread)
  268. DWORD dw = 0;
  269. HRESULT hr = E_FAIL;
  270. //
  271. // m_pPrintLib.pGet() could be NULL here in case of partial
  272. // initialization
  273. //
  274. if( m_pPrintLib.pGet() && m_pPrintLib->pNotify().pGet() )
  275. {
  276. if( bRegister )
  277. {
  278. //
  279. // Only register when in a unregistered state
  280. //
  281. if( m_bRegistered )
  282. {
  283. hr = S_OK;
  284. }
  285. else
  286. {
  287. dw = m_pPrintLib->pNotify()->sRegister(this);
  288. hr = HRESULT_FROM_WIN32(dw);
  289. }
  290. m_bRegistered = SUCCEEDED(hr) ? TRUE : m_bRegistered;
  291. }
  292. else
  293. {
  294. //
  295. // Only unregister when in a registered state
  296. //
  297. if( !m_bRegistered )
  298. {
  299. hr = S_OK;
  300. }
  301. else
  302. {
  303. dw = m_pPrintLib->pNotify()->sUnregister(this);
  304. hr = HRESULT_FROM_WIN32(dw);
  305. }
  306. m_bRegistered = SUCCEEDED(hr) ? FALSE : m_bRegistered;
  307. }
  308. }
  309. return hr;
  310. }
  311. HANDLE CPrintNotify::hEvent() const
  312. {
  313. // !!MT NOTES!!
  314. // this function can be invoked only from the bkgnd threads,
  315. // but it never touches the object state.
  316. ASSERT(m_shNotify);
  317. return m_shNotify;
  318. }
  319. void CPrintNotify::vProcessNotifyWork(TNotify *pNotify)
  320. {
  321. // !!MT NOTES!!
  322. // this function can be invoked only from the bkgnd threads,
  323. // but it never touches the object state.
  324. ASSERT(m_shNotify);
  325. ASSERT(m_spClient);
  326. DWORD dwChange = 0;
  327. CAutoPtrPrinterNotify pInfo;
  328. PRINTER_NOTIFY_OPTIONS opt = {2, 0, m_dwCount, m_arrNotifications };
  329. if( FindNextPrinterChangeNotification(m_shNotify, &dwChange, &opt, pInfo.GetPPV()) )
  330. {
  331. // we hope the client callback will process this call quickly as there shouldn't
  332. // be any delays here if we don't want to loose notifications.
  333. // we don't really care what the retirn value is here.
  334. m_spClient->PrinterChange(m_uCookie, dwChange, pInfo);
  335. }
  336. }
  337. ////////////////////////////////////////////////
  338. // class CMultilineEditBug
  339. //
  340. LRESULT CMultilineEditBug::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  341. {
  342. HWND hDlg = GetParent(hwnd);
  343. if( hDlg && GetParent(hDlg) )
  344. {
  345. hDlg = GetParent(hDlg);
  346. }
  347. if( hDlg && WM_KEYDOWN == uMsg && VK_RETURN == wParam && GetKeyState(VK_CONTROL) >= 0 )
  348. {
  349. LRESULT lr = SendMessage(hDlg, DM_GETDEFID, 0, 0);
  350. if( lr && LOWORD(lr) && DC_HASDEFID == HIWORD(lr) )
  351. {
  352. HWND hwndButton = GetDlgItem(hDlg, LOWORD(lr));
  353. PostMessage(hDlg, WM_COMMAND, MAKEWPARAM(LOWORD(lr), BN_CLICKED), (LPARAM)hwndButton);
  354. }
  355. }
  356. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  357. }