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.

860 lines
22 KiB

  1. /*++
  2. Copyright (c) 1990 - 1995 Microsoft Corporation
  3. Module Name:
  4. prtproc.c
  5. Abstract:
  6. This module provides all the public exported APIs relating to the
  7. PrintProcessor based Spooler Apis for the Local Print Providor
  8. LocalAddPrintProcessor
  9. LocalEnumPrintProcessors
  10. LocalDeletePrintProcessor
  11. LocalGetPrintProcessorDirectory
  12. LocalEnumPrintProcessorDatatypes
  13. Support Functions in prtproc.c - (Warning! Do Not Add to this list!!)
  14. AddPrintProcessorIni
  15. DeletePrintProcessorIni
  16. CopyIniPrintProcToPrintProcInfo
  17. GetPrintProcessorInfoSize
  18. Author:
  19. Dave Snipp (DaveSn) 15-Mar-1991
  20. Revision History:
  21. Felix Maxa (amaxa) 18-Jun-2000
  22. Modified registry functions to take pIniSpooler
  23. Added code to propagate print processors to the cluster disk
  24. Matthew A Felton ( MattFe ) 27 June 1994
  25. pIniSpooler
  26. --*/
  27. #define NOMINMAX
  28. #include <precomp.h>
  29. #include <offsets.h>
  30. #include "clusspl.h"
  31. //
  32. // Support Function Prototypes
  33. //
  34. DWORD
  35. GetPrintProcessorInfoSize(
  36. PINIPRINTPROC pIniPrintProc,
  37. DWORD Level,
  38. LPWSTR pEnvironment
  39. );
  40. LPBYTE
  41. CopyIniPrintProcToPrintProcInfo(
  42. LPWSTR pEnvironment,
  43. PINIPRINTPROC pIniPrintProc,
  44. DWORD Level,
  45. LPBYTE pPrintProcessorInfo,
  46. LPBYTE pEnd
  47. );
  48. BOOL
  49. AddPrintProcessorIni(
  50. PINIPRINTPROC pIniPrintProc,
  51. PINIENVIRONMENT pIniEnvironment,
  52. PINISPOOLER pIniSpooler
  53. );
  54. BOOL
  55. DeletePrintProcessorIni(
  56. PINIPRINTPROC pIniPrintProc,
  57. PINIENVIRONMENT pIniEnvironment,
  58. PINISPOOLER pIniSpooler
  59. );
  60. BOOL
  61. LocalAddPrintProcessor(
  62. LPWSTR pName,
  63. LPWSTR pEnvironment,
  64. LPWSTR pPathName,
  65. LPWSTR pPrintProcessorName
  66. )
  67. {
  68. PINISPOOLER pIniSpooler;
  69. BOOL bReturn;
  70. pIniSpooler = FindSpoolerByNameIncRef( pName, NULL );
  71. if( !pIniSpooler ){
  72. return ROUTER_UNKNOWN;
  73. }
  74. bReturn = SplAddPrintProcessor( pName, pEnvironment, pPathName,
  75. pPrintProcessorName, pIniSpooler );
  76. FindSpoolerByNameDecRef( pIniSpooler );
  77. return bReturn;
  78. }
  79. BOOL
  80. SplAddPrintProcessor(
  81. LPWSTR pName,
  82. LPWSTR pEnvironment,
  83. LPWSTR pPathName,
  84. LPWSTR pPrintProcessorName,
  85. PINISPOOLER pIniSpooler
  86. )
  87. {
  88. PINIPRINTPROC pIniPrintProc;
  89. PINIENVIRONMENT pIniEnvironment;
  90. DWORD LastError=0;
  91. if (!MyName( pName, pIniSpooler )) {
  92. return FALSE;
  93. }
  94. if(!pPrintProcessorName || wcslen( pPrintProcessorName ) >= MAX_PATH) {
  95. SetLastError(ERROR_INVALID_PARAMETER);
  96. return FALSE;
  97. }
  98. EnterSplSem();
  99. if ( ValidateObjectAccess(SPOOLER_OBJECT_SERVER,
  100. SERVER_ACCESS_ADMINISTER,
  101. NULL, NULL, pIniSpooler )) {
  102. if ((pIniEnvironment = FindEnvironment(pEnvironment, pIniSpooler)) &&
  103. (pIniEnvironment == FindEnvironment(szEnvironment, pIniSpooler))) {
  104. if (!FindPrintProc(pPrintProcessorName, pIniEnvironment)) {
  105. pIniPrintProc = LoadPrintProcessor(pIniEnvironment,
  106. pPrintProcessorName,
  107. pPathName,
  108. pIniSpooler);
  109. if (!pIniPrintProc ||
  110. !AddPrintProcessorIni(pIniPrintProc, pIniEnvironment, pIniSpooler))
  111. {
  112. LastError = GetLastError();
  113. }
  114. else
  115. {
  116. //
  117. // For a cluster type spooler copy the print proc to the cluster disk
  118. //
  119. if (pIniSpooler->SpoolerFlags & SPL_TYPE_CLUSTER)
  120. {
  121. WCHAR szDestDir[MAX_PATH] = {0};
  122. WCHAR szSourceFile[MAX_PATH] = {0};
  123. if ((LastError = StrNCatBuff(szDestDir,
  124. MAX_PATH,
  125. pIniSpooler->pszClusResDriveLetter,
  126. L"\\",
  127. szClusterDriverRoot,
  128. L"\\",
  129. pIniEnvironment->pDirectory,
  130. NULL)) == ERROR_SUCCESS &&
  131. (LastError = StrNCatBuff(szSourceFile,
  132. MAX_PATH,
  133. pIniSpooler->pDir,
  134. L"\\",
  135. szPrintProcDir,
  136. L"\\",
  137. pIniEnvironment->pDirectory,
  138. L"\\",
  139. pPathName,
  140. NULL)) == ERROR_SUCCESS)
  141. {
  142. //
  143. // This function will take care to create the destination directory tree
  144. //
  145. LastError = CopyFileToDirectory(szSourceFile, szDestDir, NULL, NULL, NULL);
  146. DBGMSG(DBG_CLUSTER, ("ClusterCopyProcessorToClusterDisks returns Win32 error %u\n", LastError));
  147. }
  148. }
  149. }
  150. } else
  151. LastError = ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED;
  152. } else
  153. LastError = ERROR_INVALID_ENVIRONMENT;
  154. } else
  155. LastError = GetLastError();
  156. if (!LastError)
  157. SetPrinterChange(NULL,
  158. NULL,
  159. NULL,
  160. PRINTER_CHANGE_ADD_PRINT_PROCESSOR,
  161. pIniSpooler);
  162. LeaveSplSem();
  163. SplOutSem();
  164. if (LastError) {
  165. SetLastError(LastError);
  166. return FALSE;
  167. }
  168. return TRUE;
  169. }
  170. BOOL
  171. LocalDeletePrintProcessor(
  172. LPWSTR pName,
  173. LPWSTR pEnvironment,
  174. LPWSTR pPrintProcessorName
  175. )
  176. {
  177. PINISPOOLER pIniSpooler;
  178. BOOL bReturn;
  179. pIniSpooler = FindSpoolerByNameIncRef( pName, NULL );
  180. if( !pIniSpooler ){
  181. return ROUTER_UNKNOWN;
  182. }
  183. bReturn = SplDeletePrintProcessor( pName,
  184. pEnvironment,
  185. pPrintProcessorName,
  186. pIniSpooler );
  187. FindSpoolerByNameDecRef( pIniSpooler );
  188. return bReturn;
  189. }
  190. BOOL
  191. SplDeletePrintProcessor(
  192. LPWSTR pName,
  193. LPWSTR pEnvironment,
  194. LPWSTR pPrintProcessorName,
  195. PINISPOOLER pIniSpooler
  196. )
  197. {
  198. PINIENVIRONMENT pIniEnvironment;
  199. PINIPRINTPROC pIniPrintProc;
  200. BOOL Remote=FALSE;
  201. if (pName && *pName) {
  202. if (!MyName( pName, pIniSpooler )) {
  203. return FALSE;
  204. } else {
  205. Remote = TRUE;
  206. }
  207. }
  208. if ( !ValidateObjectAccess(SPOOLER_OBJECT_SERVER,
  209. SERVER_ACCESS_ADMINISTER,
  210. NULL, NULL, pIniSpooler )) {
  211. return FALSE;
  212. }
  213. EnterSplSem();
  214. pIniEnvironment = FindEnvironment(pEnvironment, pIniSpooler);
  215. //
  216. // Fail the call if we can't find a matching environment or
  217. // the environemnt doesn't match to the environemnt of the
  218. // local machine
  219. //
  220. if (!pIniEnvironment ||
  221. lstrcmpi(pIniEnvironment->pName, szEnvironment))
  222. {
  223. LeaveSplSem();
  224. SetLastError(ERROR_INVALID_ENVIRONMENT);
  225. return FALSE;
  226. }
  227. if (!(pIniPrintProc=(PINIPRINTPROC)FindIniKey(
  228. (PINIENTRY)pIniEnvironment->pIniPrintProc,
  229. pPrintProcessorName)))
  230. {
  231. SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
  232. LeaveSplSem();
  233. return FALSE;
  234. }
  235. else if (pIniPrintProc->cRef)
  236. {
  237. SetLastError(ERROR_CAN_NOT_COMPLETE);
  238. LeaveSplSem();
  239. return FALSE;
  240. }
  241. RemoveFromList((PINIENTRY *)&pIniEnvironment->pIniPrintProc,
  242. (PINIENTRY)pIniPrintProc);
  243. DeletePrintProcessorIni(pIniPrintProc, pIniEnvironment, pIniSpooler);
  244. if (!FreeLibrary(pIniPrintProc->hLibrary)) {
  245. DBGMSG(DBG_TRACE, ("DeletePrintProcessor: FreeLibrary failed\n"));
  246. }
  247. FreeSplMem(pIniPrintProc->pDatatypes);
  248. DeleteCriticalSection(&pIniPrintProc->CriticalSection);
  249. FreeSplMem(pIniPrintProc);
  250. SetPrinterChange(NULL,
  251. NULL,
  252. NULL,
  253. PRINTER_CHANGE_DELETE_PRINT_PROCESSOR,
  254. pIniSpooler);
  255. LeaveSplSem();
  256. return TRUE;
  257. }
  258. BOOL
  259. LocalEnumPrintProcessors(
  260. LPWSTR pName,
  261. LPWSTR pEnvironment,
  262. DWORD Level,
  263. LPBYTE pPrintProcessorInfo,
  264. DWORD cbBuf,
  265. LPDWORD pcbNeeded,
  266. LPDWORD pcReturned
  267. )
  268. {
  269. PINISPOOLER pIniSpooler;
  270. BOOL bReturn;
  271. pIniSpooler = FindSpoolerByNameIncRef( pName, NULL );
  272. if( !pIniSpooler ){
  273. return ROUTER_UNKNOWN;
  274. }
  275. bReturn = SplEnumPrintProcessors( pName,
  276. pEnvironment,
  277. Level,
  278. pPrintProcessorInfo,
  279. cbBuf,
  280. pcbNeeded,
  281. pcReturned,
  282. pIniSpooler );
  283. FindSpoolerByNameDecRef( pIniSpooler );
  284. return bReturn;
  285. }
  286. BOOL
  287. SplEnumPrintProcessors(
  288. LPWSTR pName,
  289. LPWSTR pEnvironment,
  290. DWORD Level,
  291. LPBYTE pPrintProcessorInfo,
  292. DWORD cbBuf,
  293. LPDWORD pcbNeeded,
  294. LPDWORD pcReturned,
  295. PINISPOOLER pIniSpooler
  296. )
  297. {
  298. PINIPRINTPROC pIniPrintProc;
  299. PINIENVIRONMENT pIniEnvironment;
  300. DWORD cb, cbStruct;
  301. LPBYTE pEnd;
  302. DWORD LastError=0;
  303. if (!MyName( pName, pIniSpooler )) {
  304. return FALSE;
  305. }
  306. if ( !ValidateObjectAccess(SPOOLER_OBJECT_SERVER,
  307. SERVER_ACCESS_ENUMERATE,
  308. NULL, NULL, pIniSpooler )) {
  309. return FALSE;
  310. }
  311. EnterSplSem();
  312. //
  313. // Don't ignore the environment. This was added in 3.1 as a hack instead
  314. // of fixing printman. The problem was that from remote, different
  315. // environments, it would look for the wrong architecture. Now the
  316. // NT 4.0 and 5.0 UI code does the right thing.
  317. //
  318. if( !pEnvironment ||
  319. !(pIniEnvironment = FindEnvironment( pEnvironment, pIniSpooler ))){
  320. LastError = ERROR_INVALID_ENVIRONMENT;
  321. goto Done;
  322. }
  323. switch (Level) {
  324. case 1:
  325. cbStruct = sizeof(PRINTPROCESSOR_INFO_1);
  326. break;
  327. default:
  328. LeaveSplSem();
  329. SetLastError( ERROR_INVALID_LEVEL );
  330. return FALSE;
  331. }
  332. *pcReturned=0;
  333. cb=0;
  334. pIniPrintProc=pIniEnvironment->pIniPrintProc;
  335. while (pIniPrintProc) {
  336. cb+=GetPrintProcessorInfoSize(pIniPrintProc, Level, pEnvironment);
  337. pIniPrintProc=pIniPrintProc->pNext;
  338. }
  339. *pcbNeeded=cb;
  340. if (cb <= cbBuf) {
  341. pIniPrintProc=pIniEnvironment->pIniPrintProc;
  342. pEnd=pPrintProcessorInfo+cbBuf;
  343. while (pEnd && pIniPrintProc) {
  344. pEnd = CopyIniPrintProcToPrintProcInfo(pEnvironment,
  345. pIniPrintProc,
  346. Level,
  347. pPrintProcessorInfo,
  348. pEnd);
  349. pPrintProcessorInfo+=cbStruct;
  350. (*pcReturned)++;
  351. pIniPrintProc=pIniPrintProc->pNext;
  352. }
  353. if (!pEnd && cbBuf)
  354. LastError = ERROR_OUTOFMEMORY;
  355. } else
  356. LastError = ERROR_INSUFFICIENT_BUFFER;
  357. Done:
  358. LeaveSplSem();
  359. SplOutSem();
  360. if (LastError) {
  361. SetLastError(LastError);
  362. return FALSE;
  363. }
  364. return TRUE;
  365. }
  366. BOOL
  367. LocalGetPrintProcessorDirectory(
  368. LPWSTR pName,
  369. LPWSTR pEnvironment,
  370. DWORD Level,
  371. LPBYTE pPrintProcessorInfo,
  372. DWORD cbBuf,
  373. LPDWORD pcbNeeded
  374. )
  375. {
  376. PINISPOOLER pIniSpooler;
  377. BOOL bReturn;
  378. pIniSpooler = FindSpoolerByNameIncRef( pName, NULL );
  379. if( !pIniSpooler ){
  380. return ROUTER_UNKNOWN;
  381. }
  382. bReturn = SplGetPrintProcessorDirectory( pName,
  383. pEnvironment,
  384. Level,
  385. pPrintProcessorInfo,
  386. cbBuf,
  387. pcbNeeded,
  388. pIniSpooler );
  389. FindSpoolerByNameDecRef( pIniSpooler );
  390. return bReturn;
  391. }
  392. BOOL
  393. SplGetPrintProcessorDirectory(
  394. LPWSTR pName,
  395. LPWSTR pEnvironment,
  396. DWORD Level,
  397. LPBYTE pPrintProcessorInfo,
  398. DWORD cbBuf,
  399. LPDWORD pcbNeeded,
  400. PINISPOOLER pIniSpooler
  401. )
  402. {
  403. PINIENVIRONMENT pIniEnvironment;
  404. DWORD cb;
  405. DWORD dwError = ERROR_INVALID_ENVIRONMENT;
  406. LPWSTR pszString = NULL;
  407. BOOL rc = FALSE;
  408. if (MyName( pName, pIniSpooler) &&
  409. ValidateObjectAccess(SPOOLER_OBJECT_SERVER,
  410. SERVER_ACCESS_ENUMERATE,
  411. NULL,
  412. NULL,
  413. pIniSpooler))
  414. {
  415. EnterSplSem();
  416. pIniEnvironment = FindEnvironment(pEnvironment, pIniSpooler);
  417. if (pIniEnvironment)
  418. {
  419. dwError = GetProcessorDirectory(&pszString, pIniEnvironment->pDirectory, pIniSpooler);
  420. if (dwError == ERROR_SUCCESS)
  421. {
  422. *pcbNeeded = cb = wcslen(pszString) * sizeof(WCHAR) + sizeof(WCHAR);
  423. if (cbBuf >= cb)
  424. {
  425. wcscpy((LPWSTR)pPrintProcessorInfo, pszString);
  426. //
  427. // Make sure the directory exists
  428. //
  429. CreatePrintProcDirectory(pIniEnvironment->pDirectory, pIniSpooler);
  430. rc = TRUE;
  431. }
  432. else
  433. {
  434. dwError = ERROR_INSUFFICIENT_BUFFER;
  435. }
  436. }
  437. }
  438. LeaveSplSem();
  439. SetLastError(dwError);
  440. FreeSplMem(pszString);
  441. }
  442. return rc;
  443. }
  444. BOOL
  445. LocalEnumPrintProcessorDatatypes(
  446. LPWSTR pName,
  447. LPWSTR pPrintProcessorName,
  448. DWORD Level,
  449. LPBYTE pDatatypes,
  450. DWORD cbBuf,
  451. LPDWORD pcbNeeded,
  452. LPDWORD pcReturned
  453. )
  454. {
  455. PINISPOOLER pIniSpooler;
  456. BOOL bReturn;
  457. pIniSpooler = FindSpoolerByNameIncRef( pName, NULL );
  458. if( !pIniSpooler ){
  459. return ROUTER_UNKNOWN;
  460. }
  461. bReturn = SplEnumPrintProcessorDatatypes( pName,
  462. pPrintProcessorName,
  463. Level,
  464. pDatatypes,
  465. cbBuf,
  466. pcbNeeded,
  467. pcReturned,
  468. pIniSpooler );
  469. FindSpoolerByNameDecRef( pIniSpooler );
  470. return bReturn;
  471. }
  472. BOOL
  473. SplEnumPrintProcessorDatatypes(
  474. LPWSTR pName,
  475. LPWSTR pPrintProcessorName,
  476. DWORD Level,
  477. LPBYTE pDatatypes,
  478. DWORD cbBuf,
  479. LPDWORD pcbNeeded,
  480. LPDWORD pcReturned,
  481. PINISPOOLER pIniSpooler
  482. )
  483. {
  484. PINIPRINTPROC pIniPrintProc;
  485. PINIENVIRONMENT pIniEnvironment;
  486. if (!MyName( pName, pIniSpooler )) {
  487. return FALSE;
  488. }
  489. if ( !ValidateObjectAccess(SPOOLER_OBJECT_SERVER,
  490. SERVER_ACCESS_ENUMERATE,
  491. NULL, NULL, pIniSpooler )) {
  492. return FALSE;
  493. }
  494. EnterSplSem();
  495. pIniPrintProc = FindPrintProc(pPrintProcessorName, GetLocalArchEnv(pIniSpooler));
  496. LeaveSplSem();
  497. if (pIniPrintProc)
  498. return (*pIniPrintProc->EnumDatatypes)(pName, pPrintProcessorName,
  499. Level, pDatatypes, cbBuf,
  500. pcbNeeded, pcReturned);
  501. else {
  502. SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
  503. return FALSE;
  504. }
  505. }
  506. DWORD
  507. GetPrintProcessorInfoSize(
  508. PINIPRINTPROC pIniPrintProc,
  509. DWORD Level,
  510. LPWSTR pEnvironment
  511. )
  512. {
  513. DWORD cb=0;
  514. switch (Level) {
  515. case 1:
  516. cb=sizeof(PRINTPROCESSOR_INFO_1) +
  517. wcslen(pIniPrintProc->pName)*sizeof(WCHAR) + sizeof(WCHAR);
  518. break;
  519. default:
  520. cb = 0;
  521. break;
  522. }
  523. return cb;
  524. }
  525. LPBYTE
  526. CopyIniPrintProcToPrintProcInfo(
  527. LPWSTR pEnvironment,
  528. PINIPRINTPROC pIniPrintProc,
  529. DWORD Level,
  530. LPBYTE pPrintProcessorInfo,
  531. LPBYTE pEnd
  532. )
  533. {
  534. LPWSTR *pSourceStrings, *SourceStrings;
  535. PPRINTPROCESSOR_INFO_1 pDriver1 = (PPRINTPROCESSOR_INFO_1)pPrintProcessorInfo;
  536. DWORD j;
  537. DWORD *pOffsets;
  538. switch (Level) {
  539. case 1:
  540. pOffsets = PrintProcessorInfo1Strings;
  541. break;
  542. default:
  543. return pEnd;
  544. }
  545. for (j=0; pOffsets[j] != -1; j++) {
  546. }
  547. SourceStrings = pSourceStrings = AllocSplMem(j * sizeof(LPWSTR));
  548. if (!pSourceStrings) {
  549. DBGMSG(DBG_WARNING, ("Could not allocate %d bytes for print proc source strings.\n",
  550. (j * sizeof(LPWSTR))));
  551. return pEnd;
  552. }
  553. switch (Level) {
  554. case 1:
  555. *pSourceStrings++=pIniPrintProc->pName;
  556. pEnd = PackStrings(SourceStrings, (LPBYTE)pPrintProcessorInfo, pOffsets, pEnd);
  557. break;
  558. }
  559. FreeSplMem(SourceStrings);
  560. return pEnd;
  561. }
  562. BOOL
  563. AddPrintProcessorIni(
  564. PINIPRINTPROC pIniPrintProc,
  565. PINIENVIRONMENT pIniEnvironment,
  566. PINISPOOLER pIniSpooler
  567. )
  568. {
  569. HKEY hEnvironmentsRootKey, hEnvironmentKey, hPrintProcsKey, hPrintProcKey;
  570. HANDLE hToken;
  571. BOOL ReturnValue = FALSE;
  572. hToken = RevertToPrinterSelf();
  573. if (SplRegCreateKey(pIniSpooler->SpoolerFlags & SPL_CLUSTER_REG ? pIniSpooler->hckRoot : HKEY_LOCAL_MACHINE,
  574. pIniSpooler->pszRegistryEnvironments,
  575. 0,
  576. KEY_WRITE,
  577. NULL,
  578. &hEnvironmentsRootKey,
  579. NULL,
  580. pIniSpooler) == ERROR_SUCCESS)
  581. {
  582. if (SplRegOpenKey(hEnvironmentsRootKey,
  583. pIniEnvironment->pName,
  584. KEY_WRITE,
  585. &hEnvironmentKey,
  586. pIniSpooler) == ERROR_SUCCESS)
  587. {
  588. if (SplRegOpenKey(hEnvironmentKey,
  589. szPrintProcKey,
  590. KEY_WRITE,
  591. &hPrintProcsKey,
  592. pIniSpooler) == ERROR_SUCCESS)
  593. {
  594. if (SplRegCreateKey(hPrintProcsKey,
  595. pIniPrintProc->pName,
  596. 0,
  597. KEY_WRITE,
  598. NULL,
  599. &hPrintProcKey,
  600. NULL,
  601. pIniSpooler) == ERROR_SUCCESS)
  602. {
  603. if (SplRegSetValue(hPrintProcKey,
  604. szDriverFile,
  605. REG_SZ,
  606. (LPBYTE)pIniPrintProc->pDLLName,
  607. (wcslen(pIniPrintProc->pDLLName) + 1)*sizeof(WCHAR),
  608. pIniSpooler) == ERROR_SUCCESS)
  609. {
  610. ReturnValue = TRUE;
  611. DBGMSG(DBG_CLUSTER, ("AddPrintProcessorIni Success "TSTR" "TSTR"\n", pIniPrintProc->pName, pIniPrintProc->pDLLName));
  612. }
  613. SplRegCloseKey(hPrintProcKey, pIniSpooler);
  614. }
  615. SplRegCloseKey(hPrintProcsKey, pIniSpooler);
  616. }
  617. SplRegCloseKey(hEnvironmentKey, pIniSpooler);
  618. }
  619. SplRegCloseKey(hEnvironmentsRootKey, pIniSpooler);
  620. }
  621. ImpersonatePrinterClient(hToken);
  622. return ReturnValue;
  623. }
  624. BOOL
  625. DeletePrintProcessorIni(
  626. PINIPRINTPROC pIniPrintProc,
  627. PINIENVIRONMENT pIniEnvironment,
  628. PINISPOOLER pIniSpooler
  629. )
  630. {
  631. HKEY hEnvironmentsRootKey, hEnvironmentKey, hPrintProcsKey;
  632. HANDLE hToken;
  633. hToken = RevertToPrinterSelf();
  634. if (SplRegCreateKey(pIniSpooler->SpoolerFlags & SPL_CLUSTER_REG ? pIniSpooler->hckRoot : HKEY_LOCAL_MACHINE,
  635. pIniSpooler->pszRegistryEnvironments,
  636. 0,
  637. KEY_WRITE,
  638. NULL,
  639. &hEnvironmentsRootKey,
  640. NULL,
  641. pIniSpooler) == ERROR_SUCCESS)
  642. {
  643. if (SplRegOpenKey(hEnvironmentsRootKey,
  644. pIniEnvironment->pName,
  645. KEY_WRITE,
  646. &hEnvironmentKey,
  647. pIniSpooler) == ERROR_SUCCESS)
  648. {
  649. if (SplRegOpenKey(hEnvironmentKey,
  650. szPrintProcKey,
  651. KEY_WRITE,
  652. &hPrintProcsKey,
  653. pIniSpooler) == ERROR_SUCCESS)
  654. {
  655. SplRegDeleteKey(hPrintProcsKey, pIniPrintProc->pName, pIniSpooler);
  656. SplRegCloseKey(hPrintProcsKey, pIniSpooler);
  657. DBGMSG(DBG_CLUSTER, ("DeletePrintProcessorIni Success "TSTR"\n", pIniPrintProc->pName));
  658. }
  659. SplRegCloseKey(hEnvironmentKey, pIniSpooler);
  660. }
  661. SplRegCloseKey(hEnvironmentsRootKey, pIniSpooler);
  662. }
  663. ImpersonatePrinterClient(hToken);
  664. return TRUE;
  665. }