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.

497 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C O C . C P P
  7. //
  8. // Contents: Common functions related to optional components
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 18 Dec 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "ncinf.h"
  18. #include "ncmisc.h"
  19. #include "ncsetup.h"
  20. #include "ncstring.h"
  21. #include "ncsnmp.h"
  22. #include "ncoc.h"
  23. #include "ncsvc.h"
  24. #include <winspool.h> // Print monitor routines
  25. #include "ncmisc.h"
  26. // SNMP Agent extension
  27. static const WCHAR c_szSNMPSuffix[] = L"SNMPAgent";
  28. static const WCHAR c_szSNMPAddLabel[] = L"AddAgent";
  29. static const WCHAR c_szSNMPDelLabel[] = L"DelAgent";
  30. static const WCHAR c_szServiceName[] = L"ServiceName";
  31. static const WCHAR c_szAgentName[] = L"AgentName";
  32. static const WCHAR c_szAgentPath[] = L"AgentPath";
  33. // Print extension
  34. static const WCHAR c_szPrintSuffix[] = L"PrintMonitor";
  35. static const WCHAR c_szPrintAddLabel[] = L"AddMonitor";
  36. static const WCHAR c_szPrintDelLabel[] = L"DelMonitor";
  37. static const WCHAR c_szPrintMonitorName[] = L"PrintMonitorName";
  38. static const WCHAR c_szPrintMonitorDLL[] = L"PrintMonitorDLL";
  39. static const WCHAR c_szPrintProcName[] = L"PrintProcName";
  40. static const WCHAR c_szPrintProcDLL[] = L"PrintProcDLL";
  41. static const WCHAR c_szExternalAppCmdLine[] = L"CommandLine";
  42. static const WCHAR c_szExternalAppCmdShow[] = L"WindowStyle";
  43. static const WCHAR c_szExternalAppDirectory[] = L"Directory";
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Function: HrProcessSNMPAddSection
  47. //
  48. // Purpose: Parses the AddSNMPAgent section for parameters then adds the
  49. // component as an SNMP agent.
  50. //
  51. // Arguments:
  52. // hinfFile [in] handle to INF file
  53. // szSection [in] section on which to operate
  54. //
  55. // Returns: S_OK if success, setup API HRESULT otherwise.
  56. //
  57. // Author: danielwe 28 Apr 1997
  58. //
  59. // Notes:
  60. //
  61. HRESULT HrProcessSNMPAddSection(HINF hinfFile, PCWSTR szSection)
  62. {
  63. HRESULT hr = S_OK;
  64. tstring strServiceName;
  65. tstring strAgentName;
  66. tstring strAgentPath;
  67. hr = HrSetupGetFirstString(hinfFile, szSection, c_szServiceName,
  68. &strServiceName);
  69. if (S_OK == hr)
  70. {
  71. hr = HrSetupGetFirstString(hinfFile, szSection, c_szAgentName,
  72. &strAgentName);
  73. if (S_OK == hr)
  74. {
  75. hr = HrSetupGetFirstString(hinfFile, szSection, c_szAgentPath,
  76. &strAgentPath);
  77. if (S_OK == hr)
  78. {
  79. TraceTag(ttidInfExt, "Adding SNMP agent %S...",
  80. strAgentName.c_str());
  81. hr = HrAddSNMPAgent(strServiceName.c_str(),
  82. strAgentName.c_str(),
  83. strAgentPath.c_str());
  84. }
  85. }
  86. }
  87. TraceHr (ttidError, FAL, hr, (SPAPI_E_LINE_NOT_FOUND == hr),
  88. "HrProcessSNMPAddSection");
  89. return hr;
  90. }
  91. //+---------------------------------------------------------------------------
  92. //
  93. // Function: HrProcessSNMPRemoveSection
  94. //
  95. // Purpose: Handles removal of an SNMP agent.
  96. //
  97. // Arguments:
  98. // hinfFile [in] handle to INF file
  99. // szSection [in] section on which to operate
  100. //
  101. // Returns: S_OK if success, setup API HRESULT otherwise
  102. //
  103. // Author: danielwe 28 Apr 1997
  104. //
  105. // Notes:
  106. //
  107. HRESULT HrProcessSNMPRemoveSection(HINF hinfFile, PCWSTR szSection)
  108. {
  109. HRESULT hr = S_OK;
  110. tstring strAgentName;
  111. hr = HrSetupGetFirstString(hinfFile, szSection, c_szAgentName,
  112. &strAgentName);
  113. if (S_OK == hr)
  114. {
  115. hr = HrRemoveSNMPAgent(strAgentName.c_str());
  116. }
  117. TraceHr (ttidError, FAL, hr, (SPAPI_E_LINE_NOT_FOUND == hr),
  118. "HrProcessSNMPRemoveSection");
  119. return hr;
  120. }
  121. //+---------------------------------------------------------------------------
  122. //
  123. // Function: HrProcessPrintAddSection
  124. //
  125. // Purpose: Parses the AddPrintMonitor section for parameters then adds the
  126. // monitor.
  127. //
  128. // Arguments:
  129. // hinfFile [in] handle to INF file
  130. // szSection [in] section on which to operate
  131. //
  132. // Returns: S_OK if success, setup API HRESULT otherwise.
  133. //
  134. // Author: CWill May 5 1997
  135. //
  136. // Notes:
  137. //
  138. HRESULT HrProcessPrintAddSection(HINF hinfFile, PCWSTR szSection)
  139. {
  140. HRESULT hr = S_OK;
  141. tstring strPrintMonitorName;
  142. tstring strPrintMonitorDLL;
  143. hr = HrSetupGetFirstString(hinfFile, szSection, c_szPrintMonitorName,
  144. &strPrintMonitorName);
  145. if (S_OK == hr)
  146. {
  147. hr = HrSetupGetFirstString(hinfFile, szSection, c_szPrintMonitorDLL,
  148. &strPrintMonitorDLL);
  149. if (S_OK == hr)
  150. {
  151. hr = HrAddPrintMonitor(
  152. strPrintMonitorName.c_str(),
  153. strPrintMonitorDLL.c_str());
  154. if (S_OK == hr)
  155. {
  156. tstring strPrintProcName;
  157. tstring strPrintProcDLL;
  158. hr = HrSetupGetFirstString(hinfFile, szSection,
  159. c_szPrintProcName,
  160. &strPrintProcName);
  161. if (S_OK == hr)
  162. {
  163. hr = HrSetupGetFirstString(hinfFile, szSection,
  164. c_szPrintProcDLL,
  165. &strPrintProcDLL);
  166. if (S_OK == hr)
  167. {
  168. hr = HrAddPrintProc(strPrintProcDLL.c_str(),
  169. strPrintProcName.c_str());
  170. }
  171. }
  172. else
  173. {
  174. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  175. {
  176. // Print proc's are optional.
  177. hr = S_OK;
  178. }
  179. }
  180. }
  181. }
  182. }
  183. TraceHr (ttidError, FAL, hr, (SPAPI_E_LINE_NOT_FOUND == hr),
  184. "HrProcessPrintAddSection");
  185. return hr;
  186. }
  187. //+---------------------------------------------------------------------------
  188. //
  189. // Function: HrProcessPrintRemoveSection
  190. //
  191. // Purpose: Handles removal of a print monitor.
  192. //
  193. // Arguments:
  194. // hinfFile [in] handle to INF file
  195. // szSection [in] section on which to operate
  196. //
  197. // Returns: S_OK if success, setup API HRESULT otherwise
  198. //
  199. // Author: CWill May 5 1997
  200. //
  201. // Notes:
  202. //
  203. HRESULT HrProcessPrintRemoveSection(HINF hinfFile, PCWSTR szSection)
  204. {
  205. HRESULT hr = S_OK;
  206. tstring strPrintMonitorName;
  207. hr = HrSetupGetFirstString(hinfFile, szSection, c_szPrintMonitorName,
  208. &strPrintMonitorName);
  209. if (S_OK == hr)
  210. {
  211. hr = HrRemovePrintMonitor(strPrintMonitorName.c_str());
  212. if (S_OK == hr)
  213. {
  214. tstring strPrintProcName;
  215. hr = HrSetupGetFirstString(hinfFile, szSection, c_szPrintProcName,
  216. &strPrintProcName);
  217. if (S_OK == hr)
  218. {
  219. hr = HrRemovePrintProc(strPrintProcName.c_str());
  220. }
  221. else
  222. {
  223. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  224. {
  225. // Print proc's are optional.
  226. hr = S_OK;
  227. }
  228. }
  229. }
  230. else if (HRESULT_FROM_WIN32(ERROR_BUSY) == hr)
  231. {
  232. // Consume the device busy error. NT4 and NT 3.51 had
  233. // the same limitation
  234. hr = S_OK;
  235. }
  236. }
  237. TraceHr (ttidError, FAL, hr, (SPAPI_E_LINE_NOT_FOUND == hr),
  238. "HrProcessPrintRemoveSection");
  239. return hr;
  240. }
  241. //+---------------------------------------------------------------------------
  242. //
  243. // Function: HrAddPrintProc
  244. //
  245. // Purpose: Adds a new print procedure.
  246. //
  247. // Arguments:
  248. // szDLLName [in] File name of DLL in which proc resides.
  249. // szProc [in] Name of procedure to add.
  250. //
  251. // Returns: S_OK if success, Win32 HRESULT otherwise.
  252. //
  253. // Author: danielwe 6 May 1997
  254. //
  255. // Notes:
  256. //
  257. HRESULT HrAddPrintProc(PCWSTR szDLLName, PCWSTR szProc)
  258. {
  259. HRESULT hr = S_OK;
  260. if (!AddPrintProcessor(NULL, NULL, const_cast<PWSTR>(szDLLName),
  261. const_cast<PWSTR>(szProc)))
  262. {
  263. hr = HrFromLastWin32Error();
  264. if (hr == HRESULT_FROM_WIN32(ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED))
  265. {
  266. // Don't complain if processor is already installed.
  267. hr = S_OK;
  268. }
  269. }
  270. TraceError("HrAddPrintProc", hr);
  271. return hr;
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Function: HrRemovePrintProc
  276. //
  277. // Purpose: Removes a print procedure.
  278. //
  279. // Arguments:
  280. // szProc [in] Name of procedure to remove.
  281. //
  282. // Returns: S_OK if success, Win32 HRESULT otherwise.
  283. //
  284. // Author: danielwe 6 May 1997
  285. //
  286. // Notes:
  287. //
  288. HRESULT HrRemovePrintProc(PCWSTR szProc)
  289. {
  290. HRESULT hr = S_OK;
  291. if (!DeletePrintProcessor(NULL, NULL, const_cast<PWSTR>(szProc)))
  292. {
  293. hr = HrFromLastWin32Error();
  294. if (hr == HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRINTPROCESSOR))
  295. {
  296. // Don't complain if print processor doesn't exist.
  297. hr = S_OK;
  298. }
  299. }
  300. TraceError("HrFromLastWin32Error", hr);
  301. return hr;
  302. }
  303. //+---------------------------------------------------------------------------
  304. //
  305. // Function: HrAddPrintMonitor
  306. //
  307. // Purpose: Adds a print monitor
  308. //
  309. // Arguments:
  310. // szPrintMonitorName [in] The name of the print monitor being added
  311. // szPrintMonitorDLL [in] The DLL associated with the monitor
  312. //
  313. // Returns: S_OK if success, WIN32 HRESULT otherwise
  314. //
  315. // Author: CWill May 5 1997
  316. //
  317. // Notes:
  318. //
  319. HRESULT HrAddPrintMonitor(PCWSTR szPrintMonitorName,
  320. PCWSTR szPrintMonitorDLL)
  321. {
  322. HRESULT hr = S_OK;
  323. MONITOR_INFO_2 moninfoTemp =
  324. {
  325. const_cast<WCHAR*>(szPrintMonitorName),
  326. NULL,
  327. const_cast<WCHAR*>(szPrintMonitorDLL)
  328. };
  329. //$ REVIEW (danielwe) 23 Mar 1998: Need Spooler team to add support to
  330. // PrintMonitor APIs to start Spooler if needed. Bug #149775
  331. retry:
  332. // According to MSDN, first param is NULL, second is 2
  333. // third is the monitor
  334. TraceTag(ttidInfExt, "Adding print monitor...");
  335. if (!AddMonitor(NULL, 2, (BYTE*)&moninfoTemp))
  336. {
  337. hr = HrFromLastWin32Error();
  338. if (hr == HRESULT_FROM_WIN32(ERROR_PRINT_MONITOR_ALREADY_INSTALLED))
  339. {
  340. // Don't complain if it's already there.
  341. hr = S_OK;
  342. }
  343. else if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
  344. {
  345. // Spooler service isn't started. We need to start it
  346. TraceTag(ttidInfExt, "Spooler service wasn't started. Starting"
  347. " it now...");
  348. hr = HrEnableAndStartSpooler();
  349. if (S_OK == hr)
  350. {
  351. TraceTag(ttidInfExt, "Spooler service started successfully. "
  352. "Retrying...");
  353. goto retry;
  354. }
  355. }
  356. }
  357. TraceTag(ttidInfExt, "Done adding print monitor...");
  358. TraceError("HrAddPrintMonitor", hr);
  359. return hr;
  360. }
  361. //+---------------------------------------------------------------------------
  362. //
  363. // Function: HrRemovePrintMonitor
  364. //
  365. // Purpose: Removes a print monitor
  366. //
  367. // Arguments:
  368. // szPrintMonitorName [in] The name of the print monitor being removed
  369. //
  370. // Returns: S_OK if success, WIN32 HRESULT otherwise
  371. //
  372. // Author: CWill May 5 1997
  373. //
  374. // Notes:
  375. //
  376. HRESULT HrRemovePrintMonitor(PCWSTR szPrintMonitorName)
  377. {
  378. HRESULT hr = S_OK;
  379. //$ REVIEW (danielwe) 23 Mar 1998: Need Spooler team to add support to
  380. // PrintMonitor APIs to start Spooler if needed. Bug #149775
  381. retry:
  382. // According to MSDN, first param is NULL, second is NULL,
  383. // third is the monitor
  384. TraceTag(ttidInfExt, "Removing print monitor...");
  385. if (!DeleteMonitor(NULL, NULL, const_cast<WCHAR*>(szPrintMonitorName)))
  386. {
  387. hr = HrFromLastWin32Error();
  388. if (hr == HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRINT_MONITOR))
  389. {
  390. // Don't complain if monitor is unknown.
  391. hr = S_OK;
  392. }
  393. else if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE))
  394. {
  395. // Spooler service isn't started. We need to start it
  396. TraceTag(ttidInfExt, "Spooler service wasn't started. Starting"
  397. " it now...");
  398. hr = HrEnableAndStartSpooler();
  399. if (S_OK == hr)
  400. {
  401. TraceTag(ttidInfExt, "Spooler service started successfully. "
  402. "Retrying...");
  403. goto retry;
  404. }
  405. }
  406. }
  407. TraceTag(ttidInfExt, "Done removing print monitor...");
  408. TraceError("HrRemovePrintMonitor", hr);
  409. return hr;
  410. }
  411. //+---------------------------------------------------------------------------
  412. //
  413. // Function: HrProcessAllINFExtensions
  414. //
  415. // Purpose: Handles support for all optional component extensions to the
  416. // INF file format.
  417. //
  418. // Arguments:
  419. // hinfFile [in] handle to INF to process
  420. // szInstallSection [in] Install section to process
  421. //
  422. // Returns: S_OK if success, setup API HRESULT otherwise
  423. //
  424. // Author: jeffspr 14 May 1997
  425. //
  426. // Notes:
  427. //
  428. HRESULT HrProcessAllINFExtensions(HINF hinfFile, PCWSTR szInstallSection)
  429. {
  430. HRESULT hr = S_OK;
  431. //
  432. // Handle SNMP Agent extension
  433. //
  434. hr = HrProcessInfExtension(hinfFile, szInstallSection, c_szSNMPSuffix,
  435. c_szSNMPAddLabel, c_szSNMPDelLabel,
  436. HrProcessSNMPAddSection,
  437. HrProcessSNMPRemoveSection);
  438. if (FAILED(hr) && hr != HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  439. goto err;
  440. //
  441. // Handle Print monitor/procedure extension
  442. //
  443. hr = HrProcessInfExtension(hinfFile, szInstallSection, c_szPrintSuffix,
  444. c_szPrintAddLabel, c_szPrintDelLabel,
  445. HrProcessPrintAddSection,
  446. HrProcessPrintRemoveSection);
  447. if (FAILED(hr) && hr != HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  448. goto err;
  449. hr = S_OK;
  450. err:
  451. TraceError("HrProcessAllINFExtensions", hr);
  452. return hr;
  453. }