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.

1091 lines
24 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cprinter.cxx
  7. //
  8. // Contents:
  9. //
  10. // History: 9-26-96 yihsins Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "ldap.hxx"
  14. #pragma hdrstop
  15. HRESULT
  16. ChangeSeparator(
  17. LPWSTR pszDN
  18. );
  19. HRESULT
  20. GetAuthIdentityForCaller(
  21. CCredentials& Credentials,
  22. IADs * pIADs,
  23. OUT SEC_WINNT_AUTH_IDENTITY *pAuthI,
  24. BOOL fEnforceMutualAuth
  25. );
  26. BOOL
  27. ImpersonateWrapper(
  28. CCredentials& Credentials,
  29. IADs * pIADs,
  30. HANDLE* phUserToken
  31. )
  32. {
  33. HRESULT hr = S_OK;
  34. SEC_WINNT_AUTH_IDENTITY AuthI;
  35. BOOL fImpersonating = FALSE;
  36. AuthI.User = NULL;
  37. AuthI.Domain = NULL;
  38. AuthI.Password = NULL;
  39. hr = GetAuthIdentityForCaller(
  40. Credentials,
  41. pIADs,
  42. &AuthI,
  43. FALSE
  44. );
  45. BAIL_ON_FAILURE(hr);
  46. if (LogonUser(
  47. AuthI.User,
  48. AuthI.Domain,
  49. AuthI.Password,
  50. LOGON32_LOGON_NEW_CREDENTIALS,
  51. LOGON32_PROVIDER_WINNT50,
  52. phUserToken
  53. )
  54. )
  55. {
  56. //
  57. // Call succeeded so we should use this context.
  58. //
  59. if (ImpersonateLoggedOnUser(*phUserToken))
  60. {
  61. fImpersonating = TRUE;
  62. }
  63. }
  64. error:
  65. if (AuthI.User) {
  66. FreeADsStr(AuthI.User);
  67. }
  68. if (AuthI.Domain) {
  69. FreeADsStr(AuthI.Domain);
  70. }
  71. if (AuthI.Password) {
  72. SecureZeroMemory(AuthI.Password, AuthI.PasswordLength*sizeof(WCHAR));
  73. FreeADsStr(AuthI.Password);
  74. }
  75. return fImpersonating;
  76. }
  77. struct _propmap
  78. {
  79. LPTSTR pszADsProp;
  80. LPTSTR pszLDAPProp;
  81. } aPrintPropMapping[] =
  82. { { TEXT("Description"), TEXT("description") },
  83. { TEXT("PrintDevices"), TEXT("PortName") },
  84. { TEXT("Location"), TEXT("location") },
  85. { TEXT("HostComputer"), TEXT("serverName") },
  86. { TEXT("Model"), TEXT("DriverName") },
  87. { TEXT("StartTime"), TEXT("PrintStartTime") },
  88. { TEXT("UntilTime"), TEXT("PrintEndTime") },
  89. { TEXT("Priority"), TEXT("Priority") },
  90. { TEXT("BannerPage"), TEXT("PrintSeparatorfile") }
  91. // { TEXT("NetAddresses"), TEXT("PrintNetworkAddress") },
  92. };
  93. #define UNCNAME TEXT("uNCName")
  94. //
  95. // Class CLDAPPrintQueue
  96. //
  97. // IADsExtension::PrivateGetIDsOfNames()/Invoke(), Operate() not included
  98. DEFINE_IADsExtension_Implementation(CLDAPPrintQueue)
  99. DEFINE_IPrivateDispatch_Implementation(CLDAPPrintQueue)
  100. DEFINE_DELEGATING_IDispatch_Implementation(CLDAPPrintQueue)
  101. DEFINE_CONTAINED_IADs_Implementation(CLDAPPrintQueue)
  102. DEFINE_CONTAINED_IADsPutGet_Implementation(CLDAPPrintQueue,aPrintPropMapping)
  103. CLDAPPrintQueue::CLDAPPrintQueue():
  104. _pUnkOuter(NULL),
  105. _pADs(NULL),
  106. _fDispInitialized(FALSE),
  107. _pDispMgr(NULL)
  108. {
  109. ENLIST_TRACKING(CLDAPPrintQueue);
  110. }
  111. CLDAPPrintQueue::~CLDAPPrintQueue()
  112. {
  113. delete _pDispMgr;
  114. }
  115. HRESULT
  116. CLDAPPrintQueue:: CreatePrintQueue(
  117. IUnknown *pUnkOuter,
  118. REFIID riid,
  119. LPVOID * ppvObj
  120. )
  121. {
  122. CLDAPPrintQueue FAR * pPrintQueue = NULL;
  123. IADs FAR * pADs = NULL;
  124. CAggregateeDispMgr FAR * pDispMgr = NULL;
  125. HRESULT hr = S_OK;
  126. //
  127. // our extension object only works in a provider (aggregator) environment
  128. // environment
  129. //
  130. ASSERT(pUnkOuter);
  131. ASSERT(ppvObj);
  132. ASSERT(IsEqualIID(riid, IID_IUnknown));
  133. pPrintQueue = new CLDAPPrintQueue();
  134. if (pPrintQueue == NULL) {
  135. hr = E_OUTOFMEMORY;
  136. BAIL_ON_FAILURE(hr);
  137. }
  138. //
  139. // Reference Count = 1 from object tracker
  140. //
  141. //
  142. // CAggregateeDispMgr to handle
  143. // IADsExtension::PrivateGetIDsOfNames()/PrivatInovke()
  144. //
  145. pDispMgr = new CAggregateeDispMgr;
  146. if (pDispMgr == NULL) {
  147. hr = E_OUTOFMEMORY;
  148. BAIL_ON_FAILURE(hr);
  149. }
  150. pPrintQueue->_pDispMgr = pDispMgr;
  151. hr = pDispMgr->LoadTypeInfoEntry(
  152. LIBID_ADs,
  153. IID_IADsPrintQueue,
  154. (IADsPrintQueue *)pPrintQueue,
  155. DISPID_REGULAR
  156. );
  157. BAIL_ON_FAILURE(hr);
  158. hr = pDispMgr->LoadTypeInfoEntry(
  159. LIBID_ADs,
  160. IID_IADsPrintQueueOperations,
  161. (IADsPrintQueueOperations *)pPrintQueue,
  162. DISPID_REGULAR
  163. );
  164. BAIL_ON_FAILURE(hr);
  165. //
  166. // Store the pointer to the pUnkOuter object to delegate all IUnknown
  167. // calls to the aggregator AND DO NOT add ref this pointer
  168. //
  169. pPrintQueue->_pUnkOuter = pUnkOuter;
  170. //
  171. // Ccache pADs Pointer to delegate all IDispatch calls to
  172. // the aggregator. But release immediately to avoid the aggregatee
  173. // having a reference count on the aggregator -> cycle ref counting
  174. //
  175. hr = pUnkOuter->QueryInterface(
  176. IID_IADs,
  177. (void **)&pADs
  178. );
  179. //
  180. // Our spec stated extesnion writers can expect the aggregator in our
  181. // provider ot support IDispatch. If not, major bug.
  182. //
  183. ASSERT(SUCCEEDED(hr));
  184. pADs->Release(); // see doc above pUnkOuter->QI
  185. pPrintQueue->_pADs = pADs;
  186. //
  187. // pass non-delegating IUnknown back to the aggregator
  188. //
  189. *ppvObj = (INonDelegatingUnknown FAR *) pPrintQueue;
  190. RRETURN(hr);
  191. error:
  192. if (pPrintQueue)
  193. delete pPrintQueue;
  194. *ppvObj = NULL;
  195. RRETURN(hr);
  196. }
  197. /* IUnknown methods */
  198. STDMETHODIMP
  199. CLDAPPrintQueue::QueryInterface(
  200. REFIID iid,
  201. LPVOID FAR* ppv
  202. )
  203. {
  204. HRESULT hr = S_OK;
  205. hr = _pUnkOuter->QueryInterface(iid,ppv);
  206. RRETURN(hr);
  207. }
  208. STDMETHODIMP
  209. CLDAPPrintQueue::NonDelegatingQueryInterface(
  210. REFIID iid,
  211. LPVOID FAR* ppv
  212. )
  213. {
  214. ASSERT(ppv);
  215. if (IsEqualIID(iid, IID_IADsPrintQueue))
  216. {
  217. *ppv = (IADsPrintQueue FAR *) this;
  218. } else if (IsEqualIID(iid, IID_IADsPrintQueueOperations)) {
  219. *ppv = (IADsPrintQueueOperations FAR *) this;
  220. } else if (IsEqualIID(iid, IID_IADsExtension)) {
  221. *ppv = (IADsExtension FAR *) this;
  222. } else if (IsEqualIID(iid, IID_IUnknown)) {
  223. //
  224. // probably not needed since our 3rd party extension does not stand
  225. // alone and provider does not ask for this, but to be safe
  226. //
  227. *ppv = (INonDelegatingUnknown FAR *) this;
  228. } else {
  229. *ppv = NULL;
  230. return E_NOINTERFACE;
  231. }
  232. //
  233. // Delegating AddRef to aggregator for IADsExtesnion and.
  234. // AddRef on itself for IPrivateUnknown. (both tested.)
  235. //
  236. ((IUnknown *) (*ppv)) -> AddRef();
  237. return S_OK;
  238. }
  239. /* IADs methods */
  240. /* IADsPrintQueue methods */
  241. STDMETHODIMP
  242. CLDAPPrintQueue::get_PrinterPath(THIS_ BSTR FAR* retval)
  243. {
  244. GET_PROPERTY_BSTR((IADsPrintQueue *)this, uNCName );
  245. }
  246. STDMETHODIMP
  247. CLDAPPrintQueue::put_PrinterPath(THIS_ BSTR bstruNCName)
  248. {
  249. PUT_PROPERTY_BSTR((IADsPrintQueue*)this, uNCName);
  250. }
  251. STDMETHODIMP
  252. CLDAPPrintQueue::get_Model(THIS_ BSTR FAR* retval)
  253. {
  254. GET_PROPERTY_BSTR((IADsPrintQueue *)this, Model);
  255. }
  256. STDMETHODIMP
  257. CLDAPPrintQueue::put_Model(THIS_ BSTR bstrModel)
  258. {
  259. PUT_PROPERTY_BSTR((IADsPrintQueue *)this, Model);
  260. }
  261. STDMETHODIMP
  262. CLDAPPrintQueue::get_Datatype(THIS_ BSTR *retval)
  263. {
  264. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  265. }
  266. STDMETHODIMP
  267. CLDAPPrintQueue::put_Datatype(THIS_ BSTR bstrDatatype)
  268. {
  269. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  270. }
  271. STDMETHODIMP
  272. CLDAPPrintQueue::get_PrintProcessor(THIS_ BSTR FAR* retval)
  273. {
  274. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  275. }
  276. STDMETHODIMP
  277. CLDAPPrintQueue::put_PrintProcessor(THIS_ BSTR bstrPrintProcessor)
  278. {
  279. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  280. }
  281. STDMETHODIMP
  282. CLDAPPrintQueue::get_Description(THIS_ BSTR FAR* retval)
  283. {
  284. GET_PROPERTY_BSTR((IADsPrintQueue *)this, Description);
  285. }
  286. STDMETHODIMP
  287. CLDAPPrintQueue::put_Description(THIS_ BSTR bstrDescription)
  288. {
  289. PUT_PROPERTY_BSTR((IADsPrintQueue *)this, Description);
  290. }
  291. STDMETHODIMP CLDAPPrintQueue::get_Location(THIS_ BSTR FAR* retval)
  292. {
  293. GET_PROPERTY_BSTR((IADsPrintQueue *)this, Location);
  294. }
  295. STDMETHODIMP CLDAPPrintQueue::put_Location(THIS_ BSTR bstrLocation)
  296. {
  297. PUT_PROPERTY_BSTR((IADsPrintQueue *)this, Location);
  298. }
  299. STDMETHODIMP
  300. CLDAPPrintQueue::get_StartTime(THIS_ DATE FAR* retval)
  301. {
  302. GET_PROPERTY_LONGDATE((IADsPrintQueue *)this, StartTime);
  303. }
  304. STDMETHODIMP
  305. CLDAPPrintQueue::put_StartTime(THIS_ DATE daStartTime)
  306. {
  307. PUT_PROPERTY_LONGDATE((IADsPrintQueue *)this, StartTime);
  308. }
  309. STDMETHODIMP
  310. CLDAPPrintQueue::get_UntilTime(THIS_ DATE FAR* retval)
  311. {
  312. GET_PROPERTY_LONGDATE((IADsPrintQueue *)this, UntilTime);
  313. }
  314. STDMETHODIMP
  315. CLDAPPrintQueue::put_UntilTime(THIS_ DATE daUntilTime)
  316. {
  317. PUT_PROPERTY_LONGDATE((IADsPrintQueue *)this, UntilTime);
  318. }
  319. STDMETHODIMP
  320. CLDAPPrintQueue::get_DefaultJobPriority(THIS_ LONG FAR* retval)
  321. {
  322. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  323. }
  324. STDMETHODIMP
  325. CLDAPPrintQueue::put_DefaultJobPriority(THIS_ LONG lDefaultJobPriority)
  326. {
  327. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  328. }
  329. STDMETHODIMP
  330. CLDAPPrintQueue::get_Priority(THIS_ LONG FAR* retval)
  331. {
  332. GET_PROPERTY_LONG((IADsPrintQueue *)this, Priority);
  333. }
  334. STDMETHODIMP
  335. CLDAPPrintQueue::put_Priority(THIS_ LONG lPriority)
  336. {
  337. PUT_PROPERTY_LONG((IADsPrintQueue *)this, Priority);
  338. }
  339. STDMETHODIMP
  340. CLDAPPrintQueue::get_BannerPage(THIS_ BSTR FAR* retval)
  341. {
  342. GET_PROPERTY_BSTR((IADsPrintQueue *)this, BannerPage);
  343. }
  344. STDMETHODIMP
  345. CLDAPPrintQueue::put_BannerPage(THIS_ BSTR bstrBannerPage)
  346. {
  347. PUT_PROPERTY_BSTR((IADsPrintQueue *)this, BannerPage);
  348. }
  349. STDMETHODIMP
  350. CLDAPPrintQueue::get_PrintDevices(THIS_ VARIANT FAR* retval)
  351. {
  352. GET_PROPERTY_BSTRARRAY((IADsPrintQueue *)this,PrintDevices);
  353. }
  354. STDMETHODIMP
  355. CLDAPPrintQueue::put_PrintDevices(THIS_ VARIANT vPrintDevices)
  356. {
  357. PUT_PROPERTY_BSTRARRAY((IADsPrintQueue *)this,PrintDevices);
  358. }
  359. STDMETHODIMP
  360. CLDAPPrintQueue::get_NetAddresses(THIS_ VARIANT FAR* retval)
  361. {
  362. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  363. }
  364. STDMETHODIMP
  365. CLDAPPrintQueue::put_NetAddresses(THIS_ VARIANT vNetAddresses)
  366. {
  367. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  368. }
  369. /* IADsPrintQueueOperations methods */
  370. STDMETHODIMP
  371. CLDAPPrintQueue::get_Status(THIS_ long FAR* retval)
  372. {
  373. BOOL fSuccess = FALSE;
  374. HRESULT hr = S_OK;
  375. DWORD dwStatus = 0;
  376. HANDLE hPrinter = NULL;
  377. BSTR bstrPath = NULL ;
  378. LPPRINTER_INFO_2 lpPrinterInfo2 = NULL;
  379. LPPRINTER_INFO_2 lpTempInfo = NULL;
  380. DWORD dwBufferSize = 1024, dwNeeded ;
  381. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_USE |
  382. READ_CONTROL};
  383. //
  384. // get the 'Path' property
  385. //
  386. hr = get_BSTR_Property(this->_pADs, UNCNAME, &bstrPath) ;
  387. BAIL_IF_ERROR(hr);
  388. //
  389. // Do a GetPrinter call to bstrPath
  390. //
  391. fSuccess = OpenPrinter((LPTSTR)bstrPath,
  392. &hPrinter,
  393. &PrinterDefaults
  394. );
  395. if (!fSuccess) {
  396. dwStatus = GetLastError();
  397. if (dwStatus == ERROR_ACCESS_DENIED) {
  398. PrinterDefaults.DesiredAccess = PRINTER_ACCESS_USE ;
  399. fSuccess = OpenPrinter((LPTSTR)bstrPath,
  400. &hPrinter,
  401. &PrinterDefaults
  402. );
  403. }
  404. }
  405. if (!fSuccess) {
  406. hr = HRESULT_FROM_WIN32(GetLastError());
  407. BAIL_IF_ERROR(hr);
  408. }
  409. if (!(lpPrinterInfo2 = (LPPRINTER_INFO_2) AllocADsMem(dwBufferSize))) {
  410. hr = HRESULT_FROM_WIN32(GetLastError()) ;
  411. BAIL_IF_ERROR(hr);
  412. }
  413. fSuccess = GetPrinter(hPrinter,
  414. 2,
  415. (LPBYTE) lpPrinterInfo2,
  416. dwBufferSize,
  417. &dwNeeded);
  418. if (!fSuccess) {
  419. dwStatus = GetLastError() ;
  420. if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
  421. lpTempInfo = (LPPRINTER_INFO_2) ReallocADsMem(
  422. lpPrinterInfo2,
  423. dwBufferSize,
  424. dwNeeded) ;
  425. if (!lpTempInfo) {
  426. hr = HRESULT_FROM_WIN32(GetLastError()) ;
  427. BAIL_IF_ERROR(hr);
  428. }
  429. lpPrinterInfo2 = lpTempInfo;
  430. dwBufferSize = dwNeeded ;
  431. fSuccess = GetPrinter(hPrinter,
  432. 2,
  433. (LPBYTE) lpPrinterInfo2,
  434. dwBufferSize,
  435. &dwNeeded);
  436. }
  437. }
  438. if (!fSuccess) {
  439. hr = HRESULT_FROM_WIN32(GetLastError());
  440. BAIL_IF_ERROR(hr);
  441. }
  442. *retval = lpPrinterInfo2->Status;
  443. cleanup:
  444. if (lpPrinterInfo2) {
  445. FreeADsMem((LPBYTE)lpPrinterInfo2);
  446. }
  447. if (hPrinter) {
  448. (void) ClosePrinter(hPrinter);
  449. }
  450. if(bstrPath)
  451. {
  452. SysFreeString(bstrPath);
  453. bstrPath = NULL;
  454. }
  455. RRETURN(hr);
  456. }
  457. STDMETHODIMP
  458. CLDAPPrintQueue::PrintJobs(
  459. THIS_ IADsCollection * FAR* ppCollection
  460. )
  461. {
  462. //
  463. // The job collection object is created and it is passed the printer
  464. // name. It uses this to create a printer object
  465. //
  466. HRESULT hr = S_OK;
  467. BSTR bstrPath = NULL;
  468. WCHAR *pszADsPath = NULL;
  469. IADsPrintQueueOperations *pPrintQueueOps = NULL;
  470. LPWSTR pszUserName = NULL;
  471. LPWSTR pszPassword = NULL;
  472. DWORD dwAuthFlags = 0;
  473. hr = _Credentials.GetUserName(&pszUserName);
  474. BAIL_IF_ERROR(hr);
  475. hr = _Credentials.GetPassword(&pszPassword);
  476. BAIL_IF_ERROR(hr);
  477. dwAuthFlags = _Credentials.GetAuthFlags();
  478. hr = get_BSTR_Property(_pADs, UNCNAME, &bstrPath) ;
  479. BAIL_IF_ERROR(hr);
  480. //
  481. // UNCName has '\' as separators. Convert them to '/'s.
  482. //
  483. hr = ChangeSeparator(bstrPath);
  484. BAIL_IF_ERROR(hr);
  485. pszADsPath = (LPWSTR) AllocADsMem( ( wcslen(TEXT("WinNT://"))
  486. + wcslen( bstrPath + 2)
  487. + 1 ) * sizeof(WCHAR));
  488. if ( pszADsPath == NULL )
  489. {
  490. hr = E_OUTOFMEMORY;
  491. BAIL_IF_ERROR(hr);
  492. }
  493. wcscpy(pszADsPath, L"WinNT://");
  494. wcscat(pszADsPath, bstrPath+2);
  495. hr = ADsOpenObject(
  496. pszADsPath,
  497. pszUserName,
  498. pszPassword,
  499. dwAuthFlags,
  500. IID_IADsPrintQueueOperations,
  501. (void **)&pPrintQueueOps
  502. );
  503. BAIL_IF_ERROR(hr);
  504. hr = pPrintQueueOps->PrintJobs(ppCollection);
  505. cleanup:
  506. if (pPrintQueueOps){
  507. pPrintQueueOps->Release();
  508. }
  509. if (bstrPath){
  510. ADsFreeString(bstrPath);
  511. }
  512. if (pszADsPath){
  513. FreeADsMem(pszADsPath);
  514. }
  515. if (pszPassword) {
  516. SecureZeroMemory(pszPassword, wcslen(pszPassword)*sizeof(WCHAR));
  517. FreeADsStr(pszPassword);
  518. pszPassword = NULL;
  519. }
  520. if (pszUserName) {
  521. FreeADsStr(pszUserName);
  522. pszUserName = NULL;
  523. }
  524. RRETURN(hr);
  525. }
  526. //+------------------------------------------------------------------------
  527. //
  528. // Function: CLDAPPrintQueue::Pause
  529. //
  530. // Synopsis: Binds to real printer as specified in _bstrPrinterName
  531. // and attempts to pause the real printer.
  532. //
  533. // Arguments: none
  534. //
  535. // Returns: HRESULT.
  536. //
  537. // Modifies: nothing
  538. //
  539. // History: 11-07-95 RamV Created
  540. // Appropriated from Old NetOle Code.
  541. //
  542. //---------------------------------------------------------------------------
  543. STDMETHODIMP
  544. CLDAPPrintQueue::Pause(THIS)
  545. {
  546. HRESULT hr = S_OK;
  547. BOOL fStatus = FALSE;
  548. BSTR bstrPath = NULL ;
  549. HANDLE hPrinter = NULL;
  550. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_ADMINISTER};
  551. BOOL fImpersonate = FALSE;
  552. HANDLE hUserToken = INVALID_HANDLE_VALUE;
  553. //
  554. // get the 'Path' property
  555. //
  556. hr = get_BSTR_Property(this->_pADs, UNCNAME, &bstrPath) ;
  557. BAIL_ON_FAILURE(hr);
  558. if(!_Credentials.IsNullCredentials())
  559. {
  560. fImpersonate = ImpersonateWrapper(_Credentials, _pADs, &hUserToken);
  561. }
  562. // we don't want to break the existing app, so even the impersonation call fails, we will still try to call OpenPrinter
  563. // instead of bailing out
  564. //
  565. // use Win32 to open the printer
  566. //
  567. fStatus = OpenPrinter(
  568. (LPTSTR)bstrPath,
  569. &hPrinter,
  570. &PrinterDefaults);
  571. if (!fStatus) {
  572. hr = HRESULT_FROM_WIN32(GetLastError());
  573. goto error;
  574. }
  575. fStatus = SetPrinter(hPrinter,
  576. 0,
  577. NULL,
  578. PRINTER_CONTROL_PAUSE);
  579. if (!fStatus) {
  580. hr = HRESULT_FROM_WIN32(GetLastError());
  581. }
  582. error:
  583. if(fImpersonate)
  584. {
  585. RevertToSelf();
  586. }
  587. if (hUserToken != INVALID_HANDLE_VALUE ) {
  588. CloseHandle(hUserToken);
  589. hUserToken = NULL;
  590. }
  591. if(hPrinter) {
  592. (void) ClosePrinter(hPrinter);
  593. }
  594. if (bstrPath) {
  595. ADsFreeString(bstrPath);
  596. }
  597. RRETURN(hr);
  598. }
  599. //+---------------------------------------------------------------------------
  600. //
  601. // Function: CLDAPPrintQueue::Resume
  602. //
  603. // Synopsis: Binds to real printer as specified in _bstrPrinterName and
  604. // attempts to resume the real printer.
  605. //
  606. // Arguments: void
  607. //
  608. // Returns: HRESULT.
  609. //
  610. // Modifies:
  611. //
  612. // History: 11-07-95 RamV Created
  613. // Appropriated from old NetOle Project
  614. //----------------------------------------------------------------------------
  615. STDMETHODIMP
  616. CLDAPPrintQueue::Resume(THIS)
  617. {
  618. HRESULT hr = S_OK;
  619. BOOL fStatus = FALSE;
  620. BSTR bstrPath = NULL ;
  621. HANDLE hPrinter = NULL;
  622. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_ADMINISTER};
  623. BOOL fImpersonate = FALSE;
  624. HANDLE hUserToken = INVALID_HANDLE_VALUE;
  625. //
  626. // get the 'Path' property
  627. //
  628. hr = get_BSTR_Property(this->_pADs, UNCNAME, &bstrPath) ;
  629. BAIL_ON_FAILURE(hr);
  630. if(!_Credentials.IsNullCredentials())
  631. {
  632. fImpersonate = ImpersonateWrapper(_Credentials, _pADs, &hUserToken);
  633. }
  634. // we don't want to break the existing app, so even the impersonation call fails, we will still try to call OpenPrinter
  635. // instead of bailing out
  636. //
  637. // use Win32 to open the printer
  638. //
  639. fStatus = OpenPrinter(
  640. (LPTSTR)bstrPath,
  641. &hPrinter,
  642. &PrinterDefaults);
  643. if (!fStatus) {
  644. hr = HRESULT_FROM_WIN32(GetLastError());
  645. goto error;
  646. }
  647. fStatus = SetPrinter(hPrinter,
  648. 0,
  649. NULL,
  650. PRINTER_CONTROL_RESUME);
  651. if (!fStatus) {
  652. hr = HRESULT_FROM_WIN32(GetLastError());
  653. }
  654. error:
  655. if(fImpersonate)
  656. {
  657. RevertToSelf();
  658. }
  659. if (hUserToken != INVALID_HANDLE_VALUE ) {
  660. CloseHandle(hUserToken);
  661. hUserToken = NULL;
  662. }
  663. if(hPrinter) {
  664. (void) ClosePrinter(hPrinter);
  665. }
  666. if (bstrPath) {
  667. ADsFreeString(bstrPath);
  668. }
  669. RRETURN(hr);
  670. }
  671. //+---------------------------------------------------------------------------
  672. //
  673. // Function: CLDAPPrintQueue::Purge
  674. //
  675. // Synopsis: Binds to real printer as specified in _PrinterName and attempts
  676. // to purge the real printer.
  677. //
  678. // Arguments: void
  679. //
  680. // Returns: HRESULT.
  681. //
  682. // Modifies:
  683. //
  684. // History: 11-07-95 RamV Created
  685. // Appropriated from old NetOle Code
  686. //----------------------------------------------------------------------------
  687. STDMETHODIMP
  688. CLDAPPrintQueue::Purge(THIS)
  689. {
  690. HRESULT hr = S_OK;
  691. BOOL fStatus = FALSE;
  692. BSTR bstrPath = NULL ;
  693. HANDLE hPrinter = NULL;
  694. PRINTER_DEFAULTS PrinterDefaults = {0, 0, PRINTER_ACCESS_ADMINISTER};
  695. BOOL fImpersonate = FALSE;
  696. HANDLE hUserToken = INVALID_HANDLE_VALUE;
  697. //
  698. // get the 'Path' property
  699. //
  700. hr = get_BSTR_Property(this->_pADs, UNCNAME, &bstrPath) ;
  701. BAIL_ON_FAILURE(hr);
  702. if(!_Credentials.IsNullCredentials())
  703. {
  704. fImpersonate = ImpersonateWrapper(_Credentials, _pADs, &hUserToken);
  705. }
  706. // we don't want to break the existing app, so even the impersonation call fails, we will still try to call OpenPrinter
  707. // instead of bailing out
  708. //
  709. // use Win32 to open the printer
  710. //
  711. fStatus = OpenPrinter(
  712. (LPTSTR)bstrPath,
  713. &hPrinter,
  714. &PrinterDefaults);
  715. if (!fStatus) {
  716. hr = HRESULT_FROM_WIN32(GetLastError());
  717. goto error;
  718. }
  719. fStatus = SetPrinter(hPrinter,
  720. 0,
  721. NULL,
  722. PRINTER_CONTROL_PURGE);
  723. if (!fStatus) {
  724. hr = HRESULT_FROM_WIN32(GetLastError());
  725. }
  726. error:
  727. if(fImpersonate)
  728. {
  729. RevertToSelf();
  730. }
  731. if (hUserToken != INVALID_HANDLE_VALUE ) {
  732. CloseHandle(hUserToken);
  733. hUserToken = NULL;
  734. }
  735. if(hPrinter) {
  736. (void) ClosePrinter(hPrinter);
  737. }
  738. if (bstrPath) {
  739. ADsFreeString(bstrPath);
  740. }
  741. RRETURN(hr);
  742. }
  743. STDMETHODIMP
  744. CLDAPPrintQueue::ADSIInitializeDispatchManager(
  745. long dwExtensionId
  746. )
  747. {
  748. HRESULT hr = S_OK;
  749. if (_fDispInitialized) {
  750. RRETURN(E_FAIL);
  751. }
  752. hr = _pDispMgr->InitializeDispMgr(dwExtensionId);
  753. if (SUCCEEDED(hr)) {
  754. _fDispInitialized = TRUE;
  755. }
  756. RRETURN(hr);
  757. }
  758. STDMETHODIMP
  759. CLDAPPrintQueue::ADSIInitializeObject(
  760. THIS_ BSTR lpszUserName,
  761. BSTR lpszPassword,
  762. long lnReserved
  763. )
  764. {
  765. CCredentials NewCredentials(lpszUserName, lpszPassword, lnReserved);
  766. _Credentials = NewCredentials;
  767. RRETURN(S_OK);
  768. }
  769. STDMETHODIMP
  770. CLDAPPrintQueue::ADSIReleaseObject()
  771. {
  772. delete this;
  773. RRETURN(S_OK);
  774. }
  775. //
  776. // IADsExtension::Operate()
  777. //
  778. STDMETHODIMP
  779. CLDAPPrintQueue::Operate(
  780. THIS_ DWORD dwCode,
  781. VARIANT varData1,
  782. VARIANT varData2,
  783. VARIANT varData3
  784. )
  785. {
  786. HRESULT hr = S_OK;
  787. switch (dwCode) {
  788. case ADS_EXT_INITCREDENTIALS:
  789. hr = InitCredentials(
  790. &varData1,
  791. &varData2,
  792. &varData3
  793. );
  794. break;
  795. default:
  796. hr = E_FAIL;
  797. break;
  798. }
  799. RRETURN(hr);
  800. }
  801. HRESULT
  802. CLDAPPrintQueue::InitCredentials(
  803. VARIANT * pvarUserName,
  804. VARIANT * pvarPassword,
  805. VARIANT * pvarFlags
  806. )
  807. {
  808. BSTR bstrUser = NULL;
  809. BSTR bstrPwd = NULL;
  810. DWORD dwFlags = 0;
  811. ASSERT(V_VT(pvarUserName) == VT_BSTR);
  812. ASSERT(V_VT(pvarPassword) == VT_BSTR);
  813. ASSERT(V_VT(pvarFlags) == VT_I4);
  814. bstrUser = V_BSTR(pvarUserName);
  815. bstrPwd = V_BSTR(pvarPassword);
  816. dwFlags = V_I4(pvarFlags);
  817. CCredentials NewCredentials(bstrUser, bstrPwd, dwFlags);
  818. _Credentials = NewCredentials;
  819. RRETURN(S_OK);
  820. }