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.

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