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.

586 lines
16 KiB

  1. /*****************************************************************************\
  2. * MODULE: ppinit.c
  3. *
  4. * This module contains the initialization routines for the Print-Provider.
  5. * The spooler calls InitializePrintProvider() to retreive the list of
  6. * calls that the Print-Processor supports.
  7. *
  8. *
  9. * Copyright (C) 1996-1997 Microsoft Corporation
  10. * Copyright (C) 1996-1997 Hewlett Packard
  11. *
  12. * History:
  13. * 07-Oct-1996 HWP-Guys Initiated port from win95 to winNT
  14. *
  15. \*****************************************************************************/
  16. #include "precomp.h"
  17. #include "priv.h"
  18. /*****************************************************************************\
  19. * _init_provider_worker (Local Routine)
  20. *
  21. *
  22. \*****************************************************************************/
  23. void _init_provider_worker ()
  24. {
  25. // Get the default spool directory
  26. HANDLE hServer = NULL;
  27. DWORD dwType = REG_SZ;
  28. DWORD cbSize = MAX_PATH * sizeof (TCHAR);
  29. g_szDefSplDir[0] = 0;
  30. semEnterCrit ();
  31. if (OpenPrinter (NULL, &hServer, NULL)) {
  32. if (ERROR_SUCCESS != GetPrinterData (hServer,
  33. SPLREG_DEFAULT_SPOOL_DIRECTORY,
  34. &dwType,
  35. (LPBYTE) g_szDefSplDir,
  36. cbSize,
  37. &cbSize)) {
  38. }
  39. ClosePrinter (hServer);
  40. }
  41. SplClean ();
  42. semLeaveCrit ();
  43. }
  44. /*****************************************************************************\
  45. * _init_write_displayname (Local Routine)
  46. *
  47. *
  48. \*****************************************************************************/
  49. BOOL _init_write_displayname(VOID)
  50. {
  51. LONG lRet;
  52. HKEY hkPath;
  53. DWORD dwType;
  54. DWORD cbSize;
  55. if (!LoadString (g_hInst,
  56. IDS_DISPLAY_NAME,
  57. g_szDisplayStr,
  58. MAX_PATH)) {
  59. g_szDisplayStr[0] = 0;
  60. }
  61. // Open the key to the Print-Providor.
  62. //
  63. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  64. g_szRegProvider,
  65. 0,
  66. KEY_READ | KEY_WRITE,
  67. &hkPath);
  68. if (lRet == ERROR_SUCCESS) {
  69. // Look for the "displayname". If it doesn't exist, then write it.
  70. //
  71. dwType = REG_SZ;
  72. cbSize = 0;
  73. lRet = RegQueryValueEx(hkPath,
  74. g_szDisplayName,
  75. NULL,
  76. &dwType,
  77. (LPBYTE)NULL,
  78. &cbSize);
  79. // Write the string.
  80. //
  81. if ((lRet != ERROR_SUCCESS) || (cbSize == 0)) {
  82. dwType = REG_SZ;
  83. cbSize = (lstrlen(g_szDisplayStr) + 1) * sizeof(TCHAR);
  84. lRet = RegSetValueEx(hkPath,
  85. g_szDisplayName,
  86. 0,
  87. dwType,
  88. (LPBYTE)g_szDisplayStr,
  89. cbSize);
  90. }
  91. RegCloseKey(hkPath);
  92. }
  93. if (lRet != ERROR_SUCCESS) {
  94. SetLastError (lRet);
  95. return FALSE;
  96. }
  97. else
  98. return TRUE;
  99. }
  100. /*****************************************************************************\
  101. * _init_find_filename (Local Routine)
  102. *
  103. *
  104. \*****************************************************************************/
  105. LPTSTR _init_find_filename(
  106. LPCTSTR lpszPathName)
  107. {
  108. LPTSTR lpszFileName;
  109. if (lpszPathName == NULL)
  110. return NULL;
  111. // Look for the filename in the path, by starting at the end
  112. // and looking for the ('\') char.
  113. //
  114. if (!(lpszFileName = utlStrChrR(lpszPathName, TEXT('\\'))))
  115. lpszFileName = (LPTSTR)lpszPathName;
  116. else
  117. lpszFileName++;
  118. return lpszFileName;
  119. }
  120. /*****************************************************************************\
  121. * _init_load_netapi (Local Routine)
  122. *
  123. * Initialize INET API pointers.
  124. *
  125. \*****************************************************************************/
  126. BOOL _init_load_netapi(VOID)
  127. {
  128. g_pfnHttpQueryInfo = (PFNHTTPQUERYINFO) HttpQueryInfoA;
  129. g_pfnInternetOpenUrl = (PFNINTERNETOPENURL) InternetOpenUrlA;
  130. g_pfnInternetErrorDlg = (PFNINTERNETERRORDLG) InternetErrorDlg;
  131. g_pfnHttpSendRequest = (PFNHTTPSENDREQUEST) HttpSendRequestA;
  132. g_pfnHttpSendRequestEx = (PFNHTTPSENDREQUESTEX) HttpSendRequestExA;
  133. g_pfnInternetReadFile = (PFNINTERNETREADFILE) InternetReadFile;
  134. g_pfnInternetWriteFile = (PFNINTERNETWRITEFILE) InternetWriteFile;
  135. g_pfnInternetCloseHandle = (PFNINTERNETCLOSEHANDLE) InternetCloseHandle;
  136. g_pfnInternetOpen = (PFNINTERNETOPEN) InternetOpenA;
  137. g_pfnInternetConnect = (PFNINTERNETCONNECT) InternetConnectA;
  138. g_pfnHttpOpenRequest = (PFNHTTPOPENREQUEST) HttpOpenRequestA;
  139. g_pfnHttpAddRequestHeaders = (PFNHTTPADDREQUESTHEADERS)HttpAddRequestHeadersA;
  140. g_pfnHttpEndRequest = (PFNHTTPENDREQUEST) HttpEndRequestA;
  141. g_pfnInternetSetOption = (PFNINTERNETSETOPTION) InternetSetOptionA;
  142. return TRUE;
  143. }
  144. /*****************************************************************************\
  145. * _init_load_provider (Local Routine)
  146. *
  147. * This performs the startup initialization for the print-provider.
  148. *
  149. \*****************************************************************************/
  150. BOOL _init_load_provider()
  151. {
  152. LPTSTR lpszFileName;
  153. TCHAR szBuf[MAX_PATH];
  154. DWORD i = MAX_COMPUTERNAME_LENGTH + 1;
  155. BOOL bRet = FALSE;
  156. // Get the module name for this process.
  157. //
  158. if (!GetModuleFileName(NULL, szBuf, MAX_PATH))
  159. goto exit_load;
  160. // Get the filename from the full module-name. and check that
  161. // it's the spooler.
  162. //
  163. if (lpszFileName = _init_find_filename(szBuf)) {
  164. if (lstrcmpi(lpszFileName, g_szProcessName) == 0) {
  165. // Initialize the computer name.
  166. //
  167. if (!GetComputerName(g_szMachine, &i))
  168. goto exit_load;
  169. // Initialize the internet API pointers.
  170. //
  171. if (_init_load_netapi() == FALSE)
  172. goto exit_load;
  173. //
  174. // Assume success.
  175. //
  176. bRet = TRUE;
  177. //
  178. // Try and initialize the crit-sect for synchronizing port access.
  179. //
  180. __try {
  181. InitializeCriticalSection(&g_csMonitorSection);
  182. }
  183. __except (1) {
  184. bRet = FALSE;
  185. SetLastError (ERROR_INVALID_HANDLE);
  186. }
  187. return bRet;
  188. }
  189. }
  190. exit_load:
  191. return bRet;
  192. }
  193. /*****************************************************************************\
  194. * _init_load_ports (Local Routine)
  195. *
  196. * This performs the port initialization for the print-provider.
  197. *
  198. \*****************************************************************************/
  199. BOOL _init_load_ports(
  200. LPTSTR lpszRegPath)
  201. {
  202. LONG lStat;
  203. HKEY hkPath;
  204. HKEY hkPortNames;
  205. TCHAR szPortName[MAX_PATH];
  206. BOOL bRet = FALSE;
  207. LPTSTR pEnd = NULL;
  208. size_t uSize = 0;
  209. //
  210. // Make sure there is a registry-path pointing to the
  211. // INET provider entry.
  212. //
  213. if (lpszRegPath == NULL)
  214. return FALSE;
  215. //
  216. // Copy the string to global-memory. We will need this if we require
  217. // the need to write to the registry when creating new ports.
  218. //
  219. uSize = 1 + lstrlen (lpszRegPath);
  220. if (! (g_szRegProvider = (LPTSTR) memAlloc (uSize * sizeof (TCHAR)))) {
  221. return FALSE;
  222. }
  223. StringCchCopy(g_szRegProvider, uSize, lpszRegPath);
  224. //
  225. // Copy the registry key of all the printer providers
  226. //
  227. if (! (g_szRegPrintProviders = (LPTSTR) memAlloc (uSize * sizeof (TCHAR)))) {
  228. return FALSE;
  229. }
  230. StringCchCopy(g_szRegPrintProviders, uSize, lpszRegPath);
  231. pEnd = wcsrchr (g_szRegPrintProviders, L'\\');
  232. if ( pEnd )
  233. {
  234. *pEnd = 0;
  235. }
  236. // Open registry key for Provider-Name.
  237. //
  238. lStat = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszRegPath, 0, KEY_READ, &hkPath);
  239. if (lStat == ERROR_SUCCESS) {
  240. bRet = TRUE;
  241. // Open the "ports" key for enumeration of the ports. We need to
  242. // build up this list at the provider initialization time so that
  243. // we can return the list of ports if called to EnumPorts().
  244. //
  245. lStat = RegOpenKeyEx(hkPath, g_szRegPorts, 0, KEY_READ, &hkPortNames);
  246. if (lStat == ERROR_SUCCESS) {
  247. DWORD dwSize;
  248. DWORD i = 0;
  249. while (lStat == ERROR_SUCCESS) {
  250. dwSize = sizeof(szPortName) / sizeof (TCHAR);
  251. lStat = RegEnumKey (hkPortNames,
  252. i,
  253. szPortName,
  254. dwSize);
  255. if (lStat == ERROR_SUCCESS) {
  256. // Do not short-cut this call to InetmonAddPort(),
  257. // as this will leave the crit-sect unprotected.
  258. //
  259. PPAddPort(szPortName, NULL, NULL);
  260. }
  261. i++;
  262. }
  263. RegCloseKey(hkPortNames);
  264. } else {
  265. DBG_MSG(DBG_LEV_INFO, (TEXT("RegOpenKeyEx(%s) failed: Error = %lu"), g_szRegPorts, lStat));
  266. SetLastError(lStat);
  267. }
  268. RegCloseKey(hkPath);
  269. } else {
  270. DBG_MSG(DBG_LEV_WARN, (TEXT("RegOpenKeyEx(%s) failed: Error = %lu"), lpszRegPath, lStat));
  271. SetLastError(lStat);
  272. }
  273. return bRet;
  274. }
  275. /*****************************************************************************\
  276. * _init_create_sync (Local Routine)
  277. *
  278. * This creates the events and Critical Section needed for handling the synchronisation
  279. * in the monitor.
  280. *
  281. \*****************************************************************************/
  282. _inline BOOL _init_create_sync(VOID)
  283. {
  284. BOOL bRet = TRUE;
  285. g_dwConCount = 0;
  286. __try {
  287. InitializeCriticalSection(&g_csCreateSection);
  288. }
  289. __except (1) {
  290. bRet = FALSE;
  291. SetLastError (ERROR_INVALID_HANDLE);
  292. }
  293. if (bRet) {
  294. g_eResetConnections = CreateEvent( NULL, TRUE, TRUE, NULL );
  295. if (g_eResetConnections == NULL)
  296. bRet = FALSE;
  297. }
  298. return bRet;
  299. }
  300. /*****************************************************************************\
  301. * InitializePrintProvider (API)
  302. *
  303. * The spooler calls this routine to initialize the Print-Provider. The list
  304. * of functions in the table are passed back to the spooler for it to use
  305. * when interfacing with the provider.
  306. *
  307. \*****************************************************************************/
  308. static PRINTPROVIDOR pfnPPList[] = {
  309. PPOpenPrinter,
  310. PPSetJob,
  311. PPGetJob,
  312. PPEnumJobs,
  313. stubAddPrinter,
  314. stubDeletePrinter,
  315. PPSetPrinter,
  316. PPGetPrinter,
  317. PPEnumPrinters,
  318. stubAddPrinterDriver,
  319. stubEnumPrinterDrivers,
  320. stubGetPrinterDriver,
  321. stubGetPrinterDriverDirectory,
  322. stubDeletePrinterDriver,
  323. stubAddPrintProcessor,
  324. stubEnumPrintProcessors,
  325. stubGetPrintProcessorDirectory,
  326. stubDeletePrintProcessor,
  327. stubEnumPrintProcessorDatatypes,
  328. PPStartDocPrinter,
  329. PPStartPagePrinter,
  330. PPWritePrinter,
  331. PPEndPagePrinter,
  332. PPAbortPrinter,
  333. stubReadPrinter,
  334. PPEndDocPrinter,
  335. PPAddJob,
  336. PPScheduleJob,
  337. stubGetPrinterData,
  338. stubSetPrinterData,
  339. stubWaitForPrinterChange,
  340. PPClosePrinter,
  341. stubAddForm,
  342. stubDeleteForm,
  343. stubGetForm,
  344. stubSetForm,
  345. stubEnumForms,
  346. stubEnumMonitors,
  347. PPEnumPorts,
  348. stubAddPort,
  349. NULL,
  350. NULL,
  351. stubCreatePrinterIC,
  352. stubPlayGdiScriptOnPrinterIC,
  353. stubDeletePrinterIC,
  354. stubAddPrinterConnection,
  355. stubDeletePrinterConnection,
  356. stubPrinterMessageBox,
  357. stubAddMonitor,
  358. stubDeleteMonitor,
  359. NULL, // stubResetPrinter,
  360. NULL, // stubGetPrinterDriverEx should not be called as specified in spoolss\dll\nullpp.c
  361. PPFindFirstPrinterChangeNotification,
  362. PPFindClosePrinterChangeNotification,
  363. NULL, // stubAddPortEx,
  364. NULL, // stubShutDown,
  365. NULL, // stubRefreshPrinterChangeNotification,
  366. NULL, // stubOpenPrinterEx,
  367. NULL, // stubAddPrinterEx,
  368. NULL, // stubSetPort,
  369. NULL, // stubEnumPrinterData,
  370. NULL, // stubDeletePrinterData,
  371. NULL, // fpClusterSplOpen
  372. NULL, // fpClusterSplClose
  373. NULL, // fpClusterSplIsAlive
  374. NULL, // fpSetPrinterDataEx
  375. NULL, // fpGetPrinterDataEx
  376. NULL, // fpEnumPrinterDataEx
  377. NULL, // fpEnumPrinterKey
  378. NULL, // fpDeletePrinterDataEx
  379. NULL, // fpDeletePrinterKey
  380. NULL, // fpSeekPrinter
  381. NULL, // fpDeletePrinterDriverEx
  382. NULL, // fpAddPerMachineConnection
  383. NULL, // fpDeletePerMachineConnection
  384. NULL, // fpEnumPerMachineConnections
  385. PPXcvData, // fpXcvData
  386. NULL, // fpAddPrinterDriverEx
  387. NULL, // fpSplReadPrinter
  388. NULL, // fpDriverUnloadComplete
  389. NULL, // fpGetSpoolFileInfo
  390. NULL, // fpCommitSpoolData
  391. NULL, // fpCloseSpoolFileHandle
  392. NULL, // fpFlushPrinter
  393. NULL, // fpSendRecvBidiData
  394. NULL, // fpAddDriverCatalog
  395. };
  396. BOOL WINAPI InitializePrintProvidor(
  397. LPPRINTPROVIDOR pPP,
  398. DWORD cEntries,
  399. LPWSTR pszFullRegistryPath)
  400. {
  401. HANDLE hThread;
  402. DWORD dwThreadId;
  403. g_pcsEndBrowserSessionLock = new CCriticalSection ();
  404. if (!g_pcsEndBrowserSessionLock || g_pcsEndBrowserSessionLock->bValid () == FALSE) {
  405. SetLastError(ERROR_INVALID_PARAMETER);
  406. return FALSE;
  407. }
  408. if (_init_load_provider() == FALSE) {
  409. DBG_ASSERT(FALSE, (TEXT("Assert: Failed module initialization")));
  410. return FALSE;
  411. }
  412. if (!pszFullRegistryPath || !*pszFullRegistryPath) {
  413. SetLastError(ERROR_INVALID_PARAMETER);
  414. return FALSE;
  415. }
  416. gpInetMon = new CInetMon;
  417. if (!gpInetMon || gpInetMon->bValid() == FALSE) {
  418. if (gpInetMon) {
  419. delete gpInetMon;
  420. }
  421. return FALSE;
  422. }
  423. if (gpInetMon && !gpInetMon->bValid ()) {
  424. delete gpInetMon;
  425. SetLastError(ERROR_INVALID_PARAMETER);
  426. return FALSE;
  427. }
  428. DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Call: InitializePrintProvidor")));
  429. memcpy(pPP, pfnPPList, min(sizeof(pfnPPList), (int)cEntries));
  430. // Initialise synchronisation objects
  431. if (!_init_create_sync())
  432. return FALSE;
  433. g_bUpgrade = SplIsUpgrade();
  434. if (_init_load_ports((LPTSTR)pszFullRegistryPath) == FALSE) {
  435. DBG_ASSERT(FALSE, (TEXT("Assert: Failed port initialization")));
  436. return FALSE;
  437. }
  438. if (!_init_write_displayname())
  439. return FALSE;
  440. if (hThread = CreateThread (NULL,
  441. 0,
  442. (LPTHREAD_START_ROUTINE) _init_provider_worker,
  443. NULL,
  444. 0,
  445. &dwThreadId)) {
  446. CloseHandle (hThread);
  447. return TRUE;
  448. }
  449. else
  450. return FALSE;
  451. }
  452. /*****************************************************************************\
  453. * DllMain
  454. *
  455. * This is the main entry-point for the library.
  456. *
  457. \*****************************************************************************/
  458. extern "C"
  459. BOOL WINAPI DllMain(
  460. HINSTANCE hInstDll,
  461. DWORD dwAttach,
  462. LPVOID lpcReserved)
  463. {
  464. switch (dwAttach)
  465. {
  466. case DLL_PROCESS_ATTACH:
  467. g_hInst = hInstDll;
  468. DisableThreadLibraryCalls(hInstDll);
  469. break;
  470. case DLL_PROCESS_DETACH:
  471. DeleteCriticalSection(&g_csCreateSection);
  472. DeleteCriticalSection(&g_csMonitorSection);
  473. CloseHandle(g_eResetConnections);
  474. delete g_pcsEndBrowserSessionLock;
  475. break;
  476. }
  477. return TRUE;
  478. }