/*++ Copyright (c) 1997 Microsoft Corporation Module Name: startup.c Abstract: This module: 1) Retrieves all the printer monitors 2) Verifies the fax printer monitor is installed 3) Retrieves all the printer ports 4) Verifies the fax printer port is installed 5) Retrieves all the printer drivers 6) Verifies the fax printer driver is installed 7) Retrieves all the printers 8) Verifies the fax printer is installed 9) Verifies fax is installed 10) Verifies the faxcom com objects are installed 11) Verifies the faxadmin com objects are installed 12) Verifies the routeext com objects are installed 13) Verifies the com objects are installed 14) Verifies the fax service is installed 15) Stops the fax service 16) Initializes FaxRcv 17) Initializes RAS Author: Steven Kehrli (steveke) 11/15/1997 --*/ #ifndef _STARTUP_C #define _STARTUP_C #include #include #include #include #include #include #include #define FAX_MONITOR_NAME L"Windows NT Fax Monitor" // FAX_MONITOR_NAME is the name of the Fax Printer Monitor #define FAX_MONITOR_DLL L"msfaxmon.dll" // FAX_MONITOR_DLL is the name of the Fax Printer Monitor Dll #define FAX_PORT_NAME L"MSFAX:" // FAX_PORT_NAME is the name of the Fax Printer Port #define FAX_DRIVER_NAME L"Windows NT Fax Driver" // FAX_DRIVER_NAME is the name of the Fax Printer Driver #define FAX_DRIVER_DLL L"faxdrv.dll" // FAX_DRIVER_DLL is the name of the Fax Printer Driver Dll #define FAX_SERVICE L"Fax" // FAX_SERVICE is the name of the Fax Service PVOID fnLocalEnumPrinterMonitors( LPDWORD pdwNumPrinterMonitors ) /*++ Routine Description: Retrieves all the printer monitors Arguments: pdwNumPrinterMonitors - pointer to number of printer monitors Return Value: PVOID - pointer to the printer monitors info --*/ { // pPrinterMonitorInfo is a pointer to a buffer of printer monitor info structures LPBYTE pPrinterMonitorInfo; // cb is the size of the buffer of printer driver info structures DWORD cb; *pdwNumPrinterMonitors = 0; // Get all printer monitors if ((!EnumMonitors(NULL, 2, NULL, 0, &cb, pdwNumPrinterMonitors)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { // EnumMonitors failed because the buffer is too small // cb is the size of the buffer needed, so allocate a buffer of that size pPrinterMonitorInfo = MemAllocMacro(cb); // Call EnumMonitors again with the correct size buffer if (!EnumMonitors(NULL, 2, pPrinterMonitorInfo, cb, &cb, pdwNumPrinterMonitors)) { // EnumMonitors failed // Free the buffer MemFreeMacro(pPrinterMonitorInfo); goto ExitLevel0; } // EnumMonitors succeeded, so return pointer to the buffer return pPrinterMonitorInfo; } ExitLevel0: // EnumMonitors failed DebugMacro(L"EnumMonitors() failed, ec = 0x%08x\n", GetLastError()); // Return a NULL handle return NULL; } BOOL fnIsFaxPrinterMonitorInstalled( ) /*++ Routine Description: Verifies the fax printer monitor is installed Return Value: TRUE on success --*/ { // szDllPath is the path where the fax printer monitor dll resides WCHAR szDllPath[_MAX_PATH]; // pAllPrinterMonitors is the pointer to all printer monitors info LPMONITOR_INFO_2 pAllPrinterMonitors; // dwNumPrinterMonitors is the number of all printer monitors DWORD dwNumPrinterMonitors; // dwNumFaxPrinterMonitors is the number of fax printer monitors DWORD dwNumFaxPrinterMonitors; // dwIndex is a counter to enumerate each printer monitor DWORD dwIndex; // Clear the dll path ZeroMemory(szDllPath, sizeof(szDllPath)); // Get the path if (GetSystemDirectory(szDllPath, sizeof(szDllPath)) == 0) { DebugMacro(L"GetSystemDirectory() failed, ec = 0x%08x\n", GetLastError()); return FALSE; } // Concatenate the fax printer monitor dll with the path lstrcat(szDllPath, L"\\"); lstrcat(szDllPath, FAX_MONITOR_DLL); // Verify fax printer monitor dll exists if (GetFileAttributes(szDllPath) == 0xFFFFFFFF) { DebugMacro(L"The Fax Printer Monitor DLL does not exist.\n"); return FALSE; } // Get all printer monitors pAllPrinterMonitors = fnLocalEnumPrinterMonitors(&dwNumPrinterMonitors); if (!pAllPrinterMonitors) // Return FALSE return FALSE; // Determine the number of fax printer monitors for (dwIndex = 0, dwNumFaxPrinterMonitors = 0; dwIndex < dwNumPrinterMonitors; dwIndex++) { // A fax printer monitor is determined by comparing the name of the current printer monitor against the name of the fax printer monitor if ((!lstrcmpi(pAllPrinterMonitors[dwIndex].pName, FAX_MONITOR_NAME)) && (!lstrcmpi(pAllPrinterMonitors[dwIndex].pDLLName, FAX_MONITOR_DLL))) { // Name of the current printer monitor and the name of the fax printer monitor match // Increment the number of fax printer monitors dwNumFaxPrinterMonitors++; } } // Free all printer monitors MemFreeMacro(pAllPrinterMonitors); if (dwNumFaxPrinterMonitors == 1) { return TRUE; } else if (dwNumFaxPrinterMonitors > 1) { DebugMacro(L"The Fax Printer Monitor is installed more than once.\n"); return FALSE; } else { DebugMacro(L"The Fax Printer Monitor is not installed.\n"); return FALSE; } } PVOID fnLocalEnumPrinterPorts( LPDWORD pdwNumPrinterPorts ) /*++ Routine Description: Retrieves all the printer ports Arguments: pdwNumPrinterPorts - pointer to number of printer ports Return Value: PVOID - pointer to the printer ports info --*/ { // pPrinterPortInfo is a pointer to a buffer of printer port info structures LPBYTE pPrinterPortInfo; // cb is the size of the buffer of printer port info structures DWORD cb; *pdwNumPrinterPorts = 0; // Get all printer ports if ((!EnumPorts(NULL, 2, NULL, 0, &cb, pdwNumPrinterPorts)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { // EnumPorts failed because the buffer is too small // cb is the size of the buffer needed, so allocate a buffer of that size pPrinterPortInfo = MemAllocMacro(cb); // Call EnumPorts again with the correct size buffer if (!EnumPorts(NULL, 2, pPrinterPortInfo, cb, &cb, pdwNumPrinterPorts)) { // EnumPorts failed // Free the buffer MemFreeMacro(pPrinterPortInfo); goto ExitLevel0; } // EnumPorts succeeded, so return pointer to the buffer return pPrinterPortInfo; } ExitLevel0: // EnumPorts failed DebugMacro(L"EnumPorts() failed, ec = 0x%08x\n", GetLastError()); // Return a NULL handle return NULL; } BOOL fnIsFaxPrinterPortInstalled( ) /*++ Routine Description: Verifies the fax printer port is installed Return Value: TRUE on success --*/ { // pAllPrinterPorts is the pointer to all printer ports info LPPORT_INFO_2 pAllPrinterPorts; // dwNumPrinterPorts is the number of all printer ports DWORD dwNumPrinterPorts; // dwNumFaxPrinterPorts is the number of fax printer ports DWORD dwNumFaxPrinterPorts; // dwIndex is a counter to enumerate each printer ports DWORD dwIndex; // Get all printer ports pAllPrinterPorts = fnLocalEnumPrinterPorts(&dwNumPrinterPorts); if (!pAllPrinterPorts) { // Return FALSE return FALSE; } // Determine the number of fax printer ports for (dwIndex = 0, dwNumFaxPrinterPorts = 0; dwIndex < dwNumPrinterPorts; dwIndex++) { // A fax printer port is determined by comparing the name of the current printer port against the name of the fax printer port if ((!lstrcmpi(pAllPrinterPorts[dwIndex].pPortName, FAX_PORT_NAME)) && (!lstrcmpi(pAllPrinterPorts[dwIndex].pMonitorName, FAX_MONITOR_NAME))) { // Name of the current printer port and the name of the fax printer port match // Increment the number of fax printer ports dwNumFaxPrinterPorts++; } } // Free all printer ports MemFreeMacro(pAllPrinterPorts); if (dwNumFaxPrinterPorts == 1) { return TRUE; } else if (dwNumFaxPrinterPorts > 1) { DebugMacro(L"The Fax Printer Port is installed more than once.\n"); return FALSE; } else { DebugMacro(L"The Fax Printer Port is not installed.\n"); return FALSE; } } PVOID fnLocalEnumPrinterDrivers( LPDWORD pdwNumPrinterDrivers ) /*++ Routine Description: Retrieves all the printer drivers Arguments: pdwNumPrinterDrivers - pointer to number of printer drivers Return Value: PVOID - pointer to the printer drivers info --*/ { // pPrinterDriverInfo is a pointer to a buffer of printer driver info structures LPBYTE pPrinterDriverInfo; // cb is the size of the buffer of printer driver info structures DWORD cb; *pdwNumPrinterDrivers = 0; // Get all printer drivers if ((!EnumPrinterDrivers(NULL, NULL, 2, NULL, 0, &cb, pdwNumPrinterDrivers)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { // EnumPrinterDrivers failed because the buffer is too small // cb is the size of the buffer needed, so allocate a buffer of that size pPrinterDriverInfo = MemAllocMacro(cb); // Call EnumPrinterDrivers again with the correct size buffer if (!EnumPrinterDrivers(NULL, NULL, 2, pPrinterDriverInfo, cb, &cb, pdwNumPrinterDrivers)) { // EnumPrinterDrivers failed // Free the buffer MemFreeMacro(pPrinterDriverInfo); goto ExitLevel0; } // EnumPrinterDrivers succeeded, so return pointer to the buffer return pPrinterDriverInfo; } ExitLevel0: // EnumPrinterDrivers failed DebugMacro(L"EnumPrinterDrivers() failed, ec = 0x%08x\n", GetLastError()); // Return a NULL handle return NULL; } BOOL fnIsFaxPrinterDriverInstalled( ) /*++ Routine Description: Verifies the fax printer driver is installed Return Value: TRUE on success --*/ { // pAllPrinterDrivers is the pointer to all printer drivers info LPDRIVER_INFO_2 pAllPrinterDrivers; // dwNumPrinterDrivers is the number of all printer drivers DWORD dwNumPrinterDrivers; // dwNumFaxPrinterDrivers is the number of fax printer drivers DWORD dwNumFaxPrinterDrivers; // dwIndex is a counter to enumerate each printer driver DWORD dwIndex; DWORD cb; // Get all printer drivers pAllPrinterDrivers = fnLocalEnumPrinterDrivers(&dwNumPrinterDrivers); if (!pAllPrinterDrivers) // Return FALSE return FALSE; // Determine the number of fax printer drivers for (dwIndex = 0, dwNumFaxPrinterDrivers = 0; dwIndex < dwNumPrinterDrivers; dwIndex++) { // A fax printer driver is determined by comparing the name of the current printer driver against the name of the fax printer driver 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)) { // Name of the current printer driver and the name of the fax printer driver match // Increment the number of fax printer drivers dwNumFaxPrinterDrivers++; } } // Free all printer drivers MemFreeMacro(pAllPrinterDrivers); if (dwNumFaxPrinterDrivers == 1) { return TRUE; } else if (dwNumFaxPrinterDrivers > 1) { DebugMacro(L"The Fax Printer Driver is installed more than once.\n"); return FALSE; } else { DebugMacro(L"The Fax Printer Driver is not installed.\n"); return FALSE; } } PVOID fnLocalEnumPrinters( LPDWORD pdwNumPrinters ) /*++ Routine Description: Retrieves all the printers Arguments: pdwNumPrinters - pointer to number of printers Return Value: PVOID - pointer to the printer info --*/ { // pPrinterInfo is a pointer to a buffer of printer info structures LPBYTE pPrinterInfo; // cb is the size of the buffer of printer info structures DWORD cb; *pdwNumPrinters = 0; // Get all printers if ((!EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &cb, pdwNumPrinters)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { // EnumPrinters failed because the buffer is too small // cb is the size of the buffer needed, so allocate a buffer of that size pPrinterInfo = MemAllocMacro(cb); // Call EnumPrinters again with the correct size buffer if (!EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterInfo, cb, &cb, pdwNumPrinters)) { // EnumPrinters failed // Free the buffer MemFreeMacro(pPrinterInfo); goto ExitLevel0; } // EnumPrinters succeeded, so return pointer to the buffer return pPrinterInfo; } ExitLevel0: // EnumPrinters failed DebugMacro(L"EnumPrinters() failed, ec = 0x%08x\n", GetLastError()); // Return a NULL handle return NULL; } BOOL fnIsFaxPrinterInstalled( ) /*++ Routine Description: Verifies the fax printer is installed Return Value: TRUE on success --*/ { // pPrinterInfo is the pointer to all printers info LPPRINTER_INFO_2 pAllPrinters; // dwNumPrinters is the number of all printers DWORD dwNumPrinters; // dwNumFaxPrinters is the number of fax printers DWORD dwNumFaxPrinters; // dwIndex is a counter to enumerate each printer DWORD dwIndex; // Get all printers pAllPrinters = fnLocalEnumPrinters(&dwNumPrinters); if (!pAllPrinters) // Return FALSE return FALSE; // Determine the number of fax printers for (dwIndex = 0, dwNumFaxPrinters = 0; dwIndex < dwNumPrinters; dwIndex++) { // A fax printer is determined by comparing the name of the current printer driver against the name of the fax printer driver if ((!lstrcmpi(pAllPrinters[dwIndex].pDriverName, FAX_DRIVER_NAME)) && (!lstrcmpi(pAllPrinters[dwIndex].pPortName, FAX_PORT_NAME))) { // Name of the current printer driver and the name of the fax printer driver match // Increment the number of fax printers dwNumFaxPrinters++; } } // Free all printers MemFreeMacro(pAllPrinters); if (dwNumFaxPrinters) { return TRUE; } else { DebugMacro(L"A Fax Printer is not installed.\n"); return FALSE; } } UINT fnIsFaxInstalled( ) /*++ Routine Description: Verifies fax is installed Return Value: UINT - resource id --*/ { // Verify the fax printer monitor is installed if (!fnIsFaxPrinterMonitorInstalled()) { return IDS_FAX_MONITOR_NOT_INSTALLED; } // Verify the fax printer port is installed if (!fnIsFaxPrinterPortInstalled()) { return IDS_FAX_PORT_NOT_INSTALLED; } // Verify the fax printer driver is installed if (!fnIsFaxPrinterDriverInstalled()) { return IDS_FAX_DRIVER_NOT_INSTALLED; } // Verify the fax printer is installed if (!fnIsFaxPrinterInstalled()) { return IDS_FAX_PRINTER_NOT_INSTALLED; } return ERROR_SUCCESS; } BOOL fnIsFaxComInstalled( ) /*++ Routine Description: Verifies the faxcom com objects are installed Return Value: TRUE on success --*/ { HRESULT hResult; IFaxTiff *pIFaxTiff; hResult = CoCreateInstance((REFCLSID) &CLSID_FaxTiff, NULL, CLSCTX_INPROC_SERVER, &IID_IFaxTiff, &pIFaxTiff); if (hResult != S_OK) { DebugMacro(L"CoCreateInstance(CLSID_FaxTiff, IID_IFaxTiff) failed, ec = 0x%08x\n", hResult); return FALSE; } pIFaxTiff->lpVtbl->Release(pIFaxTiff); return TRUE; } BOOL fnIsFaxAdminInstalled( ) /*++ Routine Description: Verifies the faxadmin com objects are installed Return Value: TRUE on success --*/ { HRESULT hResult; IFaxSnapin *pIFaxSnapin; hResult = CoCreateInstance((REFCLSID) &CLSID_FaxSnapin, NULL, CLSCTX_INPROC_SERVER, &IID_IFaxSnapin, &pIFaxSnapin); if (hResult != S_OK) { DebugMacro(L"CoCreateInstance(CLSID_FaxSnapin, IID_IFaxSnapin) failed, ec = 0x%08x\n", hResult); return FALSE; } pIFaxSnapin->lpVtbl->Release(pIFaxSnapin); return TRUE; } BOOL fnIsRouteExtInstalled( ) /*++ Routine Description: Verifies the routeext com objects are installed Return Value: TRUE on success --*/ { HRESULT hResult; IUnknown *pRoute; hResult = CoCreateInstance((REFCLSID) &CLSID_Route, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, &pRoute); if (hResult != S_OK) { DebugMacro(L"CoCreateInstance(CLSID_Route, IID_IUnknown) failed, ec = 0x%08x\n", hResult); return FALSE; } pRoute->lpVtbl->Release(pRoute); return TRUE; } UINT fnIsComInstalled( ) /*++ Routine Description: Verifies the com objects are installed Return Value: UINT - resource id --*/ { HRESULT hResult; UINT uRslt; hResult = CoInitialize(NULL); if (hResult != S_OK) { DebugMacro(L"CoInitialize() failed, ec = 0x%08x\n", hResult); uRslt = IDS_COM_NOT_INITIALIZED; } if (!fnIsFaxComInstalled()) { uRslt = IDS_FAXCOM_NOT_INSTALLED; } if (!fnIsFaxAdminInstalled()) { uRslt = IDS_FAXADMIN_NOT_INSTALLED; } if (!fnIsRouteExtInstalled()) { uRslt = IDS_ROUTEEXT_NOT_INSTALLED; } uRslt = ERROR_SUCCESS; CoUninitialize(); return uRslt; } BOOL fnIsFaxSvcInstalled( ) /*++ Routine Description: Verifies the fax service is installed Return Value: TRUE on success --*/ { SC_HANDLE hManager = NULL; SC_HANDLE hService = NULL; // Open the service control manager hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (!hManager) { DebugMacro(L"OpenSCManager() failed, ec = 0x%08x\n", GetLastError()); return FALSE; } // Open the service hService = OpenService(hManager, FAX_SERVICE, SERVICE_ALL_ACCESS); if (!hService) { CloseServiceHandle(hManager); DebugMacro(L"OpenService() failed, ec = 0x%08x\n", GetLastError()); return FALSE; } CloseServiceHandle(hService); CloseServiceHandle(hManager); return TRUE; } BOOL fnStopFaxSvc( ) /*++ Routine Description: Stops the fax service Return Value: TRUE on success --*/ { SC_HANDLE hManager; SC_HANDLE hService; SERVICE_STATUS ServiceStatus; BOOL bRslt; bRslt = FALSE; // Open the service control manager hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (!hManager) { DebugMacro(L"OpenSCManager() failed, ec = 0x%08x\n", GetLastError()); goto ExitLevel0; } // Open the service hService = OpenService(hManager, FAX_SERVICE, SERVICE_ALL_ACCESS); if (!hService) { DebugMacro(L"OpenService() failed, ec = 0x%08x\n", GetLastError()); goto ExitLevel0; } // Query the service status ZeroMemory(&ServiceStatus, sizeof(SERVICE_STATUS)); if (!QueryServiceStatus(hService, &ServiceStatus)) { DebugMacro(L"QueryServiceStatus() failed, ec = 0x%08x\n", GetLastError()); goto ExitLevel0; } if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) { // Service is stopped bRslt = TRUE; goto ExitLevel0; } // Stop the service if (!ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus)) { DebugMacro(L"ControlService() failed, ec = 0x%08x\n", GetLastError()); goto ExitLevel0; } // Wait until the service is stopped ZeroMemory(&ServiceStatus, sizeof(SERVICE_STATUS)); while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) { Sleep(1000); // Query the service status if (!QueryServiceStatus(hService, &ServiceStatus)) { DebugMacro(L"QueryServiceStatus() failed, ec = 0x%08x\n", GetLastError()); goto ExitLevel0; } // Verify the service is stopped or stopping if (!((ServiceStatus.dwCurrentState == SERVICE_STOPPED) || (ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING))) { DebugMacro(L"The Fax Service is in an unexpected state. dwCurrentState: 0x%08x\n", ServiceStatus.dwCurrentState); goto ExitLevel0; } } bRslt = TRUE; Sleep(1000); ExitLevel0: if (hService) { CloseServiceHandle(hService); } if (hManager) { CloseServiceHandle(hManager); } return bRslt; } UINT fnInitializeFaxRcv( ) /*++ Routine Description: Initializes FaxRcv Return Value: UINT - resource id --*/ { // szFaxRcvDll is the FaxRcv dll WCHAR szFaxRcvDll[_MAX_PATH]; // hFaxRcvExtKey is the handle to the FaxRcv Extension Registry key HKEY hFaxRcvExtKey; // hRoutingMethodsKey is the handle to the FaxRcv Routing Methods Registry key HKEY hRoutingMethodsKey; // hFaxRcvMethodKey is the handle to the FaxRcv Method Registry key HKEY hFaxRcvMethodKey; DWORD dwDisposition; DWORD dwData; LPWSTR szData; UINT uRslt; uRslt = IDS_FAX_RCV_NOT_INITIALIZED; if (!fnIsFaxSvcInstalled()) { return IDS_FAX_SVC_NOT_INSTALLED; } if (!fnStopFaxSvc()) { return IDS_FAX_SVC_NOT_STOPPED; } ExpandEnvironmentStrings(IMAGENAME_EXT_REGDATA, szFaxRcvDll, sizeof(szFaxRcvDll) / sizeof(WCHAR)); if (!lstrcmpi(IMAGENAME_EXT_REGDATA, szFaxRcvDll)) { return IDS_FAX_RCV_NOT_INITIALIZED; } // Copy the FaxRcv dll if (!CopyFile(FAXRCV_DLL, szFaxRcvDll, FALSE)) { return IDS_FAX_RCV_NOT_INITIALIZED; } // Create or open the FaxRcv Extension Registry key if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, FAXRCV_EXT_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hFaxRcvExtKey, &dwDisposition) != ERROR_SUCCESS) { return IDS_FAX_RCV_NOT_INITIALIZED; } // Create or open the FaxRcv Routing Methods Registry key if (RegCreateKeyEx(hFaxRcvExtKey, ROUTINGMETHODS_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRoutingMethodsKey, &dwDisposition) != ERROR_SUCCESS) { goto ExitLevel0; } // Create or open the FaxRcv Method Registry key if (RegCreateKeyEx(hRoutingMethodsKey, FAXRCV_METHOD_REGKEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hFaxRcvMethodKey, &dwDisposition) != ERROR_SUCCESS) { goto ExitLevel1; } // Set FaxRcv Extension bEnable Registry value dwData = BENABLE_EXT_REGDATA; if (RegSetValueEx(hFaxRcvExtKey, BENABLE_EXT_REGVAL, 0, REG_DWORD, (PBYTE) &dwData, sizeof(DWORD)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Extension FriendlyName Registry value szData = FRIENDLYNAME_EXT_REGDATA; if (RegSetValueEx(hFaxRcvExtKey, FRIENDLYNAME_EXT_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Extension ImageName Registry value szData = IMAGENAME_EXT_REGDATA; if (RegSetValueEx(hFaxRcvExtKey, IMAGENAME_EXT_REGVAL, 0, REG_EXPAND_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Method FriendlyName Registry value szData = FRIENDLYNAME_METHOD_REGDATA; if (RegSetValueEx(hFaxRcvMethodKey, FRIENDLYNAME_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Method FunctionName Registry value szData = FUNCTIONNAME_METHOD_REGDATA; if (RegSetValueEx(hFaxRcvMethodKey, FUNCTIONNAME_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Method Guid Registry value szData = GUID_METHOD_REGDATA; if (RegSetValueEx(hFaxRcvMethodKey, GUID_METHOD_REGVAL, 0, REG_SZ, (PBYTE) szData, (lstrlen(szData) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS) { goto ExitLevel2; } // Set FaxRcv Method Priority Registry value dwData = PRIORITY_METHOD_REGDATA; if (RegSetValueEx(hFaxRcvMethodKey, PRIORITY_METHOD_REGVAL, 0, REG_DWORD, (PBYTE) &dwData, sizeof(DWORD)) != ERROR_SUCCESS) { goto ExitLevel2; } uRslt = ERROR_SUCCESS; ExitLevel2: // Close the FaxRcv Method Registry key RegCloseKey(hFaxRcvMethodKey); ExitLevel1: // Close the FaxRcv Routing Methods Registry key RegCloseKey(hRoutingMethodsKey); ExitLevel0: // Close the FaxRcv Extension Registry key RegCloseKey(hFaxRcvExtKey); return uRslt; } BOOL fnInitializeRas( ) /*++ Routine Description: Initializes RAS Return Value: TRUE on success --*/ { // szDllPath is the path where the RAS dll resides WCHAR szDllPath[_MAX_PATH]; // hInstance is the handle to the RAS dll HINSTANCE hInstance; // Clear the dll path ZeroMemory(szDllPath, sizeof(szDllPath)); // Get the path if (GetSystemDirectory(szDllPath, sizeof(szDllPath)) == 0) { DebugMacro(L"GetSystemDirectory() failed, ec = 0x%08x\n", GetLastError()); return FALSE; } // Concatenate the RAS dll with the path lstrcat(szDllPath, RASAPI32_DLL); // Get the handle to the RAS dll hInstance = LoadLibrary((LPCWSTR) szDllPath); if (!hInstance) { DebugMacro(L"LoadLibrary(%s) failed, ec = 0x%08x\n", szDllPath, GetLastError()); return FALSE; } // Map all needed functions g_RasApi.hInstance = hInstance; // RasDial g_RasApi.RasDial = GetProcAddress(hInstance, "RasDialW"); if (!g_RasApi.RasDial) { DebugMacro(L"GetProcAddress(RasDial) failed, ec = 0x%08x\n", GetLastError()); FreeLibrary(hInstance); return FALSE; } // RasGetErrorString g_RasApi.RasGetErrorString = GetProcAddress(hInstance, "RasGetErrorStringW"); if (!g_RasApi.RasGetErrorString) { DebugMacro(L"GetProcAddress(RasGetErrorString) failed, ec = 0x%08x\n", GetLastError()); FreeLibrary(hInstance); return FALSE; } // RasGetConnectStatus g_RasApi.RasGetConnectStatus = GetProcAddress(hInstance, "RasGetConnectStatusW"); if (!g_RasApi.RasGetConnectStatus) { DebugMacro(L"GetProcAddress(RasGetConnectStatus) failed, ec = 0x%08x\n", GetLastError()); FreeLibrary(hInstance); return FALSE; } // RasGetConnectionStatistics g_RasApi.RasGetConnectionStatistics = GetProcAddress(hInstance, "RasGetConnectionStatistics"); if (!g_RasApi.RasGetConnectionStatistics) { DebugMacro(L"GetProcAddress(RasGetConnectionStatistics) failed, ec = 0x%08x\n", GetLastError()); FreeLibrary(hInstance); return FALSE; } // RasHangUp g_RasApi.RasHangUp = GetProcAddress(hInstance, "RasHangUpW"); if (!g_RasApi.RasHangUp) { DebugMacro(L"GetProcAddress(RasHangUp) failed, ec = 0x%08x\n", GetLastError()); FreeLibrary(hInstance); return FALSE; } return TRUE; } #endif