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.

1886 lines
63 KiB

  1. /*++
  2. Copyright (C) 2000 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. ldmgr.cxx
  6. Abstract:
  7. This file contains the methods and class implementation
  8. necessary for the RPC surrogate used to load 64 bit dlls from
  9. within 32 bit apps.
  10. Author:
  11. Khaled Sedky (khaleds) 18-Jan-2000
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #ifndef __LDINTERFACES_HPP__
  17. #include "ldintrfcs.hpp"
  18. #endif __LDINTERFACES_HPP__
  19. #ifndef __LDFUNCS_HPP__
  20. #include "ldfuncs.hpp"
  21. #endif
  22. #ifndef __LDMGR_HPP__
  23. #include "ldmgr.hpp"
  24. #endif
  25. extern TLoad64BitDllsMgr* pGLdrObj;
  26. extern DWORD DeviceCapsReqSize[MAX_CAPVAL];
  27. /*++
  28. Function Name:
  29. TLoad64BitDllsMgr :: TLoad64BitDllsMgr
  30. Description:
  31. Constructor of the main Loader Object. Mainly initializes
  32. the private data of the class and creates whatever resources
  33. are required
  34. Parameters:
  35. HRESULT *hRes: Returns result of constructing the object
  36. Return Value:
  37. None
  38. --*/
  39. TLoad64BitDllsMgr ::
  40. TLoad64BitDllsMgr(
  41. OUT HRESULT *phRes
  42. ) :
  43. m_UIRefCnt(0),
  44. TClassID("TLoad64BitDllsMgr")
  45. {
  46. HRESULT hLocalRes = S_OK;
  47. HKEY hPrintKey = NULL;
  48. DWORD ValueSize = sizeof(DWORD);
  49. //
  50. // Initializing the time structure before any time
  51. // calculations
  52. //
  53. ZeroMemory(&m_LastTransactionTime,sizeof(SYSTEMTIME));
  54. //
  55. // Read the expiration time from the registry
  56. //
  57. if((ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  58. L"System\\CurrentControlSet\\Control\\Print",
  59. &hPrintKey)) ||
  60. (ERROR_SUCCESS != RegQueryValueEx(hPrintKey,
  61. L"SplWOW64TimeOut",
  62. NULL,
  63. NULL,
  64. (LPBYTE) &m_ExpirationTime,
  65. &ValueSize)))
  66. {
  67. m_ExpirationTime = KTwoMinutes;
  68. }
  69. else
  70. {
  71. m_ExpirationTime = m_ExpirationTime * KOneMinute;
  72. }
  73. if(hPrintKey)
  74. {
  75. RegCloseKey(hPrintKey);
  76. }
  77. __try
  78. {
  79. DWORD CurrProcessId = GetCurrentProcessId();
  80. //
  81. // Initializing the Critical Section
  82. //
  83. InitializeCriticalSection(&m_LdMgrLock);
  84. //
  85. // Setting the initial time to that of the process
  86. // first instantiation
  87. //
  88. GetSystemTime(&m_LastTransactionTime);
  89. //
  90. // The Session ID uniquely identifies each process for
  91. // both the RPC end point and the LPC port name
  92. //
  93. ProcessIdToSessionId(CurrProcessId,&m_CurrSessionId);
  94. AddRef();
  95. }
  96. __except(1)
  97. {
  98. hLocalRes = GetLastErrorAsHRESULT(TranslateExceptionCode(GetExceptionCode()));
  99. }
  100. if(phRes)
  101. {
  102. *phRes = hLocalRes;
  103. }
  104. }
  105. /*++
  106. Function Name:
  107. TLoad64BitDllsMgr :: ~TLoad64BitDllsMgr
  108. Description:
  109. Destructor of the main Loader Object. Mainly fress up any
  110. allocated resources
  111. Parameters:
  112. None
  113. Return Value:
  114. None
  115. --*/
  116. TLoad64BitDllsMgr ::
  117. ~TLoad64BitDllsMgr()
  118. {
  119. DeleteCriticalSection(&m_LdMgrLock);
  120. }
  121. /*++
  122. Function Name:
  123. TLoad64BitDllsMgr :: QueryInterface
  124. Description:
  125. Returned the correct object for each set of simillar functions
  126. Parameters:
  127. None
  128. Return Value:
  129. HRESULT hREs = S_OK in case of a suitable Interface
  130. E_NOINTERFACE in case of none
  131. --*/
  132. HRESULT
  133. TLoad64BitDllsMgr ::
  134. QueryInterface(
  135. IN REFIID InterfaceID,
  136. OUT PVOID *ppInterface
  137. )
  138. {
  139. HRESULT hRes = S_OK;
  140. if(!ppInterface)
  141. {
  142. hRes = E_INVALIDARG;
  143. }
  144. else
  145. {
  146. *ppInterface = NULL;
  147. if(InterfaceID == IID_PRINTEREVENT)
  148. {
  149. *ppInterface = reinterpret_cast<TPrinterEventMgr *>(new TPrinterEventMgr(this));
  150. }
  151. else if(InterfaceID == IID_PRINTUIOPERATIONS)
  152. {
  153. *ppInterface = reinterpret_cast<TPrintUIMgr *>(new TPrintUIMgr(this));
  154. }
  155. else if(InterfaceID == IID_PRINTERCONFIGURATION)
  156. {
  157. *ppInterface = reinterpret_cast<TPrinterCfgMgr *>(new TPrinterCfgMgr(this));
  158. }
  159. else if(InterfaceID == IID_LPCMGR)
  160. {
  161. *ppInterface = reinterpret_cast<TLPCMgr *>(new TLPCMgr(this));
  162. }
  163. else
  164. {
  165. hRes = E_NOINTERFACE;
  166. }
  167. if(*ppInterface)
  168. {
  169. (reinterpret_cast<TRefCntMgr *>(*ppInterface))->AddRef();
  170. }
  171. else
  172. {
  173. hRes = E_OUTOFMEMORY;
  174. }
  175. }
  176. return hRes;
  177. }
  178. /*++
  179. Function Name:
  180. TLoad64BitDllsMgr :: Run
  181. Description:
  182. Creates the object expiration monitoring Thread and starts the
  183. RPC server listening process
  184. Parameters:
  185. None
  186. Return Value:
  187. DWORD RetVal : ERROR_SUCCESS in case of success
  188. ErrorCode in case of failure
  189. --*/
  190. DWORD
  191. TLoad64BitDllsMgr ::
  192. Run(
  193. VOID
  194. )
  195. {
  196. DWORD RetVal = ERROR_SUCCESS;
  197. HANDLE hMonSrvrThrd = NULL;
  198. DWORD MonSrvrThrdId = 0;
  199. //
  200. // Create a Thread which monitors the expiration of this
  201. // process. Expiration means that more than a given amount
  202. // of time , no one requested a service from this surrogate.
  203. //
  204. if(hMonSrvrThrd = CreateThread(NULL,
  205. 0,
  206. MonitorSrvrLifeExpiration,
  207. (PVOID)this,
  208. 0,
  209. &MonSrvrThrdId))
  210. {
  211. //
  212. // SetUp the RPC server and start listening
  213. //
  214. if((RetVal = StartLdrRPCServer()) == RPC_S_OK)
  215. {
  216. WaitForSingleObject(hMonSrvrThrd,INFINITE);
  217. }
  218. CloseHandle(hMonSrvrThrd);
  219. }
  220. else
  221. {
  222. RetVal = GetLastError();
  223. }
  224. return RetVal;
  225. }
  226. /*++
  227. Function Name:
  228. TLoad64BitDllsMgr :: StartldrRPCServer
  229. Description:
  230. This function encapsulates specifying the EndPoints,
  231. the RPC protocol and the Bindings. It also has the
  232. main listening loop for the RPC server.
  233. Parameters:
  234. None
  235. Return Value
  236. DWORD RetVal : ERROR_SUCCESS in case of success
  237. ErrorCode in case of failure
  238. --*/
  239. DWORD
  240. TLoad64BitDllsMgr ::
  241. StartLdrRPCServer(
  242. VOID
  243. )
  244. {
  245. RPC_BINDING_VECTOR *pBindingVector;
  246. RPC_STATUS RpcStatus;
  247. WCHAR szSessionEndPoint[50];
  248. DWORD CurrProcessId = GetCurrentProcessId();
  249. //
  250. // The EndPointName would be the concatenation of
  251. // both the app name and the session ID. Session
  252. // ID is a dword and hence needs max. 10 wchars ,
  253. // App name is "splwow64" which is 8 wchars. So
  254. // the max we might need is 18 whcars. I might
  255. // adjust the buffer size later. This is done
  256. // specially for terminal server because a Window
  257. // handle is not shared between differnet sessions,
  258. // hence we need a process/session
  259. //
  260. StringCchPrintfW(szSessionEndPoint,
  261. 50,
  262. L"%s_%x",
  263. APPNAME,m_CurrSessionId);
  264. if(!(((RpcStatus = RpcServerUseProtseqEp((WCHAR *)L"ncalrpc",
  265. RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
  266. (WCHAR *)szSessionEndPoint,
  267. NULL)) == RPC_S_OK) &&
  268. ((RpcStatus = RpcServerRegisterIf2(Lding64BitDlls_ServerIfHandle,
  269. NULL,
  270. NULL,
  271. 0,
  272. RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
  273. kMaxRPCPacketSize,
  274. NULL)) == RPC_S_OK) &&
  275. ((RpcStatus = RpcServerInqBindings(&pBindingVector)) == RPC_S_OK) &&
  276. ((RpcStatus = RpcBindingVectorFree(&pBindingVector)) == RPC_S_OK) &&
  277. ((RpcStatus = RpcServerRegisterAuthInfo(0,RPC_C_AUTHN_WINNT,0,0 )) == RPC_S_OK) &&
  278. ((RpcStatus = RpcServerListen(1,
  279. RPC_C_LISTEN_MAX_CALLS_DEFAULT,
  280. FALSE)) == RPC_S_OK)))
  281. {
  282. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: StartLdrRPCServer failed with %u\n",RpcStatus));
  283. }
  284. return (DWORD)RpcStatus;
  285. }
  286. /*++
  287. Function Name:
  288. TLoad64BitDllsMgr :: LockSelf
  289. Description:
  290. Locks the object from other threads for
  291. internal data update.
  292. Parameters:
  293. None
  294. Return Value:
  295. None
  296. --*/
  297. VOID
  298. TLoad64BitDllsMgr ::
  299. LockSelf(
  300. VOID
  301. )
  302. {
  303. EnterCriticalSection(&m_LdMgrLock);
  304. }
  305. /*++
  306. Function Name:
  307. TLoad64BitDllsMgr :: ReleaseSelf
  308. Description:
  309. Release the object for use by other Threads
  310. Parameters:
  311. None
  312. Return Value
  313. None
  314. --*/
  315. VOID
  316. TLoad64BitDllsMgr ::
  317. ReleaseSelf(
  318. VOID
  319. )
  320. {
  321. LeaveCriticalSection(&m_LdMgrLock);
  322. }
  323. /*++
  324. Function Name:
  325. TLoad64BitDllsMgr :: RefreshLifeSpan
  326. Description:
  327. Updates the last time @ which the object
  328. was accessed
  329. Parameters:
  330. None
  331. Return Value:
  332. None
  333. --*/
  334. VOID
  335. TLoad64BitDllsMgr ::
  336. RefreshLifeSpan(
  337. VOID
  338. )
  339. {
  340. LockSelf();
  341. {
  342. GetSystemTime(&m_LastTransactionTime);
  343. }
  344. ReleaseSelf();
  345. }
  346. /*++
  347. Function Name:
  348. TLoad64BitDllsMgr :: StillAlive
  349. Description:
  350. This function calculates the difference of
  351. time between the last time the object was
  352. accessed by any connected client and the
  353. current system time
  354. Parameters:
  355. None
  356. Return Value:
  357. BOOL RetVal : TRUE if time delta is <= server expiration time
  358. FALSE if time delta is > server expiration time
  359. --*/
  360. BOOL
  361. TLoad64BitDllsMgr ::
  362. StillAlive(
  363. VOID
  364. )
  365. {
  366. FILETIME FileTime;
  367. FILETIME LocalFileTime;
  368. SYSTEMTIME LocalSystemTime;
  369. BOOL bRetVal = TRUE;
  370. LockSelf();
  371. {
  372. GetSystemTime(&LocalSystemTime);
  373. SystemTimeToFileTime(&LocalSystemTime,&LocalFileTime);
  374. SystemTimeToFileTime(&m_LastTransactionTime,&FileTime);
  375. ULONGLONG TimeDiff = ((ULARGE_INTEGER *)&LocalFileTime)->QuadPart -
  376. ((ULARGE_INTEGER *)&FileTime)->QuadPart;
  377. //
  378. // Since FileTime is calculated as a 100 nanosecond interval
  379. // we have to divide by 10**4 to get the value in meli seconds
  380. //
  381. if((TimeDiff/10000) > m_ExpirationTime)
  382. {
  383. if(GetUIRefCnt())
  384. {
  385. GetSystemTime(&m_LastTransactionTime);
  386. }
  387. else
  388. {
  389. bRetVal = FALSE;
  390. //
  391. // Here we should terminate the Listen loop and kill the
  392. // process, by releasing the listen loop.
  393. //
  394. RpcMgmtStopServerListening(NULL);
  395. }
  396. }
  397. }
  398. ReleaseSelf();
  399. return bRetVal;
  400. }
  401. /*++
  402. Function Name:
  403. TLoad64BitDllsMgr :: StillAlive
  404. Description:
  405. Monitors the expiration of the server and in case of
  406. expiration terminations the RPC server listening loop.
  407. Parameters:
  408. PVOID pData : Pointer to the Loader Object
  409. Return Value:
  410. Always returns 0
  411. --*/
  412. DWORD
  413. TLoad64BitDllsMgr ::
  414. MonitorSrvrLifeExpiration(
  415. IN PVOID pData
  416. )
  417. {
  418. TLoad64BitDllsMgr *pMgrInstance = reinterpret_cast<TLoad64BitDllsMgr *>(pData);
  419. while(pMgrInstance->StillAlive())
  420. {
  421. Sleep(pMgrInstance->m_ExpirationTime);
  422. }
  423. return 0;
  424. }
  425. /*++
  426. Function Name:
  427. TLoad64BitDllsMgr :: IncUIRefCnt
  428. Description:
  429. While poping other components UI , the server process
  430. should never expire and that's why we incerement ref cnt
  431. on UI objects.
  432. Parameters:
  433. None
  434. Return Value:
  435. None
  436. --*/
  437. VOID
  438. TLoad64BitDllsMgr ::
  439. IncUIRefCnt(
  440. VOID
  441. )
  442. {
  443. LockSelf();
  444. {
  445. //
  446. // Since I am already in the critical section,
  447. // I don't need to use InterLocked operations
  448. //
  449. m_UIRefCnt++;
  450. }
  451. ReleaseSelf();
  452. }
  453. /*++
  454. Function Name:
  455. TLoad64BitDllsMgr :: DecUIRefCnt
  456. Description:
  457. We have to dec the ref cnt once the UI returns, in order
  458. to be able to release the process once time expires
  459. Parameters:
  460. None
  461. Return Value:
  462. None
  463. --*/
  464. VOID
  465. TLoad64BitDllsMgr ::
  466. DecUIRefCnt(
  467. VOID
  468. )
  469. {
  470. LockSelf();
  471. {
  472. SPLASSERT(m_UIRefCnt);
  473. //
  474. // Since I am already in the critical section,
  475. // I don't need to use InterLocked operations
  476. //
  477. m_UIRefCnt--;
  478. }
  479. ReleaseSelf();
  480. }
  481. /*++
  482. Function Name:
  483. TLoad64BitDllsMgr :: GetUIRefCnt
  484. Description:
  485. Returns the current number of poped UIs
  486. Parameters:
  487. None
  488. Return Value:
  489. Number of poped UIs
  490. --*/
  491. DWORD
  492. TLoad64BitDllsMgr ::
  493. GetUIRefCnt(
  494. VOID
  495. ) const
  496. {
  497. return m_UIRefCnt;
  498. }
  499. /*++
  500. Function Name:
  501. TLoad64BitDllsMgr :: ExecuteMonitorOperation
  502. Description:
  503. Loads the monitor UI Dll , Initializes the monitor UI ,
  504. determines the required Monitor Operation , and start
  505. the function whcih spins off this operation in a
  506. separate Thread
  507. Parameters:
  508. DWORD hWnd : Windows Handle for parent windows
  509. LPWSTR ServerName : Server Name
  510. LPWSTR UIDllName : The Monitor UI Dll name
  511. LPWSTR Name : Port Name or Monitor Name
  512. PortOp Index : Required Operation
  513. Return Value:
  514. DWORD RetVal : ERROR_SUCCESS in case of success
  515. ErrorCode in case of failure
  516. --*/
  517. BOOL
  518. TLoad64BitDllsMgr ::
  519. ExecuteMonitorOperation(
  520. IN ULONG_PTR hWnd,
  521. IN LPWSTR pszServerName,
  522. IN LPWSTR pszUIDllName,
  523. IN LPWSTR pszName,
  524. IN EPortOp Index,
  525. OUT PDWORD pErrorCode
  526. )
  527. {
  528. PMONITORUI (*pfnInitializePrintMonitorUI)(VOID) = NULL;
  529. RPC_STATUS RpcStatus;
  530. HMODULE hLib = NULL;
  531. HANDLE hActCtx = NULL;
  532. ULONG_PTR lActCtx = 0;
  533. BOOL bActivated = FALSE;
  534. *pErrorCode = ERROR_SUCCESS;
  535. if((RpcStatus = RpcImpersonateClient(0)) == RPC_S_OK)
  536. {
  537. RefreshLifeSpan();
  538. //
  539. // For Fusion, we run the code the gets us the
  540. // monitor UI activation context
  541. //
  542. if((*pErrorCode = this->GetMonitorUIActivationContext(pszUIDllName,&hActCtx,&lActCtx,&bActivated)) == ERROR_SUCCESS)
  543. {
  544. if(hLib = LoadLibrary(pszUIDllName))
  545. {
  546. if(pfnInitializePrintMonitorUI = (PMONITORUI (*)(VOID))
  547. GetProcAddress(hLib, "InitializePrintMonitorUI"))
  548. {
  549. PMONITORUI pMonitorUI;
  550. if(pMonitorUI = (pfnInitializePrintMonitorUI)())
  551. {
  552. LPTHREAD_START_ROUTINE pThrdFn = NULL;
  553. switch (Index)
  554. {
  555. case KAddPortOp:
  556. {
  557. pThrdFn = AddPortUI;
  558. break;
  559. }
  560. case KConfigurePortOp:
  561. case KDeletePortOp:
  562. {
  563. pThrdFn = (Index == KConfigurePortOp) ? ConfigurePortUI : DeletePortUI;
  564. break;
  565. }
  566. }
  567. SPLASSERT(pThrdFn);
  568. *pErrorCode = SpinPortOperationThread((HWND)hWnd,
  569. pszServerName,
  570. pszName,
  571. pMonitorUI,
  572. Index,
  573. pThrdFn,
  574. hLib,
  575. hActCtx,
  576. lActCtx,
  577. bActivated
  578. );
  579. }
  580. else
  581. {
  582. *pErrorCode = GetLastError();
  583. }
  584. }
  585. else
  586. {
  587. *pErrorCode = GetLastError();
  588. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: ExecuteMonitorOperation failed to Load Monitor Initializaiton fn. with %u\n",
  589. *pErrorCode));
  590. }
  591. }
  592. else
  593. {
  594. *pErrorCode = GetLastError();
  595. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: ExecuteMonitorOperation failed to load Monitor UI Dll with %u\n",
  596. *pErrorCode));
  597. }
  598. }
  599. if(*pErrorCode != ERROR_SUCCESS)
  600. {
  601. ReleaseMonitorActivationContext(hLib,hActCtx,lActCtx,bActivated);
  602. }
  603. RpcStatus = RpcRevertToSelf();
  604. }
  605. else
  606. {
  607. *pErrorCode = static_cast<DWORD>(RpcStatus);
  608. }
  609. return *pErrorCode == ERROR_SUCCESS;
  610. }
  611. /*++
  612. Function Name:
  613. TLoad64BitDllsMgr :: SpinPortOperationThread
  614. Description:
  615. Spins the appropriate monitor operation in a separate thread
  616. Parameters:
  617. HWND hWnd : Windows Handle for parent windows
  618. LPWSTR ServerName : Server Name
  619. LPWSTR UIDllName : The Monitor UI Dll name
  620. LPWSTR Name : Port Name or Monitor Name
  621. PortOp Index : Required Operation
  622. PMONITORUI pMonitorUI : Port Monitor Functions
  623. LPTHREAD_START_ROUTINE pThrdFn : Internal Thread to be executed
  624. Return Value:
  625. DWORD RetVal : ERROR_SUCCESS in case of success
  626. ErrorCode in case of failure
  627. --*/
  628. DWORD
  629. TLoad64BitDllsMgr ::
  630. SpinPortOperationThread(
  631. IN HWND hWnd,
  632. IN LPWSTR pszServerName,
  633. IN LPWSTR pszName,
  634. IN PMONITORUI pMonitorUI,
  635. IN EPortOp Index,
  636. IN LPTHREAD_START_ROUTINE pThrdFn,
  637. IN HMODULE hLib,
  638. IN HANDLE hActCtx,
  639. IN ULONG_PTR lActCtx,
  640. IN BOOL bActivated
  641. ) const
  642. {
  643. DWORD UIThrdId = 0;
  644. HANDLE hUIThrd = NULL;
  645. DWORD RetVal = ERROR_SUCCESS;
  646. SPortAddThreadData *pNewThreadData = NULL;
  647. if(pNewThreadData = new SPortAddThreadData)
  648. {
  649. switch (Index)
  650. {
  651. case KAddPortOp:
  652. {
  653. pNewThreadData->pMonFnAdd = pMonitorUI->pfnAddPortUI;
  654. pNewThreadData->pMonFns = NULL;
  655. pNewThreadData->pszMonitorName = pszName;
  656. pNewThreadData->pszPortName = NULL;
  657. break;
  658. }
  659. case KConfigurePortOp:
  660. case KDeletePortOp:
  661. {
  662. PFNMONITORFNS pfnMonitorsFns[2];
  663. pfnMonitorsFns[0] = pMonitorUI->pfnConfigurePortUI;
  664. pfnMonitorsFns[1] = pMonitorUI->pfnDeletePortUI;
  665. pNewThreadData->pMonFnAdd = NULL;
  666. pNewThreadData->pMonFns = pfnMonitorsFns[Index];
  667. pNewThreadData->pszMonitorName = NULL;
  668. pNewThreadData->pszPortName = pszName;
  669. break;
  670. }
  671. }
  672. pNewThreadData->hWnd = hWnd;
  673. pNewThreadData->pszServerName = pszServerName;
  674. pNewThreadData->ppszRetPortName = NULL;
  675. pNewThreadData->hLib = hLib;
  676. pNewThreadData->hActCtx = hActCtx;
  677. pNewThreadData->lActCtx = lActCtx;
  678. pNewThreadData->bActivated = bActivated;
  679. if(!(hUIThrd = CreateThread(NULL,
  680. 0,
  681. pThrdFn,
  682. (PVOID)pNewThreadData,
  683. 0,
  684. &UIThrdId)))
  685. {
  686. RetVal = GetLastError();
  687. delete pNewThreadData;
  688. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: SpinPortOperationThread failed to create Port Operation fn. with %u\n",
  689. RetVal));
  690. }
  691. else
  692. {
  693. CloseHandle(hUIThrd);
  694. }
  695. }
  696. else
  697. {
  698. RetVal = ERROR_OUTOFMEMORY;
  699. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: SpinPortOperationThread failed to allocate required memory with %u\n",
  700. RetVal));
  701. }
  702. return RetVal;
  703. }
  704. /*++
  705. Function Name:
  706. TLoad64BitDllsMgr :: AddPortUI
  707. Description:
  708. Calls the monitor AddPort
  709. Parameters:
  710. PVOID InThrdData : Thread Data for Adding a Port
  711. Return Value:
  712. Always 0
  713. --*/
  714. DWORD
  715. TLoad64BitDllsMgr ::
  716. AddPortUI(
  717. IN PVOID pInThrdData
  718. )
  719. {
  720. DWORD RetVal = ERROR_SUCCESS;
  721. HANDLE hMsgThrd;
  722. DWORD MsgThrdId;
  723. SPortAddThreadData *pNewThreadData = reinterpret_cast<SPortAddThreadData *>(pInThrdData);
  724. pGLdrObj->IncUIRefCnt();
  725. {
  726. RetVal = (DWORD) pNewThreadData->pMonFnAdd(pNewThreadData->pszServerName,
  727. pNewThreadData->hWnd,
  728. pNewThreadData->pszMonitorName,
  729. NULL);
  730. }
  731. pGLdrObj->DecUIRefCnt();
  732. //
  733. // Here we should post a message to the caller client window to inform
  734. // it that the operation was completed and also whether it was succesful
  735. // or not
  736. //
  737. PostMessage(pNewThreadData->hWnd,WM_ENDADDPORT,
  738. (WPARAM)RetVal,
  739. (RetVal != ERROR_SUCCESS) ? ERROR_SUCCESS : (DWORD)GetLastError());
  740. pGLdrObj->ReleaseMonitorActivationContext(pNewThreadData->hLib,
  741. pNewThreadData->hActCtx,
  742. pNewThreadData->lActCtx,
  743. pNewThreadData->bActivated);
  744. delete pInThrdData;
  745. return 0;
  746. }
  747. /*++
  748. Function Name:
  749. TLoad64BitDllsMgr :: DeletePortUI
  750. Description:
  751. Calls the monitor DeletePort
  752. Parameters:
  753. PVOID InThrdData : Thread Data for Adding a Port
  754. Return Value:
  755. Always 0
  756. --*/
  757. DWORD
  758. TLoad64BitDllsMgr ::
  759. DeletePortUI(
  760. IN PVOID pInThrdData
  761. )
  762. {
  763. DWORD RetVal = ERROR_SUCCESS;
  764. SPortAddThreadData *pNewThreadData = reinterpret_cast<SPortAddThreadData *>(pInThrdData);
  765. pGLdrObj->IncUIRefCnt();
  766. {
  767. RetVal = (DWORD) pNewThreadData->pMonFns(pNewThreadData->pszServerName,
  768. pNewThreadData->hWnd,
  769. pNewThreadData->pszPortName);
  770. }
  771. pGLdrObj->DecUIRefCnt();
  772. //
  773. // Here we should post a message to the caller window to inform them
  774. // the operation was completed and also whether it was succesful or
  775. // not
  776. //
  777. PostMessage(pNewThreadData->hWnd,WM_ENDDELPORT,
  778. (WPARAM)RetVal,
  779. (RetVal != ERROR_SUCCESS) ? ERROR_SUCCESS : (DWORD)GetLastError());
  780. pGLdrObj->ReleaseMonitorActivationContext(pNewThreadData->hLib,
  781. pNewThreadData->hActCtx,
  782. pNewThreadData->lActCtx,
  783. pNewThreadData->bActivated);
  784. delete pInThrdData;
  785. return 0;
  786. }
  787. /*++
  788. Function Name:
  789. TLoad64BitDllsMgr :: ConfigurePortUI
  790. Description:
  791. Calls the monitor ConfigurePort
  792. Parameters:
  793. PVOID InThrdData : Thread Data for Adding a Port
  794. Return Value:
  795. Always 0
  796. --*/
  797. DWORD
  798. TLoad64BitDllsMgr ::
  799. ConfigurePortUI(
  800. IN PVOID pInThrdData
  801. )
  802. {
  803. DWORD RetVal = ERROR_SUCCESS;
  804. SPortAddThreadData *pNewThreadData = reinterpret_cast<SPortAddThreadData *>(pInThrdData);
  805. pGLdrObj->IncUIRefCnt();
  806. {
  807. RetVal = (DWORD) pNewThreadData->pMonFns(pNewThreadData->pszServerName,
  808. pNewThreadData->hWnd,
  809. pNewThreadData->pszPortName);
  810. }
  811. pGLdrObj->DecUIRefCnt();
  812. //
  813. // Here we should post a message to the caller window to inform them
  814. // the operation was completed and also whether it was succesful or
  815. // not
  816. //
  817. PostMessage(pNewThreadData->hWnd,WM_ENDCFGPORT,
  818. (WPARAM)RetVal,
  819. (RetVal != ERROR_SUCCESS) ? ERROR_SUCCESS : (DWORD)GetLastError());
  820. pGLdrObj->ReleaseMonitorActivationContext(pNewThreadData->hLib,
  821. pNewThreadData->hActCtx,
  822. pNewThreadData->lActCtx,
  823. pNewThreadData->bActivated);
  824. delete pInThrdData;
  825. return 0;
  826. }
  827. /*++
  828. Function Name:
  829. TLoad64BitDllsMgr :: DeviceCapabilities
  830. Description:
  831. Queries the Device capabilities , by calling into
  832. the driver
  833. Parameters:
  834. LPWSTR DeviceName : Device Name
  835. LPWSTR PortName : Port Name
  836. WORD Capabilities : Required Capabilites to Query for
  837. DWORD DevModeSize : Input DevMode Size
  838. LPBYTE DevMode : Input DevMode
  839. BOOL ClonedOutputFill : Required To fill output DevMode
  840. PDWORD ClonedOutputSize : Output DevMode size
  841. LPBYTE* ClonedOutput : Output DevMode
  842. Return Value:
  843. int RetVal : -1 in case of Failure
  844. : Some value depending on Capabilities flag in case
  845. of Success
  846. --*/
  847. int
  848. TLoad64BitDllsMgr ::
  849. DeviceCapabilities(
  850. IN LPWSTR pszDeviceName,
  851. IN LPWSTR pszPortName,
  852. IN WORD Capabilities,
  853. IN DWORD DevModeSize,
  854. IN LPBYTE pDevMode,
  855. IN BOOL bClonedOutputFill,
  856. OUT PDWORD pClonedOutputSize,
  857. OUT LPBYTE *ppClonedOutput,
  858. OUT PDWORD pErrorCode
  859. )
  860. {
  861. HANDLE hPrinter = NULL;
  862. HANDLE hDriver = NULL;
  863. INT ReturnValue = -1;
  864. INT_FARPROC pfn;
  865. LPWSTR pszDriverFileName;
  866. RPC_STATUS RpcStatus;
  867. pGLdrObj->IncUIRefCnt();
  868. {
  869. if((RpcStatus = RpcImpersonateClient(0)) == RPC_S_OK)
  870. {
  871. if (OpenPrinter((LPWSTR)pszDeviceName, &hPrinter, NULL))
  872. {
  873. if(hDriver = LoadPrinterDriver(hPrinter))
  874. {
  875. if (pfn = (INT_FARPROC)GetProcAddress(hDriver,
  876. "DrvDeviceCapabilities"))
  877. {
  878. __try
  879. {
  880. *ppClonedOutput = NULL;
  881. ReturnValue = (*pfn)(hPrinter,
  882. pszDeviceName,
  883. Capabilities,
  884. (PVOID)*ppClonedOutput,
  885. (PDEVMODE)pDevMode);
  886. if(ReturnValue != -1 &&
  887. ReturnValue != 0 &&
  888. bClonedOutputFill &&
  889. DevCapFillsOutput(Capabilities))
  890. {
  891. if(*ppClonedOutput = new BYTE[*pClonedOutputSize = CalcReqSizeForDevCaps(ReturnValue,
  892. Capabilities)])
  893. {
  894. ZeroMemory(*ppClonedOutput,*pClonedOutputSize);
  895. if((ReturnValue = (*pfn)(hPrinter,
  896. pszDeviceName,
  897. Capabilities,
  898. (PVOID)*ppClonedOutput,
  899. (PDEVMODE)pDevMode)) == -1)
  900. {
  901. *pErrorCode = GetLastError();
  902. }
  903. }
  904. else
  905. {
  906. ReturnValue = -1;
  907. *pErrorCode = ERROR_OUTOFMEMORY;
  908. }
  909. }
  910. if(!ReturnValue)
  911. {
  912. *pErrorCode = GetLastError();
  913. }
  914. }
  915. __except(1)
  916. {
  917. SetLastError(GetExceptionCode());
  918. ReturnValue = -1;
  919. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: DeviceCapabilities failed to allocate memory"));
  920. }
  921. }
  922. FreeLibrary(hDriver);
  923. }
  924. else
  925. { *pErrorCode = GetLastError();
  926. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: DeviceCapabilities failed to load driver with %u\n",
  927. *pErrorCode));
  928. }
  929. ClosePrinter(hPrinter);
  930. }
  931. else
  932. {
  933. *pErrorCode = GetLastError();
  934. DBGMSG(DBG_WARN, ("TLoad64BitDllsMgr :: DeviceCapabilities failed to open printer with %u\n",
  935. *pErrorCode));
  936. }
  937. RpcStatus = RpcRevertToSelf();
  938. }
  939. else
  940. {
  941. *pErrorCode = RpcStatus;
  942. }
  943. }
  944. pGLdrObj->DecUIRefCnt();
  945. return ReturnValue;
  946. }
  947. /*++
  948. Function Name:
  949. TLoad64BitDllsMgr :: DevCapFillsOutput
  950. Description:
  951. Does the capability fill out an out buffer or not
  952. Parameters:
  953. DWORD Capabilites : The required Capability
  954. Return Value:
  955. BOOL : 1 OR 0
  956. --*/
  957. BOOL
  958. TLoad64BitDllsMgr ::
  959. DevCapFillsOutput(
  960. IN DWORD Capabilities
  961. ) const
  962. {
  963. SPLASSERT(Capabilities>0 && Capabilities<= DC_NUP);
  964. return(!!DeviceCapsReqSize[Capabilities-1]);
  965. }
  966. /*++
  967. Function Name:
  968. TLoad64BitDllsMgr :: CalcReqSizeForDevCaps
  969. Description:
  970. Given the required capability returns the size required
  971. for all enumerated values of it
  972. Parameters:
  973. DWORD CapNum : Num Of Items for given Capability
  974. DWORD Capabilites : The required Capability
  975. Return Value:
  976. DWORD : Required size to store all items of capability
  977. --*/
  978. DWORD
  979. TLoad64BitDllsMgr ::
  980. CalcReqSizeForDevCaps(
  981. IN DWORD CapNum,
  982. IN DWORD Capabilities
  983. ) const
  984. {
  985. SPLASSERT(Capabilities>0 && Capabilities<= DC_NUP);
  986. return((Capabilities && DeviceCapsReqSize[Capabilities-1]) ?
  987. (CapNum * DeviceCapsReqSize[Capabilities-1]) :
  988. CapNum);
  989. }
  990. /*++
  991. Function Name:
  992. TLoad64BitDllsMgr :: DocumentProperties
  993. Description:
  994. Displays the driver specific properties
  995. Parameters:
  996. HWND hWnd : Parent Window Handle
  997. LPWSTR PrinterName : Printer Name
  998. PDWORD ClonedDevModeOutSize : Output DevMode size
  999. LPBYTE* ClonedDevModeOut : Output DevMode
  1000. DWORD DevModeSize : Input DevMode Size
  1001. LPBYTE DevMode : Input DevMode
  1002. WORD Capabilities : Required Capabilites to Query for
  1003. BOOL ClonedDevModeOutFill : Required To fill output DevMode
  1004. DWORD fMode : Mode Options
  1005. Return Value:
  1006. int RetVal : -1 in case of Failure
  1007. : Some value depending on fMode flag and DevModes
  1008. and this might be posted to the client window in
  1009. case of running asynchronously
  1010. --*/
  1011. LONG
  1012. TLoad64BitDllsMgr ::
  1013. DocumentProperties(
  1014. IN ULONG_PTR hWnd,
  1015. IN LPWSTR pszPrinterName,
  1016. OUT PDWORD pTouchedDevModeSize,
  1017. OUT PDWORD pClonedDevModeOutSize,
  1018. OUT LPBYTE *ppClonedDevModeOut,
  1019. IN DWORD DevModeSize,
  1020. IN LPBYTE pDevMode,
  1021. IN BOOL bClonedDevModeOutFill,
  1022. IN DWORD fMode,
  1023. OUT PDWORD pErrorCode
  1024. )
  1025. {
  1026. LONG RetVal = -1;
  1027. SDocPropsThreadData *pNewThrdData = NULL;
  1028. RPC_STATUS RpcStatus;
  1029. if((RpcStatus = RpcImpersonateClient(0)) == RPC_S_OK)
  1030. {
  1031. RefreshLifeSpan();
  1032. if(pNewThrdData = new SDocPropsThreadData)
  1033. {
  1034. pNewThrdData->hWnd = (HWND)hWnd;
  1035. pNewThrdData->pszPrinterName = pszPrinterName;
  1036. pNewThrdData->pClonedDevModeOutSize = pClonedDevModeOutSize;
  1037. pNewThrdData->pTouchedDevModeSize = pTouchedDevModeSize;
  1038. pNewThrdData->ppClonedDevModeOut = ppClonedDevModeOut;
  1039. pNewThrdData->DevModeSize = DevModeSize;
  1040. pNewThrdData->pDevMode = pDevMode;
  1041. pNewThrdData->bClonedDevModeOutFill = bClonedDevModeOutFill;
  1042. pNewThrdData->fMode = fMode;
  1043. pNewThrdData->fExclusionFlags = 0;
  1044. pNewThrdData->ErrorCode = ERROR_SUCCESS;
  1045. pNewThrdData->RetVal = -1;
  1046. InternalDocumentProperties((PVOID)pNewThrdData);
  1047. RetVal = pNewThrdData->RetVal;
  1048. *pErrorCode = pNewThrdData->ErrorCode;
  1049. delete pNewThrdData;
  1050. }
  1051. RpcStatus = RpcRevertToSelf();
  1052. }
  1053. else
  1054. {
  1055. *pErrorCode = RpcStatus;
  1056. }
  1057. return RetVal;
  1058. }
  1059. /*++
  1060. Function Name:
  1061. TLoad64BitDllsMgr :: AsyncDocumentProperties
  1062. Description:
  1063. Displays the driver specific UI in a separate sheet
  1064. Parameters:
  1065. PVOID : Thread Data
  1066. Return Value:
  1067. Always returns 0
  1068. --*/
  1069. DWORD
  1070. TLoad64BitDllsMgr ::
  1071. InternalDocumentProperties(
  1072. PVOID pInThrdData
  1073. )
  1074. {
  1075. DOCUMENTPROPERTYHEADER DPHdr;
  1076. HANDLE hPrinter = NULL;
  1077. SDocPropsThreadData *pNewThreadData = reinterpret_cast<SDocPropsThreadData *>(pInThrdData);
  1078. TLoad64BitDllsMgr *pMgrInstance = pNewThreadData->pMgrInstance;
  1079. HWND hWnd = pNewThreadData->hWnd;
  1080. LPWSTR pszPrinterName = pNewThreadData->pszPrinterName;
  1081. PDWORD pClonedDevModeOutSize = pNewThreadData->pClonedDevModeOutSize;
  1082. PDWORD pTouchedDevModeSize = pNewThreadData->pTouchedDevModeSize;
  1083. LPBYTE* ppClonedDevModeOut = pNewThreadData->ppClonedDevModeOut;
  1084. DWORD DevModeSize = pNewThreadData->DevModeSize;
  1085. LPBYTE pDevMode = pNewThreadData->pDevMode;
  1086. BOOL bClonedDevModeOutFill = pNewThreadData->bClonedDevModeOutFill;
  1087. DWORD fMode = pNewThreadData->fMode;
  1088. HMODULE hWinSpool = NULL;
  1089. PFNDOCPROPSHEETS pfnDocPropSheets = NULL;
  1090. LONG Result = -1;
  1091. LONG cbOut = 0;
  1092. pGLdrObj->IncUIRefCnt();
  1093. {
  1094. if(hWinSpool = LoadLibrary(L"winspool.drv"))
  1095. {
  1096. if(pfnDocPropSheets = reinterpret_cast<PFNDOCPROPSHEETS>(GetProcAddress(hWinSpool,
  1097. "DocumentPropertySheets")))
  1098. {
  1099. if(OpenPrinter(pszPrinterName,&hPrinter,NULL))
  1100. {
  1101. //
  1102. // Do I need to protect the printer handle ?????
  1103. //
  1104. DPHdr.cbSize = sizeof(DPHdr);
  1105. DPHdr.Reserved = 0;
  1106. DPHdr.hPrinter = hPrinter;
  1107. DPHdr.pszPrinterName = pszPrinterName;
  1108. if(bClonedDevModeOutFill)
  1109. {
  1110. DPHdr.pdmIn = NULL;
  1111. DPHdr.pdmOut = NULL;
  1112. DPHdr.fMode = 0;
  1113. cbOut = pfnDocPropSheets(NULL, (LPARAM)&DPHdr);
  1114. //
  1115. // The function returns zero or a negative number when it fails.
  1116. //
  1117. if (cbOut > 0)
  1118. {
  1119. DPHdr.cbOut = cbOut;
  1120. if(*ppClonedDevModeOut = new BYTE[DPHdr.cbOut])
  1121. {
  1122. ZeroMemory(*ppClonedDevModeOut, DPHdr.cbOut);
  1123. }
  1124. }
  1125. else
  1126. {
  1127. DPHdr.cbOut = 0;
  1128. *ppClonedDevModeOut = NULL;
  1129. }
  1130. }
  1131. else
  1132. {
  1133. DPHdr.cbOut = 0;
  1134. *ppClonedDevModeOut = NULL;
  1135. }
  1136. *pClonedDevModeOutSize = DPHdr.cbOut;
  1137. DPHdr.pdmIn = (PDEVMODE)pDevMode;
  1138. DPHdr.pdmOut = (PDEVMODE)*ppClonedDevModeOut;
  1139. DPHdr.fMode = fMode;
  1140. if (fMode & DM_PROMPT)
  1141. {
  1142. PFNCALLCOMMONPROPSHEETUI pfnCallCommonPropSheeUI = NULL;
  1143. Result = CPSUI_CANCEL;
  1144. if(pfnCallCommonPropSheeUI= reinterpret_cast<PFNCALLCOMMONPROPSHEETUI>(GetProcAddress(hWinSpool,
  1145. (LPCSTR) MAKELPARAM(218, 0))))
  1146. {
  1147. pGLdrObj->IncUIRefCnt();
  1148. if(pfnCallCommonPropSheeUI(hWnd,
  1149. pfnDocPropSheets,
  1150. (LPARAM)&DPHdr,
  1151. (LPDWORD)&Result) < 0)
  1152. {
  1153. Result = -1;
  1154. pNewThreadData->ErrorCode = GetLastError();
  1155. }
  1156. else
  1157. {
  1158. Result = (Result == CPSUI_OK) ? IDOK : IDCANCEL;
  1159. }
  1160. pGLdrObj->DecUIRefCnt();
  1161. }
  1162. else
  1163. {
  1164. Result = -1;
  1165. pNewThreadData->ErrorCode = GetLastError();
  1166. }
  1167. }
  1168. else
  1169. {
  1170. Result = pfnDocPropSheets(NULL, (LPARAM)&DPHdr);
  1171. if(Result<0)
  1172. {
  1173. pNewThreadData->ErrorCode = GetLastError();
  1174. }
  1175. }
  1176. //
  1177. // Here we try to adjust the required memory . Sometimes it is less
  1178. //
  1179. if((PDEVMODE)*ppClonedDevModeOut)
  1180. {
  1181. if((DWORD)(((PDEVMODE)*ppClonedDevModeOut)->dmSize +
  1182. ((PDEVMODE)*ppClonedDevModeOut)->dmDriverExtra) <
  1183. *pClonedDevModeOutSize)
  1184. {
  1185. *pTouchedDevModeSize = (((PDEVMODE)*ppClonedDevModeOut)->dmSize +
  1186. ((PDEVMODE)*ppClonedDevModeOut)->dmDriverExtra);
  1187. }
  1188. else
  1189. {
  1190. *pTouchedDevModeSize = *pClonedDevModeOutSize;
  1191. }
  1192. }
  1193. if(hPrinter)
  1194. {
  1195. ClosePrinter(hPrinter);
  1196. }
  1197. }
  1198. else
  1199. {
  1200. pNewThreadData->ErrorCode = GetLastError();
  1201. }
  1202. }
  1203. else
  1204. {
  1205. pNewThreadData->ErrorCode = GetLastError();
  1206. }
  1207. FreeLibrary(hWinSpool);
  1208. }
  1209. else
  1210. {
  1211. pNewThreadData->ErrorCode = GetLastError();
  1212. }
  1213. if(hWnd && (fMode & DM_PROMPT))
  1214. {
  1215. PostMessage(pNewThreadData->hWnd,WM_ENDDOCUMENTPROPERTIES,
  1216. (WPARAM)Result,
  1217. (LPARAM)pNewThreadData->ErrorCode);
  1218. }
  1219. pNewThreadData->RetVal = Result;
  1220. }
  1221. pGLdrObj->DecUIRefCnt();
  1222. return 0;
  1223. }
  1224. /*++
  1225. Function Name:
  1226. TLoad64BitDllsMgr :: PrinUIDocumentProperties
  1227. Description:
  1228. Displays the driver specific properties
  1229. Parameters:
  1230. HWND hWnd : Parent Window Handle
  1231. LPWSTR PrinterName : Printer Name
  1232. PDWORD ClonedDevModeOutSize : Output DevMode size
  1233. LPBYTE* ClonedDevModeOut : Output DevMode
  1234. DWORD DevModeSize : Input DevMode Size
  1235. LPBYTE DevMode : Input DevMode
  1236. WORD Capabilities : Required Capabilites to Query for
  1237. BOOL ClonedDevModeOutFill : Required To fill output DevMode
  1238. DWORD fMode : Mode Options
  1239. Return Value:
  1240. int RetVal : -1 in case of Failure
  1241. : Some value depending on fMode flag and DevModes
  1242. and this might be posted to the client window in
  1243. case of running asynchronously
  1244. --*/
  1245. LONG
  1246. TLoad64BitDllsMgr ::
  1247. PrintUIDocumentProperties(
  1248. IN ULONG_PTR hWnd,
  1249. IN LPWSTR pszPrinterName,
  1250. OUT PDWORD pTouchedDevModeSize,
  1251. OUT PDWORD pClonedDevModeOutSize,
  1252. OUT LPBYTE *ppClonedDevModeOut,
  1253. IN DWORD DevModeSize,
  1254. IN LPBYTE pDevMode,
  1255. IN BOOL bClonedDevModeOutFill,
  1256. IN DWORD fMode,
  1257. IN DWORD fExclusionFlags,
  1258. OUT PDWORD pErrorCode
  1259. )
  1260. {
  1261. LONG RetVal = -1;
  1262. SDocPropsThreadData *pNewThrdData = NULL;
  1263. RPC_STATUS RpcStatus;
  1264. if((RpcStatus = RpcImpersonateClient(0)) == RPC_S_OK)
  1265. {
  1266. RefreshLifeSpan();
  1267. if(pNewThrdData = new SDocPropsThreadData)
  1268. {
  1269. pNewThrdData->hWnd = (HWND)hWnd;
  1270. pNewThrdData->pszPrinterName = pszPrinterName;
  1271. pNewThrdData->pClonedDevModeOutSize = pClonedDevModeOutSize;
  1272. pNewThrdData->pTouchedDevModeSize = pTouchedDevModeSize;
  1273. pNewThrdData->ppClonedDevModeOut = ppClonedDevModeOut;
  1274. pNewThrdData->DevModeSize = DevModeSize;
  1275. pNewThrdData->pDevMode = pDevMode;
  1276. pNewThrdData->bClonedDevModeOutFill = bClonedDevModeOutFill;
  1277. pNewThrdData->fMode = fMode;
  1278. pNewThrdData->fExclusionFlags = fExclusionFlags;
  1279. pNewThrdData->ErrorCode = ERROR_SUCCESS;
  1280. pNewThrdData->RetVal = -1;
  1281. InternalPrintUIDocumentProperties((PVOID)pNewThrdData);
  1282. RetVal = pNewThrdData->RetVal;
  1283. *pErrorCode = pNewThrdData->ErrorCode;
  1284. delete pNewThrdData;
  1285. }
  1286. RpcStatus = RpcRevertToSelf();
  1287. }
  1288. else
  1289. {
  1290. *pErrorCode = RpcStatus;
  1291. }
  1292. return RetVal;
  1293. }
  1294. /*++
  1295. Function Name:
  1296. TLoad64BitDllsMgr :: AsyncDocumentProperties
  1297. Description:
  1298. Displays the driver specific UI in a separate sheet
  1299. Parameters:
  1300. PVOID : Thread Data
  1301. Return Value:
  1302. Always returns 0
  1303. --*/
  1304. DWORD
  1305. TLoad64BitDllsMgr ::
  1306. InternalPrintUIDocumentProperties(
  1307. PVOID pInThrdData
  1308. )
  1309. {
  1310. DOCUMENTPROPERTYHEADER DPHdr;
  1311. HANDLE hPrinter = NULL;
  1312. SDocPropsThreadData *pNewThreadData = reinterpret_cast<SDocPropsThreadData *>(pInThrdData);
  1313. TLoad64BitDllsMgr *pMgrInstance = pNewThreadData->pMgrInstance;
  1314. HWND hWnd = pNewThreadData->hWnd;
  1315. LPWSTR pszPrinterName = pNewThreadData->pszPrinterName;
  1316. PDWORD pClonedDevModeOutSize = pNewThreadData->pClonedDevModeOutSize;
  1317. PDWORD pTouchedDevModeSize = pNewThreadData->pTouchedDevModeSize;
  1318. LPBYTE* ppClonedDevModeOut = pNewThreadData->ppClonedDevModeOut;
  1319. DWORD DevModeSize = pNewThreadData->DevModeSize;
  1320. LPBYTE pDevMode = pNewThreadData->pDevMode;
  1321. BOOL bClonedDevModeOutFill = pNewThreadData->bClonedDevModeOutFill;
  1322. DWORD fMode = pNewThreadData->fMode;
  1323. DWORD fExclusionFlags = pNewThreadData->fExclusionFlags;
  1324. HMODULE hWinSpool = NULL;
  1325. PFNDOCPROPSHEETS pfnDocPropSheets = NULL;
  1326. LONG Result = -1;
  1327. pGLdrObj->IncUIRefCnt();
  1328. {
  1329. if(hWinSpool = LoadLibrary(L"winspool.drv"))
  1330. {
  1331. if(pfnDocPropSheets = reinterpret_cast<PFNDOCPROPSHEETS>(GetProcAddress(hWinSpool,
  1332. "DocumentPropertySheets")))
  1333. {
  1334. if(OpenPrinter(pszPrinterName,&hPrinter,NULL))
  1335. {
  1336. DPHdr.cbSize = sizeof(DPHdr);
  1337. DPHdr.Reserved = 0;
  1338. DPHdr.hPrinter = hPrinter;
  1339. DPHdr.pszPrinterName = pszPrinterName;
  1340. if(bClonedDevModeOutFill)
  1341. {
  1342. DPHdr.pdmIn = NULL;
  1343. DPHdr.pdmOut = NULL;
  1344. DPHdr.fMode = 0;
  1345. DPHdr.cbOut = pfnDocPropSheets(NULL,
  1346. (LPARAM)&DPHdr);
  1347. *ppClonedDevModeOut = new BYTE[DPHdr.cbOut];
  1348. }
  1349. else
  1350. {
  1351. DPHdr.cbOut = 0;
  1352. *ppClonedDevModeOut = NULL;
  1353. }
  1354. *pClonedDevModeOutSize = DPHdr.cbOut;
  1355. PFNPRINTUIDOCUMENTPROPERTIES pfnPrintUIDocumentProperties = NULL;
  1356. HMODULE hPrintUI = NULL;
  1357. if(hPrintUI = LoadLibrary(L"printui.dll"))
  1358. {
  1359. if(pfnPrintUIDocumentProperties = reinterpret_cast<PFNPRINTUIDOCUMENTPROPERTIES>(GetProcAddress(hPrintUI,
  1360. "DocumentPropertiesWrap")))
  1361. {
  1362. pGLdrObj->IncUIRefCnt();
  1363. Result = pfnPrintUIDocumentProperties(hWnd,
  1364. hPrinter,
  1365. pszPrinterName,
  1366. (PDEVMODE)*ppClonedDevModeOut,
  1367. (PDEVMODE)pDevMode,
  1368. fMode,
  1369. fExclusionFlags
  1370. );
  1371. pNewThreadData->ErrorCode = GetLastError();
  1372. pGLdrObj->DecUIRefCnt();
  1373. //
  1374. // Here we try to adjust the required memory . Sometimes it is less
  1375. //
  1376. if((PDEVMODE)*ppClonedDevModeOut)
  1377. {
  1378. if((DWORD)(((PDEVMODE)*ppClonedDevModeOut)->dmSize +
  1379. ((PDEVMODE)*ppClonedDevModeOut)->dmDriverExtra) <
  1380. *pClonedDevModeOutSize)
  1381. {
  1382. *pTouchedDevModeSize = (((PDEVMODE)*ppClonedDevModeOut)->dmSize +
  1383. ((PDEVMODE)*ppClonedDevModeOut)->dmDriverExtra);
  1384. }
  1385. else
  1386. {
  1387. *pTouchedDevModeSize = *pClonedDevModeOutSize;
  1388. }
  1389. }
  1390. }
  1391. FreeLibrary(hPrintUI);
  1392. }
  1393. if(hPrinter)
  1394. {
  1395. ClosePrinter(hPrinter);
  1396. }
  1397. }
  1398. else
  1399. {
  1400. pNewThreadData->ErrorCode = GetLastError();
  1401. }
  1402. }
  1403. else
  1404. {
  1405. pNewThreadData->ErrorCode = GetLastError();
  1406. }
  1407. FreeLibrary(hWinSpool);
  1408. }
  1409. else
  1410. {
  1411. pNewThreadData->ErrorCode = GetLastError();
  1412. }
  1413. if(hWnd)
  1414. {
  1415. PostMessage(pNewThreadData->hWnd,WM_ENDPRINTUIDOCUMENTPROPERTIES,
  1416. (WPARAM)Result,
  1417. (LPARAM)pNewThreadData->ErrorCode);
  1418. }
  1419. pNewThreadData->RetVal = Result;
  1420. }
  1421. pGLdrObj->DecUIRefCnt();
  1422. return 0;
  1423. }
  1424. /*++
  1425. Function Name:
  1426. TLoad64BitDllsMgr :: GetCurrSeesionId
  1427. Description:
  1428. returns the Current Session ID for terminal server
  1429. sessions
  1430. Parameters:
  1431. None
  1432. Return Value:
  1433. DWORD: Session ID
  1434. --*/
  1435. DWORD
  1436. TLoad64BitDllsMgr ::
  1437. GetCurrSessionId() const
  1438. {
  1439. return m_CurrSessionId;
  1440. }
  1441. /*++
  1442. Function Name:
  1443. TLoad64BitDllsMgr :: GetMonitorUIActivationContext
  1444. Description:
  1445. This routine gets the monitor UI activation context and then
  1446. activates the context. If the monitor does not have an activation
  1447. context in it's resource file it will activate the empty context
  1448. for compatiblity with previous version of common control.
  1449. Parameters:
  1450. pszUIDllName - The name of the monitor ui DLL.
  1451. phActCtx - Pointer to the activation context handle
  1452. Return Value:
  1453. DWORD: Error Code if any else ERROR_SUCCESS
  1454. --*/
  1455. DWORD
  1456. TLoad64BitDllsMgr ::
  1457. GetMonitorUIActivationContext(
  1458. IN LPWSTR pszUIDllName,
  1459. IN OUT HANDLE *phActCtx,
  1460. IN OUT ULONG_PTR *plActCtx,
  1461. IN OUT BOOL *pbActivated
  1462. ) const
  1463. {
  1464. DWORD ErrorCode = ERROR_SUCCESS;
  1465. LPWSTR pszFullPath = NULL;
  1466. if(!pszUIDllName)
  1467. {
  1468. ErrorCode = ERROR_INVALID_PARAMETER;
  1469. }
  1470. else
  1471. {
  1472. if(pszFullPath = new WCHAR[MAX_PATH])
  1473. {
  1474. ZeroMemory(pszFullPath,MAX_PATH*sizeof(WCHAR));
  1475. if((ErrorCode = this->GetMonitorUIFullPath(pszUIDllName,pszFullPath)) == ERROR_SUCCESS)
  1476. {
  1477. ACTCTX ActCtx;
  1478. ZeroMemory(&ActCtx, sizeof(ActCtx));
  1479. ActCtx.cbSize = sizeof(ActCtx);
  1480. ActCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  1481. ActCtx.lpSource = pszFullPath;
  1482. ActCtx.lpResourceName = MAKEINTRESOURCE(ACTIVATION_CONTEXT_RESOURCE_ID);
  1483. if((*phActCtx = CreateActCtx(&ActCtx)) == INVALID_HANDLE_VALUE)
  1484. {
  1485. *phActCtx = ACTCTX_EMPTY;
  1486. if(!ActivateActCtx(*phActCtx,plActCtx))
  1487. {
  1488. ErrorCode = GetLastError();
  1489. }
  1490. else
  1491. {
  1492. *pbActivated = TRUE;
  1493. }
  1494. }
  1495. }
  1496. delete [] pszFullPath;
  1497. }
  1498. else
  1499. {
  1500. ErrorCode = ERROR_OUTOFMEMORY;
  1501. }
  1502. }
  1503. return ErrorCode;
  1504. }
  1505. /*++
  1506. Function Name:
  1507. TLoad64BitDllsMgr :: GetMonitorUIFullPath
  1508. Description:
  1509. Functioning returning the full path to create an activation context.
  1510. We have at this stage the monitor name not the full path.
  1511. Parameters:
  1512. pszUIDllName - The name of the monitor ui DLL.
  1513. pszFullPath - The FullPath
  1514. Return Value:
  1515. DWORD: Error Code if any else ERROR_SUCCESS
  1516. --*/
  1517. DWORD
  1518. TLoad64BitDllsMgr ::
  1519. GetMonitorUIFullPath(
  1520. IN LPWSTR pszUIDllName,
  1521. IN OUT LPWSTR pszFullPath
  1522. ) const
  1523. {
  1524. DWORD ErrorCode = ERROR_SUCCESS;
  1525. PWSTR pszFileName = NULL;
  1526. DWORD CchCount;
  1527. if( !pszFullPath && !pszUIDllName)
  1528. {
  1529. ErrorCode = ERROR_INVALID_PARAMETER;
  1530. }
  1531. else
  1532. {
  1533. //
  1534. // Get the monitor full path and the monitor name.
  1535. // pszFullPath is already allocated of MAX_PATH size.
  1536. //
  1537. if (!GetFullPathName(pszUIDllName, MAX_PATH, pszFullPath, &pszFileName))
  1538. {
  1539. ErrorCode = GetLastError();
  1540. }
  1541. else
  1542. {
  1543. ErrorCode = ERROR_INVALID_NAME;
  1544. //
  1545. // Check to see if the monitor name came as a fully qualified path.
  1546. //
  1547. if (_wcsicmp(pszFullPath, pszUIDllName) == 0)
  1548. {
  1549. //
  1550. // We got a full path. Use it as it is.
  1551. //
  1552. ErrorCode = ERROR_SUCCESS;
  1553. }
  1554. else if (_wcsicmp(pszFileName, pszUIDllName) == 0)
  1555. {
  1556. //
  1557. // Xcv can return the monitor name. We want to build the full path
  1558. // out of the name and system directory.
  1559. //
  1560. if (!(CchCount = GetSystemDirectory(pszFullPath, MAX_PATH)))
  1561. {
  1562. ErrorCode = GetLastError();
  1563. }
  1564. else
  1565. {
  1566. //
  1567. // Append the monitor name to the system directory.
  1568. //
  1569. ErrorCode = StatusFromHResult(StringCchPrintf(pszFullPath + CchCount,
  1570. MAX_PATH - CchCount,
  1571. L"\\%s",
  1572. pszUIDllName));
  1573. }
  1574. }
  1575. //
  1576. // Check if the file actually exists.
  1577. //
  1578. if (ErrorCode == ERROR_SUCCESS)
  1579. {
  1580. if (GetFileAttributes(pszFullPath) == INVALID_FILE_ATTRIBUTES)
  1581. {
  1582. ErrorCode = GetLastError();
  1583. }
  1584. }
  1585. }
  1586. }
  1587. return ErrorCode;
  1588. }
  1589. /*++
  1590. Function Name:
  1591. TLoad64BitDllsMgr :: ReleaseMonitorActivationContext
  1592. Description:
  1593. This function releases data relative to activating the monitor UI
  1594. context. It is responsible of releasing the monitor library as well
  1595. the monitor fusion activation context. Note this function is called
  1596. in error cases when GetMonitorUI fails so all the parameters must be
  1597. checked for validity before use.
  1598. Parameters:
  1599. hLib - The handle of the monitor ui DLL.
  1600. hActCtx - The Activation context
  1601. lActCtx = The Activation Cookie
  1602. Return Value:
  1603. VOID
  1604. --*/
  1605. VOID
  1606. TLoad64BitDllsMgr ::
  1607. ReleaseMonitorActivationContext(
  1608. IN HINSTANCE hLib ,
  1609. IN HANDLE hActCtx ,
  1610. IN ULONG_PTR lActCtx ,
  1611. IN BOOL bActivated
  1612. ) const
  1613. {
  1614. //
  1615. // Release the monitor library.
  1616. //
  1617. if (hLib)
  1618. {
  1619. FreeLibrary(hLib);
  1620. }
  1621. //
  1622. // If we have an activation cookie then deactivate this context
  1623. //
  1624. if (bActivated)
  1625. {
  1626. DeactivateActCtx(0 , lActCtx);
  1627. }
  1628. //
  1629. // If we have created an activation context then release it.
  1630. //
  1631. if (hActCtx != INVALID_HANDLE_VALUE && hActCtx != ACTCTX_EMPTY)
  1632. {
  1633. ReleaseActCtx(hActCtx);
  1634. }
  1635. }