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.

817 lines
27 KiB

  1. /*++
  2. Copyright (c) 1994 - 1995 Microsoft Corporation
  3. Module Name:
  4. trueconn.c
  5. Abstract:
  6. This module contains routines for copying drivers from the Server to the
  7. Workstation for Point and Print or "True Connections."
  8. Author:
  9. Krishna Ganugapati (Krishna Ganugapati) 21-Apr-1994
  10. Revision History:
  11. 21-Apr-1994 - Created.
  12. 21-Apr-1994 - There are actually two code modules in this file. Both deal
  13. with true connections
  14. 27-Oct-1994 - Matthew Felton (mattfe) rewrite updatefile routine to allow
  15. non power users to point and print, for caching. Removed
  16. old Caching code.
  17. 23-Feb-1995 - Matthew Felton (mattfe) removed more code by allowing spladdprinterdriver
  18. to do all file copying.
  19. 24-Mar-1999 - Felix Maxa (AMaxa) AddPrinterDriver key must be read from the old location
  20. of the Servers key in System hive
  21. 19-Oct-2000 - Steve Kiraly (SteveKi) Read the AddPrinterDrivers key every time, group
  22. policy modifies this key while the spooler is running, we don't want require
  23. the customer to restart the spooler when this policy changes.
  24. --*/
  25. #include "precomp.h"
  26. DWORD dwLoadTrustedDrivers = 0;
  27. WCHAR TrustedDriverPath[MAX_PATH];
  28. DWORD dwSyncOpenPrinter = 0;
  29. BOOL
  30. ReadImpersonateOnCreate(
  31. VOID
  32. )
  33. {
  34. BOOL bImpersonateOnCreate = FALSE;
  35. HKEY hKey = NULL;
  36. NT_PRODUCT_TYPE NtProductType = {0};
  37. DWORD dwRetval = ERROR_SUCCESS;
  38. DWORD cbData = sizeof(bImpersonateOnCreate);
  39. DWORD dwType = REG_DWORD;
  40. //
  41. // Open the providers registry key
  42. //
  43. dwRetval = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  44. szOldLocationOfServersKey,
  45. 0,
  46. KEY_READ, &hKey);
  47. if (dwRetval == ERROR_SUCCESS)
  48. {
  49. //
  50. // Attempt to read the AddPrinterDrivers policy.
  51. //
  52. dwRetval = RegQueryValueEx(hKey,
  53. L"AddPrinterDrivers",
  54. NULL,
  55. &dwType,
  56. (LPBYTE)&bImpersonateOnCreate,
  57. &cbData);
  58. }
  59. //
  60. // If we did not read the AddPrinterDrivers policy then set the default
  61. // based on the product type.
  62. //
  63. if (dwRetval != ERROR_SUCCESS)
  64. {
  65. bImpersonateOnCreate = FALSE;
  66. // Server Default Always Impersonate on AddPrinterConnection
  67. // WorkStation Default Do Not Impersonate on AddPrinterConnection
  68. if (RtlGetNtProductType(&NtProductType))
  69. {
  70. if (NtProductType != NtProductWinNt)
  71. {
  72. bImpersonateOnCreate = TRUE;
  73. }
  74. }
  75. }
  76. if (hKey)
  77. {
  78. RegCloseKey(hKey);
  79. }
  80. return bImpersonateOnCreate;
  81. }
  82. BOOL
  83. CopyDriversLocally(
  84. PWSPOOL pSpool,
  85. LPWSTR pEnvironment,
  86. LPBYTE pDriverInfo,
  87. DWORD dwLevel,
  88. DWORD cbDriverInfo,
  89. LPDWORD pcbNeeded)
  90. {
  91. DWORD ReturnValue=FALSE;
  92. DWORD RpcError;
  93. DWORD dwServerMajorVersion = 0;
  94. DWORD dwServerMinorVersion = 0;
  95. BOOL DaytonaServer = TRUE;
  96. BOOL bReturn = FALSE;
  97. if (pSpool->Type != SJ_WIN32HANDLE) {
  98. SetLastError(ERROR_INVALID_HANDLE);
  99. return(FALSE);
  100. }
  101. //
  102. // Test RPC call to determine if we're talking to Daytona or Product 1
  103. //
  104. SYNCRPCHANDLE( pSpool );
  105. RpcTryExcept {
  106. ReturnValue = RpcGetPrinterDriver2(pSpool->RpcHandle,
  107. pEnvironment, dwLevel,
  108. pDriverInfo,
  109. cbDriverInfo,
  110. pcbNeeded,
  111. cThisMajorVersion,
  112. cThisMinorVersion,
  113. &dwServerMajorVersion,
  114. &dwServerMinorVersion);
  115. } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) {
  116. RpcError = RpcExceptionCode();
  117. ReturnValue = RpcError;
  118. if (RpcError == RPC_S_PROCNUM_OUT_OF_RANGE) {
  119. //
  120. // Product 1 server
  121. //
  122. DaytonaServer = FALSE;
  123. }
  124. } RpcEndExcept
  125. if ( DaytonaServer ) {
  126. if (ReturnValue) {
  127. SetLastError(ReturnValue);
  128. goto FreeDone;
  129. }
  130. } else {
  131. RpcTryExcept {
  132. //
  133. // I am talking to a Product 1.0/511/528
  134. //
  135. ReturnValue = RpcGetPrinterDriver( pSpool->RpcHandle,
  136. pEnvironment,
  137. dwLevel,
  138. pDriverInfo,
  139. cbDriverInfo,
  140. pcbNeeded );
  141. } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) {
  142. RpcError = RpcExceptionCode();
  143. } RpcEndExcept
  144. if (ReturnValue) {
  145. SetLastError(ReturnValue);
  146. goto FreeDone;
  147. }
  148. }
  149. switch (dwLevel) {
  150. case 2:
  151. bReturn = MarshallUpStructure(pDriverInfo, DriverInfo2Fields, sizeof(DRIVER_INFO_2), RPC_CALL);
  152. break;
  153. case 3:
  154. bReturn = MarshallUpStructure(pDriverInfo, DriverInfo3Fields, sizeof(DRIVER_INFO_3), RPC_CALL);
  155. break;
  156. case 4:
  157. bReturn = MarshallUpStructure(pDriverInfo, DriverInfo4Fields, sizeof(DRIVER_INFO_4), RPC_CALL);
  158. break;
  159. case 6:
  160. bReturn = MarshallUpStructure(pDriverInfo, DriverInfo6Fields, sizeof(DRIVER_INFO_6), RPC_CALL);
  161. break;
  162. case DRIVER_INFO_VERSION_LEVEL:
  163. bReturn = MarshallUpStructure(pDriverInfo, DriverInfoVersionFields, sizeof(DRIVER_INFO_VERSION), RPC_CALL);
  164. break;
  165. default:
  166. DBGMSG(DBG_ERROR,
  167. ("CopyDriversLocally: Invalid level %d", dwLevel));
  168. SetLastError(ERROR_INVALID_LEVEL);
  169. bReturn = FALSE;
  170. goto FreeDone;
  171. }
  172. if (bReturn)
  173. {
  174. bReturn = DownloadDriverFiles(pSpool, pDriverInfo, dwLevel);
  175. }
  176. FreeDone:
  177. return bReturn;
  178. }
  179. BOOL
  180. ConvertDependentFilesToTrustedPath(
  181. LPWSTR *pNewDependentFiles,
  182. LPWSTR pOldDependentFiles,
  183. DWORD dwVersion)
  184. {
  185. //
  186. // Assuming version is single digit
  187. // we need space for \ and the version digit
  188. //
  189. DWORD dwVersionPathLen = wcslen(TrustedDriverPath) + 2;
  190. DWORD dwFilenameLen, cchSize;
  191. LPWSTR pStr1, pStr2, pStr3;
  192. if ( !pOldDependentFiles || !*pOldDependentFiles ) {
  193. *pNewDependentFiles = NULL;
  194. return TRUE;
  195. }
  196. pStr1 = pOldDependentFiles;
  197. cchSize = 0;
  198. while ( *pStr1 ) {
  199. pStr2 = wcsrchr( pStr1, L'\\' );
  200. dwFilenameLen = wcslen(pStr2) + 1;
  201. cchSize += dwVersionPathLen + dwFilenameLen;
  202. pStr1 = pStr2 + dwFilenameLen;
  203. }
  204. // For the last \0
  205. ++cchSize;
  206. *pNewDependentFiles = AllocSplMem(cchSize*sizeof(WCHAR));
  207. if ( !*pNewDependentFiles ) {
  208. return FALSE;
  209. }
  210. pStr1 = pOldDependentFiles;
  211. pStr3 = *pNewDependentFiles;
  212. while ( *pStr1 ) {
  213. pStr2 = wcsrchr( pStr1, L'\\' );
  214. dwFilenameLen = wcslen(pStr2) + 1;
  215. wsprintf( pStr3, L"%ws\\%d%ws", TrustedDriverPath, dwVersion, pStr2 );
  216. pStr1 = pStr2 + dwFilenameLen;
  217. pStr3 += dwVersionPathLen + dwFilenameLen;
  218. }
  219. *pStr3 = '\0';
  220. return TRUE;
  221. }
  222. LPWSTR
  223. ConvertToTrustedPath(
  224. PWCHAR pScratchBuffer,
  225. LPWSTR pDriverPath,
  226. DWORD cVersion
  227. )
  228. {
  229. PWSTR pData;
  230. SPLASSERT( pScratchBuffer != NULL && pDriverPath != NULL );
  231. pData = wcsrchr( pDriverPath, L'\\' );
  232. wsprintf( pScratchBuffer, L"%ws\\%d%ws", TrustedDriverPath, cVersion, pData );
  233. return ( AllocSplStr( pScratchBuffer ) );
  234. }
  235. //
  236. // GetPolicy()
  237. //
  238. // We are hard coding the policy to try the server first and then
  239. // to try the inf install if this installation failed.
  240. //
  241. // This function may be used in the future to leverage different policies.
  242. //
  243. DWORD
  244. GetPolicy()
  245. {
  246. return (SERVER_INF_INSTALL);
  247. }
  248. //
  249. // If there is a language monitor associated with the driver and it is
  250. // not installed on this machine NULL the pMonitorName field.
  251. // We do not want to download the monitor from thr server since there
  252. // is no version associated with them
  253. //
  254. BOOL
  255. NullMonitorName (
  256. LPBYTE pDriverInfo,
  257. DWORD dwLevel
  258. )
  259. {
  260. LPWSTR *ppMonitorName = NULL;
  261. BOOL bReturn = FALSE;
  262. switch (dwLevel) {
  263. case 3:
  264. case 4:
  265. case 6:
  266. {
  267. ppMonitorName = &((LPDRIVER_INFO_6)pDriverInfo)->pMonitorName;
  268. break;
  269. }
  270. case DRIVER_INFO_VERSION_LEVEL:
  271. {
  272. ppMonitorName = &((LPDRIVER_INFO_VERSION)pDriverInfo)->pMonitorName;
  273. break;
  274. }
  275. default:
  276. {
  277. break;
  278. }
  279. }
  280. if (ppMonitorName && *ppMonitorName && **ppMonitorName &&
  281. !SplMonitorIsInstalled(*ppMonitorName))
  282. {
  283. *ppMonitorName = NULL;
  284. bReturn = TRUE;
  285. }
  286. return bReturn;
  287. }
  288. BOOL
  289. DownloadDriverFiles(
  290. PWSPOOL pSpool,
  291. LPBYTE pDriverInfo,
  292. DWORD dwLevel
  293. )
  294. {
  295. PWCHAR pScratchBuffer = NULL;
  296. BOOL bReturnValue = FALSE;
  297. LPBYTE pTempDriverInfo = NULL;
  298. DWORD dwVersion;
  299. DWORD dwInstallPolicy = GetPolicy();
  300. LPDRIVER_INFO_6 pTempDriverInfo6, pDriverInfo6;
  301. //
  302. // If there is a language monitor associated with the driver and it is
  303. // not installed on this machine NULL the pMonitorName field.
  304. // We do not want to pull down the monitor since there is no version
  305. // associated with them
  306. //
  307. NullMonitorName(pDriverInfo, dwLevel);
  308. //
  309. // If LoadTrustedDrivers is FALSE
  310. // then we don't care, we load the files from
  311. // server itself because he has the files
  312. //
  313. if ( !IsTrustedPathConfigured() ) {
  314. //
  315. // At this point dwInstallPolicy will always be SERVER_INF_INSTALL
  316. // as this is hardcoded in the GetPolicy() call.
  317. // This will always be executed in the current GetPolicy() implementation.
  318. //
  319. // If this is only a server install or we're doing a server install first.
  320. //
  321. if( dwInstallPolicy & SERVER_INSTALL_ONLY || dwInstallPolicy & SERVER_INF_INSTALL )
  322. {
  323. //
  324. // SplAddPrinterDriverEx will do the copying of the Driver files if the
  325. // date and time are newer than the drivers it already has
  326. //
  327. bReturnValue = SplAddPrinterDriverEx( NULL,
  328. dwLevel,
  329. pDriverInfo,
  330. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  331. pSpool->hIniSpooler,
  332. DO_NOT_USE_SCRATCH_DIR,
  333. ReadImpersonateOnCreate() );
  334. if (!bReturnValue && dwLevel == 6 && GetLastError() == ERROR_INVALID_LEVEL)
  335. {
  336. //
  337. // If a call with level 6 failed, then try with level 4
  338. //
  339. bReturnValue = SplAddPrinterDriverEx( NULL,
  340. 4,
  341. pDriverInfo,
  342. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  343. pSpool->hIniSpooler,
  344. DO_NOT_USE_SCRATCH_DIR,
  345. ReadImpersonateOnCreate() );
  346. }
  347. }
  348. //
  349. // dwInstallPolicy will be SERVER_INF_INSTALL at this point due to the
  350. // current implementation of GetPolicy(). The below code will only be
  351. // executed if the SplAddPrinterDriverEx calls above failed.
  352. //
  353. // Do this only if we haven't tried a previous install or the previous attempt failed.
  354. // Policy: If this is an INF install only,
  355. // or we're doing and INF install first,
  356. // or the INF install is happening after the server install.
  357. //
  358. if( !bReturnValue && (ERROR_PRINTER_DRIVER_BLOCKED != GetLastError()) && !(dwInstallPolicy & SERVER_INSTALL_ONLY) )
  359. {
  360. LPDRIVER_INFO_2 pDriverInfo2 = (LPDRIVER_INFO_2)pDriverInfo;
  361. LPDRIVER_INFO_1 pDriverInfo1 = (LPDRIVER_INFO_1)pDriverInfo;
  362. //
  363. // Assume if info2 is valid, info1 is too.
  364. //
  365. if( pDriverInfo2 ) {
  366. //
  367. // Paranoid code. We should never receive a call with a level
  368. // one, but if we did, the driver info struct for level 1 is
  369. // different to that in a level 2, so we could AV if we don't
  370. // do this.
  371. //
  372. bReturnValue = AddDriverFromLocalCab( dwLevel == 1 ? pDriverInfo1->pName : pDriverInfo2->pName,
  373. pSpool->hIniSpooler );
  374. }
  375. else if( dwInstallPolicy & INF_INSTALL_ONLY )
  376. {
  377. //
  378. // If this isn't an inf only install, then we should not overwrite the
  379. // last error that will occur with AddPrinterDriver calls.
  380. // If this is an inf install only, pDriverInfo2 was NULL
  381. // so we need to set some last error for this install.
  382. //
  383. SetLastError( ERROR_INVALID_PARAMETER );
  384. }
  385. }
  386. //
  387. // Due to the current implemenation of GetPolicy() the below section
  388. // of code will never be executed. If the GetPolicy() call changes from
  389. // being hardcoded into something actually policy driven, then could be used.
  390. //
  391. // If the inf install is followed by a server install.
  392. // Do this only if the previous install has failed.
  393. //
  394. if( !bReturnValue && dwInstallPolicy & INF_SERVER_INSTALL )
  395. {
  396. //
  397. // SplAddPrinterDriverEx will do the copying of the Driver files if the
  398. // date and time are newer than the drivers it already has
  399. //
  400. bReturnValue = SplAddPrinterDriverEx( NULL,
  401. dwLevel,
  402. pDriverInfo,
  403. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  404. pSpool->hIniSpooler,
  405. DO_NOT_USE_SCRATCH_DIR,
  406. ReadImpersonateOnCreate() );
  407. if (!bReturnValue && dwLevel == 6 && GetLastError() == ERROR_INVALID_LEVEL)
  408. {
  409. //
  410. // If a call with level 6 failed, then try with level 4
  411. //
  412. bReturnValue = SplAddPrinterDriverEx( NULL,
  413. 4,
  414. pDriverInfo,
  415. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  416. pSpool->hIniSpooler,
  417. DO_NOT_USE_SCRATCH_DIR,
  418. ReadImpersonateOnCreate() );
  419. }
  420. }
  421. return bReturnValue;
  422. }
  423. //
  424. // check if we have a valid path to retrieve the files from
  425. //
  426. if ( !TrustedDriverPath || !*TrustedDriverPath ) {
  427. DBGMSG( DBG_WARNING, ( "DownloadDriverFiles Bad Trusted Driver Path\n" ));
  428. SetLastError( ERROR_FILE_NOT_FOUND );
  429. return(FALSE);
  430. }
  431. DBGMSG( DBG_TRACE, ( "Retrieving Files from Trusted Driver Path\n" ) );
  432. DBGMSG( DBG_TRACE, ( "Trusted Driver Path is %ws\n", TrustedDriverPath ) );
  433. //
  434. // In the code below the if statement we make the assumption that the caller
  435. // passed in a pointer to a DRIVER_INFO_6 structure or to a DRIVER_INFO_6
  436. // compatible structure, we need to check the level
  437. //
  438. if (dwLevel == DRIVER_INFO_VERSION_LEVEL)
  439. {
  440. SetLastError(ERROR_INVALID_LEVEL);
  441. return FALSE;
  442. }
  443. try {
  444. pScratchBuffer = AllocSplMem( MAX_PATH );
  445. if ( pScratchBuffer == NULL )
  446. leave;
  447. pDriverInfo6 = (LPDRIVER_INFO_6) pDriverInfo;
  448. pTempDriverInfo = AllocSplMem(sizeof(DRIVER_INFO_6));
  449. if ( pTempDriverInfo == NULL )
  450. leave;
  451. pTempDriverInfo6 = (LPDRIVER_INFO_6) pTempDriverInfo;
  452. pTempDriverInfo6->cVersion = pDriverInfo6->cVersion;
  453. pTempDriverInfo6->pName = pDriverInfo6->pName;
  454. pTempDriverInfo6->pEnvironment = pDriverInfo6->pEnvironment;
  455. pTempDriverInfo6->pDriverPath = ConvertToTrustedPath(pScratchBuffer,
  456. pDriverInfo6->pDriverPath,
  457. pDriverInfo6->cVersion);
  458. pTempDriverInfo6->pConfigFile = ConvertToTrustedPath(pScratchBuffer,
  459. pDriverInfo6->pConfigFile,
  460. pDriverInfo6->cVersion);
  461. pTempDriverInfo6->pDataFile = ConvertToTrustedPath(pScratchBuffer,
  462. pDriverInfo6->pDataFile,
  463. pDriverInfo6->cVersion);
  464. if ( pTempDriverInfo6->pDataFile == NULL ||
  465. pTempDriverInfo6->pDriverPath == NULL ||
  466. pTempDriverInfo6->pConfigFile == NULL ) {
  467. leave;
  468. }
  469. if ( dwLevel == 2 )
  470. goto Call;
  471. pTempDriverInfo6->pMonitorName = pDriverInfo6->pMonitorName;
  472. pTempDriverInfo6->pDefaultDataType = pDriverInfo6->pDefaultDataType;
  473. if ( pDriverInfo6->pHelpFile && *pDriverInfo6->pHelpFile ) {
  474. pTempDriverInfo6->pHelpFile = ConvertToTrustedPath(pScratchBuffer,
  475. pDriverInfo6->pHelpFile,
  476. pDriverInfo6->cVersion);
  477. if ( !pTempDriverInfo6->pHelpFile )
  478. leave;
  479. }
  480. if ( !ConvertDependentFilesToTrustedPath(&pTempDriverInfo6->pDependentFiles,
  481. pDriverInfo6->pDependentFiles,
  482. pDriverInfo6->cVersion) )
  483. leave;
  484. if ( dwLevel == 3 )
  485. goto Call;
  486. SPLASSERT(dwLevel == 4 || dwLevel == 6);
  487. pTempDriverInfo6->pszzPreviousNames = pDriverInfo6->pszzPreviousNames;
  488. Call:
  489. //
  490. // At this point dwInstallPolicy will always be SERVER_INF_INSTALL
  491. // as this is hardcoded in the GetPolicy() call.
  492. // This will always be executed in the current GetPolicy() implementation
  493. //
  494. // If this is only a server install or we're doing a server install first.
  495. //
  496. if( dwInstallPolicy & SERVER_INSTALL_ONLY || dwInstallPolicy & SERVER_INF_INSTALL )
  497. {
  498. //
  499. // SplAddPrinterDriverEx will do the copying of the Driver files if the
  500. // date and time are newer than the drivers it already has
  501. //
  502. bReturnValue = SplAddPrinterDriverEx( NULL,
  503. dwLevel,
  504. pTempDriverInfo,
  505. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  506. pSpool->hIniSpooler,
  507. DO_NOT_USE_SCRATCH_DIR,
  508. ReadImpersonateOnCreate() );
  509. if (!bReturnValue && dwLevel == 6 && GetLastError() == ERROR_INVALID_LEVEL)
  510. {
  511. //
  512. // If a call with level 6 failed, then try with level 4
  513. //
  514. bReturnValue = SplAddPrinterDriverEx( NULL,
  515. 4,
  516. pDriverInfo,
  517. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  518. pSpool->hIniSpooler,
  519. DO_NOT_USE_SCRATCH_DIR,
  520. ReadImpersonateOnCreate() );
  521. }
  522. }
  523. //
  524. // dwInstallPolicy will be SERVER_INF_INSTALL at this point due to the
  525. // current implementation of GetPolicy(). The below code will only be
  526. // executed if the SplAddPrinterDriverEx calls above failed.
  527. //
  528. // Do this only if we haven't tried a previous install or the previous attempt failed.
  529. // Policy: If this is an INF install only,
  530. // or we're doing and INF install first,
  531. // or the INF install is happening after the server install.
  532. //
  533. if( !bReturnValue && (ERROR_PRINTER_DRIVER_BLOCKED != GetLastError()) && !(dwInstallPolicy & SERVER_INSTALL_ONLY) ) {
  534. LPDRIVER_INFO_2 pDriverInfo2 = (LPDRIVER_INFO_2)pDriverInfo;
  535. LPDRIVER_INFO_1 pDriverInfo1 = (LPDRIVER_INFO_1)pDriverInfo;
  536. //
  537. // Set up the info structures first... (assume if info2 is valid, info1 is too)
  538. //
  539. if( pDriverInfo2 ) {
  540. //
  541. // Paranoid code. We should never receive a call with a level
  542. // one, but if we did, the driver info struct for level 1 is
  543. // different to that in a level 2, so we could AV if we don't
  544. // treat them differently.
  545. //
  546. bReturnValue = AddDriverFromLocalCab( dwLevel == 1 ? pDriverInfo1->pName : pDriverInfo2->pName,
  547. pSpool->hIniSpooler );
  548. }
  549. else if( dwInstallPolicy & INF_INSTALL_ONLY ) {
  550. //
  551. // If this isn't an inf only install, then we should not overwrite the
  552. // last error that will occur with AddPrinterDriver calls.
  553. // If this install was only an inf install, pDriverInfo2 was NULL
  554. // so we need to set some last error for this install.
  555. //
  556. SetLastError( ERROR_INVALID_PARAMETER );
  557. }
  558. }
  559. //
  560. // Due to the current implemenation of GetPolicy() the below section
  561. // of code will never be executed. If the GetPolicy() call changes from
  562. // being hardcoded into something actually policy driven, then could be used.
  563. //
  564. // If the inf install is followed by a server install.
  565. // Do this only if the previous install has failed.
  566. //
  567. if( !bReturnValue && dwInstallPolicy & INF_SERVER_INSTALL )
  568. {
  569. //
  570. // SplAddPrinterDriverEx will do the copying of the Driver files if the
  571. // date and time are newer than the drivers it already has
  572. //
  573. bReturnValue = SplAddPrinterDriverEx( NULL,
  574. dwLevel,
  575. pTempDriverInfo,
  576. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  577. pSpool->hIniSpooler,
  578. DO_NOT_USE_SCRATCH_DIR,
  579. ReadImpersonateOnCreate() );
  580. if (!bReturnValue && dwLevel == 6 && GetLastError() == ERROR_INVALID_LEVEL)
  581. {
  582. //
  583. // If a call with level 6 failed, then try with level 4
  584. //
  585. bReturnValue = SplAddPrinterDriverEx( NULL,
  586. 4,
  587. pDriverInfo,
  588. APD_COPY_NEW_FILES | APD_INSTALL_WARNED_DRIVER | APD_RETURN_BLOCKING_STATUS_CODE | APD_DONT_SET_CHECKPOINT,
  589. pSpool->hIniSpooler,
  590. DO_NOT_USE_SCRATCH_DIR,
  591. ReadImpersonateOnCreate() );
  592. }
  593. }
  594. } finally {
  595. FreeSplMem( pScratchBuffer );
  596. if ( pTempDriverInfo != NULL ) {
  597. FreeSplStr(pTempDriverInfo6->pDriverPath);
  598. FreeSplStr(pTempDriverInfo6->pConfigFile);
  599. FreeSplStr(pTempDriverInfo6->pDataFile);
  600. FreeSplStr(pTempDriverInfo6->pDependentFiles);
  601. FreeSplMem(pTempDriverInfo);
  602. }
  603. }
  604. return bReturnValue;
  605. }
  606. VOID
  607. QueryTrustedDriverInformation(
  608. VOID
  609. )
  610. {
  611. DWORD dwRet;
  612. DWORD cbData;
  613. DWORD dwType = 0;
  614. HKEY hKey;
  615. //
  616. // There was a migration of printer connections cache from System
  617. // to sftware. The Servers key and the AddPrinterDrivers values
  618. // remain at the old location, though.
  619. //
  620. dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szOldLocationOfServersKey,
  621. 0, KEY_ALL_ACCESS, &hKey);
  622. if (dwRet != ERROR_SUCCESS) {
  623. return;
  624. }
  625. cbData = sizeof(DWORD);
  626. dwRet = RegQueryValueEx(hKey, L"LoadTrustedDrivers", NULL, &dwType, (LPBYTE)&dwLoadTrustedDrivers, &cbData);
  627. if (dwRet != ERROR_SUCCESS) {
  628. dwLoadTrustedDrivers = 0;
  629. }
  630. //
  631. // By Default we don't wait for the RemoteOpenPrinter to succeed if we have a cache ( Connection )
  632. // Users might want to have Syncronous opens
  633. //
  634. cbData = sizeof(DWORD);
  635. dwRet = RegQueryValueEx(hKey, L"SyncOpenPrinter", NULL, &dwType, (LPBYTE)&dwSyncOpenPrinter, &cbData);
  636. if (dwRet != ERROR_SUCCESS) {
  637. dwSyncOpenPrinter = 0;
  638. }
  639. //
  640. // if !dwLoadedTrustedDrivers then just return
  641. // we won't be using the driver path at all
  642. //
  643. if (!dwLoadTrustedDrivers) {
  644. DBGMSG(DBG_TRACE, ("dwLoadTrustedDrivers is %d\n", dwLoadTrustedDrivers));
  645. RegCloseKey(hKey);
  646. return;
  647. }
  648. cbData = sizeof(TrustedDriverPath);
  649. dwRet = RegQueryValueEx(hKey, L"TrustedDriverPath", NULL, &dwType, (LPBYTE)TrustedDriverPath, &cbData);
  650. if (dwRet != ERROR_SUCCESS) {
  651. dwLoadTrustedDrivers = 0;
  652. DBGMSG(DBG_TRACE, ("dwLoadTrustedDrivers is %d\n", dwLoadTrustedDrivers));
  653. RegCloseKey(hKey);
  654. return;
  655. }
  656. DBGMSG(DBG_TRACE, ("dwLoadTrustedDrivers is %d\n", dwLoadTrustedDrivers));
  657. DBGMSG(DBG_TRACE, ("TrustedPath is %ws\n", TrustedDriverPath));
  658. RegCloseKey(hKey);
  659. return;
  660. }
  661. BOOL
  662. IsTrustedPathConfigured(
  663. IN VOID
  664. )
  665. {
  666. return !!dwLoadTrustedDrivers;
  667. }