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.

1004 lines
27 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. startup.c
  5. Abstract:
  6. This module:
  7. 1) Retrieves all the printer monitors
  8. 2) Verifies the fax printer monitor is installed
  9. 3) Retrieves all the printer ports
  10. 4) Verifies the fax printer port is installed
  11. 5) Retrieves all the printer drivers
  12. 6) Verifies the fax printer driver is installed
  13. 7) Retrieves all the printers
  14. 8) Verifies the fax printer is installed
  15. 9) Verifies fax is installed
  16. 10) Verifies the faxcom com objects are installed
  17. 11) Verifies the faxadmin com objects are installed
  18. 12) Verifies the routeext com objects are installed
  19. 13) Verifies the com objects are installed
  20. 14) Verifies the fax service is installed
  21. 15) Stops the fax service
  22. 16) Initializes FaxRcv
  23. 17) Initializes RAS
  24. Author:
  25. Steven Kehrli (steveke) 11/15/1997
  26. --*/
  27. #ifndef _STARTUP_C
  28. #define _STARTUP_C
  29. #include <winspool.h>
  30. #include <faxcom.h>
  31. #include <faxcom_i.c>
  32. #include <faxadmin.h>
  33. #include <faxadmin_i.c>
  34. #include <routeext.h>
  35. #include <routeext_i.c>
  36. #define FAX_MONITOR_NAME L"Windows NT Fax Monitor" // FAX_MONITOR_NAME is the name of the Fax Printer Monitor
  37. #define FAX_MONITOR_DLL L"msfaxmon.dll" // FAX_MONITOR_DLL is the name of the Fax Printer Monitor Dll
  38. #define FAX_PORT_NAME L"MSFAX:" // FAX_PORT_NAME is the name of the Fax Printer Port
  39. #define FAX_DRIVER_NAME L"Windows NT Fax Driver" // FAX_DRIVER_NAME is the name of the Fax Printer Driver
  40. #define FAX_DRIVER_DLL L"faxdrv.dll" // FAX_DRIVER_DLL is the name of the Fax Printer Driver Dll
  41. #define FAX_SERVICE L"Fax" // FAX_SERVICE is the name of the Fax Service
  42. PVOID
  43. fnLocalEnumPrinterMonitors(
  44. LPDWORD pdwNumPrinterMonitors
  45. )
  46. /*++
  47. Routine Description:
  48. Retrieves all the printer monitors
  49. Arguments:
  50. pdwNumPrinterMonitors - pointer to number of printer monitors
  51. Return Value:
  52. PVOID - pointer to the printer monitors info
  53. --*/
  54. {
  55. // pPrinterMonitorInfo is a pointer to a buffer of printer monitor info structures
  56. LPBYTE pPrinterMonitorInfo;
  57. // cb is the size of the buffer of printer driver info structures
  58. DWORD cb;
  59. *pdwNumPrinterMonitors = 0;
  60. // Get all printer monitors
  61. if ((!EnumMonitors(NULL, 2, NULL, 0, &cb, pdwNumPrinterMonitors)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  62. // EnumMonitors failed because the buffer is too small
  63. // cb is the size of the buffer needed, so allocate a buffer of that size
  64. pPrinterMonitorInfo = MemAllocMacro(cb);
  65. // Call EnumMonitors again with the correct size buffer
  66. if (!EnumMonitors(NULL, 2, pPrinterMonitorInfo, cb, &cb, pdwNumPrinterMonitors)) {
  67. // EnumMonitors failed
  68. // Free the buffer
  69. MemFreeMacro(pPrinterMonitorInfo);
  70. goto ExitLevel0;
  71. }
  72. // EnumMonitors succeeded, so return pointer to the buffer
  73. return pPrinterMonitorInfo;
  74. }
  75. ExitLevel0:
  76. // EnumMonitors failed
  77. DebugMacro(L"EnumMonitors() failed, ec = 0x%08x\n", GetLastError());
  78. // Return a NULL handle
  79. return NULL;
  80. }
  81. BOOL
  82. fnIsFaxPrinterMonitorInstalled(
  83. )
  84. /*++
  85. Routine Description:
  86. Verifies the fax printer monitor is installed
  87. Return Value:
  88. TRUE on success
  89. --*/
  90. {
  91. // szDllPath is the path where the fax printer monitor dll resides
  92. WCHAR szDllPath[_MAX_PATH];
  93. // pAllPrinterMonitors is the pointer to all printer monitors info
  94. LPMONITOR_INFO_2 pAllPrinterMonitors;
  95. // dwNumPrinterMonitors is the number of all printer monitors
  96. DWORD dwNumPrinterMonitors;
  97. // dwNumFaxPrinterMonitors is the number of fax printer monitors
  98. DWORD dwNumFaxPrinterMonitors;
  99. // dwIndex is a counter to enumerate each printer monitor
  100. DWORD dwIndex;
  101. // Clear the dll path
  102. ZeroMemory(szDllPath, sizeof(szDllPath));
  103. // Get the path
  104. if (GetSystemDirectory(szDllPath, sizeof(szDllPath)) == 0) {
  105. DebugMacro(L"GetSystemDirectory() failed, ec = 0x%08x\n", GetLastError());
  106. return FALSE;
  107. }
  108. // Concatenate the fax printer monitor dll with the path
  109. lstrcat(szDllPath, L"\\");
  110. lstrcat(szDllPath, FAX_MONITOR_DLL);
  111. // Verify fax printer monitor dll exists
  112. if (GetFileAttributes(szDllPath) == 0xFFFFFFFF) {
  113. DebugMacro(L"The Fax Printer Monitor DLL does not exist.\n");
  114. return FALSE;
  115. }
  116. // Get all printer monitors
  117. pAllPrinterMonitors = fnLocalEnumPrinterMonitors(&dwNumPrinterMonitors);
  118. if (!pAllPrinterMonitors)
  119. // Return FALSE
  120. return FALSE;
  121. // Determine the number of fax printer monitors
  122. for (dwIndex = 0, dwNumFaxPrinterMonitors = 0; dwIndex < dwNumPrinterMonitors; dwIndex++) {
  123. // A fax printer monitor is determined by comparing the name of the current printer monitor against the name of the fax printer monitor
  124. if ((!lstrcmpi(pAllPrinterMonitors[dwIndex].pName, FAX_MONITOR_NAME)) && (!lstrcmpi(pAllPrinterMonitors[dwIndex].pDLLName, FAX_MONITOR_DLL))) {
  125. // Name of the current printer monitor and the name of the fax printer monitor match
  126. // Increment the number of fax printer monitors
  127. dwNumFaxPrinterMonitors++;
  128. }
  129. }
  130. // Free all printer monitors
  131. MemFreeMacro(pAllPrinterMonitors);
  132. if (dwNumFaxPrinterMonitors == 1) {
  133. return TRUE;
  134. }
  135. else if (dwNumFaxPrinterMonitors > 1) {
  136. DebugMacro(L"The Fax Printer Monitor is installed more than once.\n");
  137. return FALSE;
  138. }
  139. else {
  140. DebugMacro(L"The Fax Printer Monitor is not installed.\n");
  141. return FALSE;
  142. }
  143. }
  144. PVOID
  145. fnLocalEnumPrinterPorts(
  146. LPDWORD pdwNumPrinterPorts
  147. )
  148. /*++
  149. Routine Description:
  150. Retrieves all the printer ports
  151. Arguments:
  152. pdwNumPrinterPorts - pointer to number of printer ports
  153. Return Value:
  154. PVOID - pointer to the printer ports info
  155. --*/
  156. {
  157. // pPrinterPortInfo is a pointer to a buffer of printer port info structures
  158. LPBYTE pPrinterPortInfo;
  159. // cb is the size of the buffer of printer port info structures
  160. DWORD cb;
  161. *pdwNumPrinterPorts = 0;
  162. // Get all printer ports
  163. if ((!EnumPorts(NULL, 2, NULL, 0, &cb, pdwNumPrinterPorts)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  164. // EnumPorts failed because the buffer is too small
  165. // cb is the size of the buffer needed, so allocate a buffer of that size
  166. pPrinterPortInfo = MemAllocMacro(cb);
  167. // Call EnumPorts again with the correct size buffer
  168. if (!EnumPorts(NULL, 2, pPrinterPortInfo, cb, &cb, pdwNumPrinterPorts)) {
  169. // EnumPorts failed
  170. // Free the buffer
  171. MemFreeMacro(pPrinterPortInfo);
  172. goto ExitLevel0;
  173. }
  174. // EnumPorts succeeded, so return pointer to the buffer
  175. return pPrinterPortInfo;
  176. }
  177. ExitLevel0:
  178. // EnumPorts failed
  179. DebugMacro(L"EnumPorts() failed, ec = 0x%08x\n", GetLastError());
  180. // Return a NULL handle
  181. return NULL;
  182. }
  183. BOOL
  184. fnIsFaxPrinterPortInstalled(
  185. )
  186. /*++
  187. Routine Description:
  188. Verifies the fax printer port is installed
  189. Return Value:
  190. TRUE on success
  191. --*/
  192. {
  193. // pAllPrinterPorts is the pointer to all printer ports info
  194. LPPORT_INFO_2 pAllPrinterPorts;
  195. // dwNumPrinterPorts is the number of all printer ports
  196. DWORD dwNumPrinterPorts;
  197. // dwNumFaxPrinterPorts is the number of fax printer ports
  198. DWORD dwNumFaxPrinterPorts;
  199. // dwIndex is a counter to enumerate each printer ports
  200. DWORD dwIndex;
  201. // Get all printer ports
  202. pAllPrinterPorts = fnLocalEnumPrinterPorts(&dwNumPrinterPorts);
  203. if (!pAllPrinterPorts) {
  204. // Return FALSE
  205. return FALSE;
  206. }
  207. // Determine the number of fax printer ports
  208. for (dwIndex = 0, dwNumFaxPrinterPorts = 0; dwIndex < dwNumPrinterPorts; dwIndex++) {
  209. // A fax printer port is determined by comparing the name of the current printer port against the name of the fax printer port
  210. if ((!lstrcmpi(pAllPrinterPorts[dwIndex].pPortName, FAX_PORT_NAME)) && (!lstrcmpi(pAllPrinterPorts[dwIndex].pMonitorName, FAX_MONITOR_NAME))) {
  211. // Name of the current printer port and the name of the fax printer port match
  212. // Increment the number of fax printer ports
  213. dwNumFaxPrinterPorts++;
  214. }
  215. }
  216. // Free all printer ports
  217. MemFreeMacro(pAllPrinterPorts);
  218. if (dwNumFaxPrinterPorts == 1) {
  219. return TRUE;
  220. }
  221. else if (dwNumFaxPrinterPorts > 1) {
  222. DebugMacro(L"The Fax Printer Port is installed more than once.\n");
  223. return FALSE;
  224. }
  225. else {
  226. DebugMacro(L"The Fax Printer Port is not installed.\n");
  227. return FALSE;
  228. }
  229. }
  230. PVOID
  231. fnLocalEnumPrinterDrivers(
  232. LPDWORD pdwNumPrinterDrivers
  233. )
  234. /*++
  235. Routine Description:
  236. Retrieves all the printer drivers
  237. Arguments:
  238. pdwNumPrinterDrivers - pointer to number of printer drivers
  239. Return Value:
  240. PVOID - pointer to the printer drivers info
  241. --*/
  242. {
  243. // pPrinterDriverInfo is a pointer to a buffer of printer driver info structures
  244. LPBYTE pPrinterDriverInfo;
  245. // cb is the size of the buffer of printer driver info structures
  246. DWORD cb;
  247. *pdwNumPrinterDrivers = 0;
  248. // Get all printer drivers
  249. if ((!EnumPrinterDrivers(NULL, NULL, 2, NULL, 0, &cb, pdwNumPrinterDrivers)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  250. // EnumPrinterDrivers failed because the buffer is too small
  251. // cb is the size of the buffer needed, so allocate a buffer of that size
  252. pPrinterDriverInfo = MemAllocMacro(cb);
  253. // Call EnumPrinterDrivers again with the correct size buffer
  254. if (!EnumPrinterDrivers(NULL, NULL, 2, pPrinterDriverInfo, cb, &cb, pdwNumPrinterDrivers)) {
  255. // EnumPrinterDrivers failed
  256. // Free the buffer
  257. MemFreeMacro(pPrinterDriverInfo);
  258. goto ExitLevel0;
  259. }
  260. // EnumPrinterDrivers succeeded, so return pointer to the buffer
  261. return pPrinterDriverInfo;
  262. }
  263. ExitLevel0:
  264. // EnumPrinterDrivers failed
  265. DebugMacro(L"EnumPrinterDrivers() failed, ec = 0x%08x\n", GetLastError());
  266. // Return a NULL handle
  267. return NULL;
  268. }
  269. BOOL
  270. fnIsFaxPrinterDriverInstalled(
  271. )
  272. /*++
  273. Routine Description:
  274. Verifies the fax printer driver is installed
  275. Return Value:
  276. TRUE on success
  277. --*/
  278. {
  279. // pAllPrinterDrivers is the pointer to all printer drivers info
  280. LPDRIVER_INFO_2 pAllPrinterDrivers;
  281. // dwNumPrinterDrivers is the number of all printer drivers
  282. DWORD dwNumPrinterDrivers;
  283. // dwNumFaxPrinterDrivers is the number of fax printer drivers
  284. DWORD dwNumFaxPrinterDrivers;
  285. // dwIndex is a counter to enumerate each printer driver
  286. DWORD dwIndex;
  287. DWORD cb;
  288. // Get all printer drivers
  289. pAllPrinterDrivers = fnLocalEnumPrinterDrivers(&dwNumPrinterDrivers);
  290. if (!pAllPrinterDrivers)
  291. // Return FALSE
  292. return FALSE;
  293. // Determine the number of fax printer drivers
  294. for (dwIndex = 0, dwNumFaxPrinterDrivers = 0; dwIndex < dwNumPrinterDrivers; dwIndex++) {
  295. // A fax printer driver is determined by comparing the name of the current printer driver against the name of the fax printer driver
  296. if ((!lstrcmpi(pAllPrinterDrivers[dwIndex].pName, FAX_DRIVER_NAME)) && (!lstrcmpi((LPWSTR) ((UINT_PTR) pAllPrinterDrivers[dwIndex].pDriverPath + (lstrlen(pAllPrinterDrivers[dwIndex].pDriverPath) - lstrlen(FAX_DRIVER_DLL)) * sizeof(WCHAR)), FAX_DRIVER_DLL)) && (GetFileAttributes(pAllPrinterDrivers[dwIndex].pDriverPath) != 0xFFFFFFFF)) {
  297. // Name of the current printer driver and the name of the fax printer driver match
  298. // Increment the number of fax printer drivers
  299. dwNumFaxPrinterDrivers++;
  300. }
  301. }
  302. // Free all printer drivers
  303. MemFreeMacro(pAllPrinterDrivers);
  304. if (dwNumFaxPrinterDrivers == 1) {
  305. return TRUE;
  306. }
  307. else if (dwNumFaxPrinterDrivers > 1) {
  308. DebugMacro(L"The Fax Printer Driver is installed more than once.\n");
  309. return FALSE;
  310. }
  311. else {
  312. DebugMacro(L"The Fax Printer Driver is not installed.\n");
  313. return FALSE;
  314. }
  315. }
  316. PVOID
  317. fnLocalEnumPrinters(
  318. LPDWORD pdwNumPrinters
  319. )
  320. /*++
  321. Routine Description:
  322. Retrieves all the printers
  323. Arguments:
  324. pdwNumPrinters - pointer to number of printers
  325. Return Value:
  326. PVOID - pointer to the printer info
  327. --*/
  328. {
  329. // pPrinterInfo is a pointer to a buffer of printer info structures
  330. LPBYTE pPrinterInfo;
  331. // cb is the size of the buffer of printer info structures
  332. DWORD cb;
  333. *pdwNumPrinters = 0;
  334. // Get all printers
  335. if ((!EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &cb, pdwNumPrinters)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  336. // EnumPrinters failed because the buffer is too small
  337. // cb is the size of the buffer needed, so allocate a buffer of that size
  338. pPrinterInfo = MemAllocMacro(cb);
  339. // Call EnumPrinters again with the correct size buffer
  340. if (!EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterInfo, cb, &cb, pdwNumPrinters)) {
  341. // EnumPrinters failed
  342. // Free the buffer
  343. MemFreeMacro(pPrinterInfo);
  344. goto ExitLevel0;
  345. }
  346. // EnumPrinters succeeded, so return pointer to the buffer
  347. return pPrinterInfo;
  348. }
  349. ExitLevel0:
  350. // EnumPrinters failed
  351. DebugMacro(L"EnumPrinters() failed, ec = 0x%08x\n", GetLastError());
  352. // Return a NULL handle
  353. return NULL;
  354. }
  355. BOOL
  356. fnIsFaxPrinterInstalled(
  357. )
  358. /*++
  359. Routine Description:
  360. Verifies the fax printer is installed
  361. Return Value:
  362. TRUE on success
  363. --*/
  364. {
  365. // pPrinterInfo is the pointer to all printers info
  366. LPPRINTER_INFO_2 pAllPrinters;
  367. // dwNumPrinters is the number of all printers
  368. DWORD dwNumPrinters;
  369. // dwNumFaxPrinters is the number of fax printers
  370. DWORD dwNumFaxPrinters;
  371. // dwIndex is a counter to enumerate each printer
  372. DWORD dwIndex;
  373. // Get all printers
  374. pAllPrinters = fnLocalEnumPrinters(&dwNumPrinters);
  375. if (!pAllPrinters)
  376. // Return FALSE
  377. return FALSE;
  378. // Determine the number of fax printers
  379. for (dwIndex = 0, dwNumFaxPrinters = 0; dwIndex < dwNumPrinters; dwIndex++) {
  380. // A fax printer is determined by comparing the name of the current printer driver against the name of the fax printer driver
  381. if ((!lstrcmpi(pAllPrinters[dwIndex].pDriverName, FAX_DRIVER_NAME)) && (!lstrcmpi(pAllPrinters[dwIndex].pPortName, FAX_PORT_NAME))) {
  382. // Name of the current printer driver and the name of the fax printer driver match
  383. // Increment the number of fax printers
  384. dwNumFaxPrinters++;
  385. }
  386. }
  387. // Free all printers
  388. MemFreeMacro(pAllPrinters);
  389. if (dwNumFaxPrinters) {
  390. return TRUE;
  391. }
  392. else {
  393. DebugMacro(L"A Fax Printer is not installed.\n");
  394. return FALSE;
  395. }
  396. }
  397. UINT
  398. fnIsFaxInstalled(
  399. )
  400. /*++
  401. Routine Description:
  402. Verifies fax is installed
  403. Return Value:
  404. UINT - resource id
  405. --*/
  406. {
  407. // Verify the fax printer monitor is installed
  408. if (!fnIsFaxPrinterMonitorInstalled()) {
  409. return IDS_FAX_MONITOR_NOT_INSTALLED;
  410. }
  411. // Verify the fax printer port is installed
  412. if (!fnIsFaxPrinterPortInstalled()) {
  413. return IDS_FAX_PORT_NOT_INSTALLED;
  414. }
  415. // Verify the fax printer driver is installed
  416. if (!fnIsFaxPrinterDriverInstalled()) {
  417. return IDS_FAX_DRIVER_NOT_INSTALLED;
  418. }
  419. // Verify the fax printer is installed
  420. if (!fnIsFaxPrinterInstalled()) {
  421. return IDS_FAX_PRINTER_NOT_INSTALLED;
  422. }
  423. return ERROR_SUCCESS;
  424. }
  425. BOOL
  426. fnIsFaxComInstalled(
  427. )
  428. /*++
  429. Routine Description:
  430. Verifies the faxcom com objects are installed
  431. Return Value:
  432. TRUE on success
  433. --*/
  434. {
  435. HRESULT hResult;
  436. IFaxTiff *pIFaxTiff;
  437. hResult = CoCreateInstance((REFCLSID) &CLSID_FaxTiff, NULL, CLSCTX_INPROC_SERVER, &IID_IFaxTiff, &pIFaxTiff);
  438. if (hResult != S_OK) {
  439. DebugMacro(L"CoCreateInstance(CLSID_FaxTiff, IID_IFaxTiff) failed, ec = 0x%08x\n", hResult);
  440. return FALSE;
  441. }
  442. pIFaxTiff->lpVtbl->Release(pIFaxTiff);
  443. return TRUE;
  444. }
  445. BOOL
  446. fnIsFaxAdminInstalled(
  447. )
  448. /*++
  449. Routine Description:
  450. Verifies the faxadmin com objects are installed
  451. Return Value:
  452. TRUE on success
  453. --*/
  454. {
  455. HRESULT hResult;
  456. IFaxSnapin *pIFaxSnapin;
  457. hResult = CoCreateInstance((REFCLSID) &CLSID_FaxSnapin, NULL, CLSCTX_INPROC_SERVER, &IID_IFaxSnapin, &pIFaxSnapin);
  458. if (hResult != S_OK) {
  459. DebugMacro(L"CoCreateInstance(CLSID_FaxSnapin, IID_IFaxSnapin) failed, ec = 0x%08x\n", hResult);
  460. return FALSE;
  461. }
  462. pIFaxSnapin->lpVtbl->Release(pIFaxSnapin);
  463. return TRUE;
  464. }
  465. BOOL
  466. fnIsRouteExtInstalled(
  467. )
  468. /*++
  469. Routine Description:
  470. Verifies the routeext com objects are installed
  471. Return Value:
  472. TRUE on success
  473. --*/
  474. {
  475. HRESULT hResult;
  476. IUnknown *pRoute;
  477. hResult = CoCreateInstance((REFCLSID) &CLSID_Route, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, &pRoute);
  478. if (hResult != S_OK) {
  479. DebugMacro(L"CoCreateInstance(CLSID_Route, IID_IUnknown) failed, ec = 0x%08x\n", hResult);
  480. return FALSE;
  481. }
  482. pRoute->lpVtbl->Release(pRoute);
  483. return TRUE;
  484. }
  485. UINT
  486. fnIsComInstalled(
  487. )
  488. /*++
  489. Routine Description:
  490. Verifies the com objects are installed
  491. Return Value:
  492. UINT - resource id
  493. --*/
  494. {
  495. HRESULT hResult;
  496. UINT uRslt;
  497. hResult = CoInitialize(NULL);
  498. if (hResult != S_OK) {
  499. DebugMacro(L"CoInitialize() failed, ec = 0x%08x\n", hResult);
  500. uRslt = IDS_COM_NOT_INITIALIZED;
  501. }
  502. if (!fnIsFaxComInstalled()) {
  503. uRslt = IDS_FAXCOM_NOT_INSTALLED;
  504. }
  505. if (!fnIsFaxAdminInstalled()) {
  506. uRslt = IDS_FAXADMIN_NOT_INSTALLED;
  507. }
  508. if (!fnIsRouteExtInstalled()) {
  509. uRslt = IDS_ROUTEEXT_NOT_INSTALLED;
  510. }
  511. uRslt = ERROR_SUCCESS;
  512. CoUninitialize();
  513. return uRslt;
  514. }
  515. BOOL
  516. fnIsFaxSvcInstalled(
  517. )
  518. /*++
  519. Routine Description:
  520. Verifies the fax service is installed
  521. Return Value:
  522. TRUE on success
  523. --*/
  524. {
  525. SC_HANDLE hManager = NULL;
  526. SC_HANDLE hService = NULL;
  527. // Open the service control manager
  528. hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
  529. if (!hManager) {
  530. DebugMacro(L"OpenSCManager() failed, ec = 0x%08x\n", GetLastError());
  531. return FALSE;
  532. }
  533. // Open the service
  534. hService = OpenService(hManager, FAX_SERVICE, SERVICE_ALL_ACCESS);
  535. if (!hService) {
  536. CloseServiceHandle(hManager);
  537. DebugMacro(L"OpenService() failed, ec = 0x%08x\n", GetLastError());
  538. return FALSE;
  539. }
  540. CloseServiceHandle(hService);
  541. CloseServiceHandle(hManager);
  542. return TRUE;
  543. }
  544. BOOL
  545. fnStopFaxSvc(
  546. )
  547. /*++
  548. Routine Description:
  549. Stops the fax service
  550. Return Value:
  551. TRUE on success
  552. --*/
  553. {
  554. SC_HANDLE hManager;
  555. SC_HANDLE hService;
  556. SERVICE_STATUS ServiceStatus;
  557. BOOL bRslt;
  558. bRslt = FALSE;
  559. // Open the service control manager
  560. hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
  561. if (!hManager) {
  562. DebugMacro(L"OpenSCManager() failed, ec = 0x%08x\n", GetLastError());
  563. goto ExitLevel0;
  564. }
  565. // Open the service
  566. hService = OpenService(hManager, FAX_SERVICE, SERVICE_ALL_ACCESS);
  567. if (!hService) {
  568. DebugMacro(L"OpenService() failed, ec = 0x%08x\n", GetLastError());
  569. goto ExitLevel0;
  570. }
  571. // Query the service status
  572. ZeroMemory(&ServiceStatus, sizeof(SERVICE_STATUS));
  573. if (!QueryServiceStatus(hService, &ServiceStatus)) {
  574. DebugMacro(L"QueryServiceStatus() failed, ec = 0x%08x\n", GetLastError());
  575. goto ExitLevel0;
  576. }
  577. if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) {
  578. // Service is stopped
  579. bRslt = TRUE;
  580. goto ExitLevel0;
  581. }
  582. // Stop the service
  583. if (!ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus)) {
  584. DebugMacro(L"ControlService() failed, ec = 0x%08x\n", GetLastError());
  585. goto ExitLevel0;
  586. }
  587. // Wait until the service is stopped
  588. ZeroMemory(&ServiceStatus, sizeof(SERVICE_STATUS));
  589. while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
  590. Sleep(1000);
  591. // Query the service status
  592. if (!QueryServiceStatus(hService, &ServiceStatus)) {
  593. DebugMacro(L"QueryServiceStatus() failed, ec = 0x%08x\n", GetLastError());
  594. goto ExitLevel0;
  595. }
  596. // Verify the service is stopped or stopping
  597. if (!((ServiceStatus.dwCurrentState == SERVICE_STOPPED) || (ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING))) {
  598. DebugMacro(L"The Fax Service is in an unexpected state. dwCurrentState: 0x%08x\n", ServiceStatus.dwCurrentState);
  599. goto ExitLevel0;
  600. }
  601. }
  602. bRslt = TRUE;
  603. Sleep(1000);
  604. ExitLevel0:
  605. if (hService) {
  606. CloseServiceHandle(hService);
  607. }
  608. if (hManager) {
  609. CloseServiceHandle(hManager);
  610. }
  611. return bRslt;
  612. }
  613. UINT
  614. fnInitializeFaxRcv(
  615. )
  616. /*++
  617. Routine Description:
  618. Initializes FaxRcv
  619. Return Value:
  620. UINT - resource id
  621. --*/
  622. {
  623. // szFaxRcvDll is the FaxRcv dll
  624. WCHAR szFaxRcvDll[_MAX_PATH];
  625. // hFaxRcvExtKey is the handle to the FaxRcv Extension Registry key
  626. HKEY hFaxRcvExtKey;
  627. // hRoutingMethodsKey is the handle to the FaxRcv Routing Methods Registry key
  628. HKEY hRoutingMethodsKey;
  629. // hFaxRcvMethodKey is the handle to the FaxRcv Method Registry key
  630. HKEY hFaxRcvMethodKey;
  631. DWORD dwDisposition;
  632. DWORD dwData;
  633. LPWSTR szData;
  634. UINT uRslt;
  635. uRslt = IDS_FAX_RCV_NOT_INITIALIZED;
  636. if (!fnIsFaxSvcInstalled()) {
  637. return IDS_FAX_SVC_NOT_INSTALLED;
  638. }
  639. if (!fnStopFaxSvc()) {
  640. return IDS_FAX_SVC_NOT_STOPPED;
  641. }
  642. ExpandEnvironmentStrings(IMAGENAME_EXT_REGDATA, szFaxRcvDll, sizeof(szFaxRcvDll) / sizeof(WCHAR));
  643. if (!lstrcmpi(IMAGENAME_EXT_REGDATA, szFaxRcvDll)) {
  644. return IDS_FAX_RCV_NOT_INITIALIZED;
  645. }
  646. // Copy the FaxRcv dll
  647. if (!CopyFile(FAXRCV_DLL, szFaxRcvDll, FALSE)) {
  648. return IDS_FAX_RCV_NOT_INITIALIZED;
  649. }
  650. // Create or open the FaxRcv Extension Registry key
  651. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, FAXRCV_EXT_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hFaxRcvExtKey, &dwDisposition) != ERROR_SUCCESS) {
  652. return IDS_FAX_RCV_NOT_INITIALIZED;
  653. }
  654. // Create or open the FaxRcv Routing Methods Registry key
  655. if (RegCreateKeyEx(hFaxRcvExtKey, ROUTINGMETHODS_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRoutingMethodsKey, &dwDisposition) != ERROR_SUCCESS) {
  656. goto ExitLevel0;
  657. }
  658. // Create or open the FaxRcv Method Registry key
  659. if (RegCreateKeyEx(hRoutingMethodsKey, FAXRCV_METHOD_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hFaxRcvMethodKey, &dwDisposition) != ERROR_SUCCESS) {
  660. goto ExitLevel1;
  661. }
  662. // Set FaxRcv Extension bEnable Registry value
  663. dwData = BENABLE_EXT_REGDATA;
  664. if (RegSetValueEx(hFaxRcvExtKey, BENABLE_EXT_REGVAL, 0, REG_DWORD, (PBYTE) &dwData, sizeof(DWORD)) != ERROR_SUCCESS) {
  665. goto ExitLevel2;
  666. }
  667. // Set FaxRcv Extension FriendlyName Registry value
  668. szData = FRIENDLYNAME_EXT_REGDATA;
  669. if (RegSetValueEx(hFaxRcvExtKey, FRIENDLYNAME_EXT_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) {
  670. goto ExitLevel2;
  671. }
  672. // Set FaxRcv Extension ImageName Registry value
  673. szData = IMAGENAME_EXT_REGDATA;
  674. if (RegSetValueEx(hFaxRcvExtKey, IMAGENAME_EXT_REGVAL, 0, REG_EXPAND_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) {
  675. goto ExitLevel2;
  676. }
  677. // Set FaxRcv Method FriendlyName Registry value
  678. szData = FRIENDLYNAME_METHOD_REGDATA;
  679. if (RegSetValueEx(hFaxRcvMethodKey, FRIENDLYNAME_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) {
  680. goto ExitLevel2;
  681. }
  682. // Set FaxRcv Method FunctionName Registry value
  683. szData = FUNCTIONNAME_METHOD_REGDATA;
  684. if (RegSetValueEx(hFaxRcvMethodKey, FUNCTIONNAME_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) {
  685. goto ExitLevel2;
  686. }
  687. // Set FaxRcv Method Guid Registry value
  688. szData = GUID_METHOD_REGDATA;
  689. if (RegSetValueEx(hFaxRcvMethodKey, GUID_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) {
  690. goto ExitLevel2;
  691. }
  692. // Set FaxRcv Method Priority Registry value
  693. dwData = PRIORITY_METHOD_REGDATA;
  694. if (RegSetValueEx(hFaxRcvMethodKey, PRIORITY_METHOD_REGVAL, 0, REG_DWORD, (PBYTE) &dwData, sizeof(DWORD)) != ERROR_SUCCESS) {
  695. goto ExitLevel2;
  696. }
  697. uRslt = ERROR_SUCCESS;
  698. ExitLevel2:
  699. // Close the FaxRcv Method Registry key
  700. RegCloseKey(hFaxRcvMethodKey);
  701. ExitLevel1:
  702. // Close the FaxRcv Routing Methods Registry key
  703. RegCloseKey(hRoutingMethodsKey);
  704. ExitLevel0:
  705. // Close the FaxRcv Extension Registry key
  706. RegCloseKey(hFaxRcvExtKey);
  707. return uRslt;
  708. }
  709. BOOL
  710. fnInitializeRas(
  711. )
  712. /*++
  713. Routine Description:
  714. Initializes RAS
  715. Return Value:
  716. TRUE on success
  717. --*/
  718. {
  719. // szDllPath is the path where the RAS dll resides
  720. WCHAR szDllPath[_MAX_PATH];
  721. // hInstance is the handle to the RAS dll
  722. HINSTANCE hInstance;
  723. // Clear the dll path
  724. ZeroMemory(szDllPath, sizeof(szDllPath));
  725. // Get the path
  726. if (GetSystemDirectory(szDllPath, sizeof(szDllPath)) == 0) {
  727. DebugMacro(L"GetSystemDirectory() failed, ec = 0x%08x\n", GetLastError());
  728. return FALSE;
  729. }
  730. // Concatenate the RAS dll with the path
  731. lstrcat(szDllPath, RASAPI32_DLL);
  732. // Get the handle to the RAS dll
  733. hInstance = LoadLibrary((LPCWSTR) szDllPath);
  734. if (!hInstance) {
  735. DebugMacro(L"LoadLibrary(%s) failed, ec = 0x%08x\n", szDllPath, GetLastError());
  736. return FALSE;
  737. }
  738. // Map all needed functions
  739. g_RasApi.hInstance = hInstance;
  740. // RasDial
  741. g_RasApi.RasDial = GetProcAddress(hInstance, "RasDialW");
  742. if (!g_RasApi.RasDial) {
  743. DebugMacro(L"GetProcAddress(RasDial) failed, ec = 0x%08x\n", GetLastError());
  744. FreeLibrary(hInstance);
  745. return FALSE;
  746. }
  747. // RasGetErrorString
  748. g_RasApi.RasGetErrorString = GetProcAddress(hInstance, "RasGetErrorStringW");
  749. if (!g_RasApi.RasGetErrorString) {
  750. DebugMacro(L"GetProcAddress(RasGetErrorString) failed, ec = 0x%08x\n", GetLastError());
  751. FreeLibrary(hInstance);
  752. return FALSE;
  753. }
  754. // RasGetConnectStatus
  755. g_RasApi.RasGetConnectStatus = GetProcAddress(hInstance, "RasGetConnectStatusW");
  756. if (!g_RasApi.RasGetConnectStatus) {
  757. DebugMacro(L"GetProcAddress(RasGetConnectStatus) failed, ec = 0x%08x\n", GetLastError());
  758. FreeLibrary(hInstance);
  759. return FALSE;
  760. }
  761. // RasGetConnectionStatistics
  762. g_RasApi.RasGetConnectionStatistics = GetProcAddress(hInstance, "RasGetConnectionStatistics");
  763. if (!g_RasApi.RasGetConnectionStatistics) {
  764. DebugMacro(L"GetProcAddress(RasGetConnectionStatistics) failed, ec = 0x%08x\n", GetLastError());
  765. FreeLibrary(hInstance);
  766. return FALSE;
  767. }
  768. // RasHangUp
  769. g_RasApi.RasHangUp = GetProcAddress(hInstance, "RasHangUpW");
  770. if (!g_RasApi.RasHangUp) {
  771. DebugMacro(L"GetProcAddress(RasHangUp) failed, ec = 0x%08x\n", GetLastError());
  772. FreeLibrary(hInstance);
  773. return FALSE;
  774. }
  775. return TRUE;
  776. }
  777. #endif