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.

1503 lines
44 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. faxdev.c
  5. Abstract:
  6. This module contains all access to the
  7. FAX device providers.
  8. Author:
  9. Wesley Witt (wesw) 22-Jan-1996
  10. Revision History:
  11. --*/
  12. #include "faxsvc.h"
  13. #pragma hdrstop
  14. #ifdef DBG
  15. #define DebugDumpProviderRegistryInfo(lpcProviderInfo,lptstrPrefix)\
  16. DebugDumpProviderRegistryInfoFunc(lpcProviderInfo,lptstrPrefix)
  17. BOOL DebugDumpProviderRegistryInfoFunc(const REG_DEVICE_PROVIDER * lpcProviderInfo, LPTSTR lptstrPrefix);
  18. #else
  19. #define DebugDumpProviderRegistryInfo(lpcProviderInfo,lptstrPrefix)
  20. #endif
  21. typedef struct STATUS_CODE_MAP_tag
  22. {
  23. DWORD dwDeviceStatus;
  24. DWORD dwExtendedStatus;
  25. } STATUS_CODE_MAP;
  26. STATUS_CODE_MAP const gc_CodeMap[]=
  27. {
  28. { FPS_INITIALIZING, FSPI_ES_INITIALIZING },
  29. { FPS_DIALING, FSPI_ES_DIALING },
  30. { FPS_SENDING, FSPI_ES_TRANSMITTING },
  31. { FPS_RECEIVING, FSPI_ES_RECEIVING },
  32. { FPS_SENDING, FSPI_ES_TRANSMITTING },
  33. { FPS_HANDLED, FSPI_ES_HANDLED },
  34. { FPS_UNAVAILABLE, FSPI_ES_LINE_UNAVAILABLE },
  35. { FPS_BUSY, FSPI_ES_BUSY },
  36. { FPS_NO_ANSWER, FSPI_ES_NO_ANSWER },
  37. { FPS_BAD_ADDRESS, FSPI_ES_BAD_ADDRESS },
  38. { FPS_NO_DIAL_TONE, FSPI_ES_NO_DIAL_TONE },
  39. { FPS_DISCONNECTED, FSPI_ES_DISCONNECTED },
  40. { FPS_FATAL_ERROR, FSPI_ES_FATAL_ERROR },
  41. { FPS_NOT_FAX_CALL, FSPI_ES_NOT_FAX_CALL },
  42. { FPS_CALL_DELAYED, FSPI_ES_CALL_DELAYED },
  43. { FPS_CALL_BLACKLISTED, FSPI_ES_CALL_BLACKLISTED },
  44. { FPS_ANSWERED, FSPI_ES_ANSWERED },
  45. { FPS_COMPLETED, -1},
  46. { FPS_ABORTING, -1}
  47. };
  48. static BOOL GetLegacyProviderEntryPoints(HMODULE hModule, PDEVICE_PROVIDER lpProvider);
  49. LIST_ENTRY g_DeviceProvidersListHead;
  50. void
  51. UnloadDeviceProvider(
  52. PDEVICE_PROVIDER pDeviceProvider
  53. )
  54. {
  55. DEBUG_FUNCTION_NAME(TEXT("UnloadDeviceProvider"));
  56. Assert (pDeviceProvider);
  57. if (pDeviceProvider->hModule)
  58. {
  59. FreeLibrary( pDeviceProvider->hModule );
  60. }
  61. if (pDeviceProvider->HeapHandle &&
  62. FALSE == pDeviceProvider->fMicrosoftExtension)
  63. {
  64. HeapDestroy(pDeviceProvider->HeapHandle);
  65. }
  66. MemFree (pDeviceProvider);
  67. return;
  68. }
  69. void
  70. UnloadDeviceProviders(
  71. void
  72. )
  73. /*++
  74. Routine Description:
  75. Unloads all loaded device providers.
  76. Arguments:
  77. None.
  78. Return Value:
  79. TRUE - The device providers are initialized.
  80. FALSE - The device providers could not be initialized.
  81. --*/
  82. {
  83. PLIST_ENTRY pNext;
  84. PDEVICE_PROVIDER pProvider;
  85. pNext = g_DeviceProvidersListHead.Flink;
  86. while ((ULONG_PTR)pNext != (ULONG_PTR)&g_DeviceProvidersListHead)
  87. {
  88. pProvider = CONTAINING_RECORD( pNext, DEVICE_PROVIDER, ListEntry );
  89. pNext = pProvider->ListEntry.Flink;
  90. RemoveEntryList(&pProvider->ListEntry);
  91. UnloadDeviceProvider(pProvider);
  92. }
  93. return;
  94. } // UnloadDeviceProviders
  95. BOOL
  96. LoadDeviceProviders(
  97. PREG_FAX_SERVICE FaxReg
  98. )
  99. /*++
  100. Routine Description:
  101. Initializes all registered device providers.
  102. This function read the system registry to
  103. determine what device providers are available.
  104. All registered device providers are given the
  105. opportunity to initialize. Any failure causes
  106. the device provider to be unloaded.
  107. Arguments:
  108. None.
  109. Return Value:
  110. TRUE - The device providers are initialized.
  111. FALSE - The device providers could not be initialized.
  112. --*/
  113. {
  114. DWORD i;
  115. HMODULE hModule = NULL;
  116. PDEVICE_PROVIDER DeviceProvider = NULL;
  117. BOOL bAllLoaded = TRUE;
  118. DWORD ec = ERROR_SUCCESS;
  119. DEBUG_FUNCTION_NAME(TEXT("LoadDeviceProviders"));
  120. for (i = 0; i < FaxReg->DeviceProviderCount; i++)
  121. {
  122. WCHAR wszImageFileName[_MAX_FNAME] = {0};
  123. WCHAR wszImageFileExt[_MAX_EXT] = {0};
  124. DeviceProvider = NULL; // so we won't attempt to free it on cleanup
  125. hModule = NULL; // so we won't attempt to free it on cleanup
  126. DebugPrintEx(
  127. DEBUG_MSG,
  128. TEXT("Loading provider #%d."),
  129. i);
  130. //
  131. // Allocate buffer for provider data
  132. //
  133. DeviceProvider = (PDEVICE_PROVIDER) MemAlloc( sizeof(DEVICE_PROVIDER) );
  134. if (!DeviceProvider)
  135. {
  136. DebugPrintEx(
  137. DEBUG_ERR,
  138. TEXT("Could not allocate memory for device provider [%s] (ec: %ld)"),
  139. FaxReg->DeviceProviders[i].ImageName ,
  140. GetLastError());
  141. FaxLog(
  142. FAXLOG_CATEGORY_INIT,
  143. FAXLOG_LEVEL_MIN,
  144. 2,
  145. MSG_FSP_INIT_FAILED_MEM,
  146. FaxReg->DeviceProviders[i].FriendlyName,
  147. FaxReg->DeviceProviders[i].ImageName
  148. );
  149. goto InitializationFailure;
  150. }
  151. //
  152. // Init the provider's data
  153. //
  154. memset(DeviceProvider,0,sizeof(DEVICE_PROVIDER));
  155. wcsncpy( DeviceProvider->FriendlyName,
  156. FaxReg->DeviceProviders[i].FriendlyName ?
  157. FaxReg->DeviceProviders[i].FriendlyName :
  158. EMPTY_STRING,
  159. ARR_SIZE(DeviceProvider->FriendlyName)-1);
  160. wcsncpy( DeviceProvider->ImageName,
  161. FaxReg->DeviceProviders[i].ImageName ?
  162. FaxReg->DeviceProviders[i].ImageName :
  163. EMPTY_STRING,
  164. ARR_SIZE(DeviceProvider->ImageName)-1);
  165. wcsncpy( DeviceProvider->ProviderName,
  166. FaxReg->DeviceProviders[i].ProviderName ?
  167. FaxReg->DeviceProviders[i].ProviderName :
  168. EMPTY_STRING,
  169. ARR_SIZE(DeviceProvider->ProviderName)-1);
  170. wcsncpy( DeviceProvider->szGUID,
  171. FaxReg->DeviceProviders[i].lptstrGUID ?
  172. FaxReg->DeviceProviders[i].lptstrGUID :
  173. EMPTY_STRING,
  174. ARR_SIZE(DeviceProvider->szGUID)-1);
  175. _wsplitpath( DeviceProvider->ImageName, NULL, NULL, wszImageFileName, wszImageFileExt );
  176. if (_wcsicmp( wszImageFileName, FAX_T30_MODULE_NAME ) == 0 &&
  177. _wcsicmp( wszImageFileExt, TEXT(".DLL") ) == 0)
  178. {
  179. DeviceProvider->fMicrosoftExtension = TRUE;
  180. }
  181. DeviceProvider->dwAPIVersion = FaxReg->DeviceProviders[i].dwAPIVersion;
  182. if (FSPI_API_VERSION_1 != DeviceProvider->dwAPIVersion)
  183. {
  184. //
  185. // We do not support this API version. Could only happen if some one messed up the registry
  186. //
  187. DebugPrintEx(
  188. DEBUG_ERR,
  189. TEXT("FSPI API version [0x%08x] unsupported."),
  190. DeviceProvider->dwAPIVersion);
  191. FaxLog(
  192. FAXLOG_CATEGORY_INIT,
  193. FAXLOG_LEVEL_MIN,
  194. 3,
  195. MSG_FSP_INIT_FAILED_UNSUPPORTED_FSPI,
  196. FaxReg->DeviceProviders[i].FriendlyName,
  197. FaxReg->DeviceProviders[i].ImageName,
  198. DWORD2HEX(DeviceProvider->dwAPIVersion)
  199. );
  200. DeviceProvider->Status = FAX_PROVIDER_STATUS_BAD_VERSION;
  201. DeviceProvider->dwLastError = ERROR_GEN_FAILURE;
  202. goto InitializationFailure;
  203. }
  204. //
  205. // Try to load the module
  206. //
  207. DebugDumpProviderRegistryInfo(&FaxReg->DeviceProviders[i],TEXT("\t"));
  208. hModule = LoadLibrary( DeviceProvider->ImageName );
  209. if (!hModule)
  210. {
  211. ec = GetLastError();
  212. DebugPrintEx(
  213. DEBUG_ERR,
  214. TEXT("LoadLibrary() failed: [%s] (ec: %ld)"),
  215. FaxReg->DeviceProviders[i].ImageName,
  216. ec);
  217. FaxLog(
  218. FAXLOG_CATEGORY_INIT,
  219. FAXLOG_LEVEL_MIN,
  220. 3,
  221. MSG_FSP_INIT_FAILED_LOAD,
  222. FaxReg->DeviceProviders[i].FriendlyName,
  223. FaxReg->DeviceProviders[i].ImageName,
  224. DWORD2DECIMAL(ec)
  225. );
  226. DeviceProvider->Status = FAX_PROVIDER_STATUS_CANT_LOAD;
  227. DeviceProvider->dwLastError = ec;
  228. goto InitializationFailure;
  229. }
  230. DeviceProvider->hModule = hModule;
  231. //
  232. // Retrieve the FSP's version from the DLL
  233. //
  234. DeviceProvider->Version.dwSizeOfStruct = sizeof (FAX_VERSION);
  235. ec = GetFileVersion ( FaxReg->DeviceProviders[i].ImageName,
  236. &DeviceProvider->Version
  237. );
  238. if (ERROR_SUCCESS != ec)
  239. {
  240. //
  241. // If the FSP's DLL does not have version data or the
  242. // version data is non-retrievable, we consider this a
  243. // warning (debug print) but carry on with the DLL's load.
  244. //
  245. DebugPrintEx(
  246. DEBUG_ERR,
  247. TEXT("GetFileVersion() failed: [%s] (ec: %ld)"),
  248. FaxReg->DeviceProviders[i].ImageName,
  249. ec);
  250. }
  251. //
  252. // Link - find the entry points and store them
  253. //
  254. if (FSPI_API_VERSION_1 == DeviceProvider->dwAPIVersion)
  255. {
  256. if (!GetLegacyProviderEntryPoints(hModule,DeviceProvider))
  257. {
  258. ec = GetLastError ();
  259. DebugPrintEx(
  260. DEBUG_ERR,
  261. TEXT("GetLegacyProviderEntryPoints() failed. (ec: %ld)"),
  262. ec);
  263. FaxLog(
  264. FAXLOG_CATEGORY_INIT,
  265. FAXLOG_LEVEL_MIN,
  266. 3,
  267. MSG_FSP_INIT_FAILED_INVALID_FSPI,
  268. FaxReg->DeviceProviders[i].FriendlyName,
  269. FaxReg->DeviceProviders[i].ImageName,
  270. DWORD2DECIMAL(ec)
  271. );
  272. DeviceProvider->Status = FAX_PROVIDER_STATUS_CANT_LINK;
  273. DeviceProvider->dwLastError = ec;
  274. goto InitializationFailure;
  275. }
  276. //
  277. // create the device provider's heap
  278. //
  279. DeviceProvider->HeapHandle = DeviceProvider->fMicrosoftExtension ?
  280. GetProcessHeap() : HeapCreate( 0, 1024*100, 1024*1024*2 );
  281. if (!DeviceProvider->HeapHandle)
  282. {
  283. ec = GetLastError ();
  284. DebugPrintEx(
  285. DEBUG_ERR,
  286. TEXT("HeapCreate() failed for device provider heap handle (ec: %ld)"),
  287. ec);
  288. FaxLog(
  289. FAXLOG_CATEGORY_INIT,
  290. FAXLOG_LEVEL_MIN,
  291. 2,
  292. MSG_FSP_INIT_FAILED_MEM,
  293. FaxReg->DeviceProviders[i].FriendlyName,
  294. FaxReg->DeviceProviders[i].ImageName
  295. );
  296. DeviceProvider->Status = FAX_PROVIDER_STATUS_SERVER_ERROR;
  297. DeviceProvider->dwLastError = ec;
  298. goto InitializationFailure;
  299. }
  300. }
  301. else
  302. {
  303. //
  304. // Unknown API version
  305. //
  306. DebugPrintEx(
  307. DEBUG_ERR,
  308. TEXT("FSPI API version [0x%08x] unsupported."),
  309. DeviceProvider->dwAPIVersion);
  310. FaxLog(
  311. FAXLOG_CATEGORY_INIT,
  312. FAXLOG_LEVEL_MIN,
  313. 3,
  314. MSG_FSP_INIT_FAILED_UNSUPPORTED_FSPI,
  315. FaxReg->DeviceProviders[i].FriendlyName,
  316. FaxReg->DeviceProviders[i].ImageName,
  317. DWORD2HEX(DeviceProvider->dwAPIVersion)
  318. );
  319. DeviceProvider->Status = FAX_PROVIDER_STATUS_BAD_VERSION;
  320. DeviceProvider->dwLastError = ERROR_GEN_FAILURE;
  321. goto InitializationFailure;
  322. }
  323. //
  324. // Success on load (we still have to init)
  325. //
  326. InsertTailList( &g_DeviceProvidersListHead, &DeviceProvider->ListEntry );
  327. DeviceProvider->Status = FAX_PROVIDER_STATUS_SUCCESS;
  328. DeviceProvider->dwLastError = ERROR_SUCCESS;
  329. goto next;
  330. InitializationFailure:
  331. //
  332. // the device provider dll does not have a complete export list
  333. //
  334. bAllLoaded = FALSE;
  335. if (DeviceProvider)
  336. {
  337. if (DeviceProvider->hModule)
  338. {
  339. FreeLibrary( hModule );
  340. DeviceProvider->hModule = NULL;
  341. }
  342. if (DeviceProvider->HeapHandle &&
  343. FALSE == DeviceProvider->fMicrosoftExtension)
  344. {
  345. if (!HeapDestroy(DeviceProvider->HeapHandle))
  346. {
  347. DebugPrintEx(
  348. DEBUG_ERR,
  349. TEXT("HeapDestroy() failed (ec: %ld)"),
  350. GetLastError());
  351. }
  352. DeviceProvider->HeapHandle = NULL;
  353. }
  354. //
  355. // We keep the device provider's record intact because we want
  356. // to return init failure data on RPC calls to FAX_EnumerateProviders
  357. //
  358. Assert (FAX_PROVIDER_STATUS_SUCCESS != DeviceProvider->Status);
  359. Assert (ERROR_SUCCESS != DeviceProvider->dwLastError);
  360. InsertTailList( &g_DeviceProvidersListHead, &DeviceProvider->ListEntry );
  361. }
  362. DebugPrintEx(
  363. DEBUG_ERR,
  364. TEXT("Device provider [%s] FAILED to initialized "),
  365. FaxReg->DeviceProviders[i].FriendlyName );
  366. next:
  367. ;
  368. }
  369. return bAllLoaded;
  370. }
  371. VOID
  372. HandleFSPInitializationFailure(
  373. PDEVICE_PROVIDER pDeviceProvider,
  374. BOOL fExtensionConfigFail
  375. )
  376. //*********************************************************************************
  377. //* Name: HandleFSPInitializationFailure()
  378. //* Author: Oded Sacher
  379. //* Date: Jul 4, 2002
  380. //*********************************************************************************
  381. //* DESCRIPTION:
  382. //* Handles a FSP initialization failure.
  383. //*
  384. //* PARAMETERS:
  385. //* pDeviceProvider - points to a DEVICE_PROVIDER structure of a loaded FSP.
  386. //* The status and the last error must be updated with the failure info.
  387. //* fExtensionConfigFail - TRUE if FaxExtInitializeConfig failed, FALSE if FaxDevInitialize failed
  388. //*
  389. //* RETURN VALUE:
  390. //* None.
  391. //*********************************************************************************
  392. {
  393. DEBUG_FUNCTION_NAME(TEXT("HandleFSPInitializationFailure"));
  394. //
  395. // Issue an event log
  396. //
  397. FaxLog(
  398. FAXLOG_CATEGORY_INIT,
  399. FAXLOG_LEVEL_MIN,
  400. 4,
  401. MSG_FSP_INIT_FAILED,
  402. pDeviceProvider->FriendlyName,
  403. DWORD2DECIMAL(fExtensionConfigFail), // 1 = Failed during FaxExtInitializeConfig
  404. // 0 = Failed during FaxDevInitialize
  405. DWORD2DECIMAL(pDeviceProvider->dwLastError),
  406. pDeviceProvider->ImageName
  407. );
  408. //
  409. // Unload the DLL
  410. //
  411. Assert (pDeviceProvider->hModule);
  412. if (!FreeLibrary( pDeviceProvider->hModule ))
  413. {
  414. DebugPrintEx(
  415. DEBUG_ERR,
  416. TEXT("Failed to free library [%s] (ec: %ld)"),
  417. pDeviceProvider->ImageName,
  418. GetLastError());
  419. Assert(FALSE);
  420. }
  421. pDeviceProvider->hModule = NULL;
  422. //
  423. // We weed to get rid of the lines we already created.
  424. //
  425. PLIST_ENTRY pNext = NULL;
  426. PLINE_INFO LineInfo;
  427. pNext = g_TapiLinesListHead.Flink;
  428. while ((ULONG_PTR)pNext != (ULONG_PTR)&g_TapiLinesListHead)
  429. {
  430. LineInfo = CONTAINING_RECORD( pNext, LINE_INFO, ListEntry );
  431. pNext = LineInfo->ListEntry.Flink;
  432. if (!_tcscmp(LineInfo->Provider->ProviderName, pDeviceProvider->ProviderName))
  433. {
  434. DebugPrintEx(
  435. DEBUG_WRN,
  436. TEXT("Removing Line: [%s] due to provider initialization failure."),
  437. LineInfo->DeviceName);
  438. RemoveEntryList(&LineInfo->ListEntry);
  439. if (TRUE == IsDeviceEnabled(LineInfo))
  440. {
  441. Assert (g_dwDeviceEnabledCount);
  442. g_dwDeviceEnabledCount -=1;
  443. }
  444. g_dwDeviceCount -=1;
  445. FreeTapiLine(LineInfo);
  446. }
  447. }
  448. //
  449. // We keep the device provider's record intact because we want
  450. // to return init failure data on RPC calls to FAX_EnumerateProviders
  451. //
  452. return;
  453. } // HandleFSPInitializationFailure
  454. //*********************************************************************************
  455. //* Name: InitializeDeviceProvidersConfiguration()
  456. //* Author: Oded Sacher
  457. //* Date: Jul 4, 2002
  458. //*********************************************************************************
  459. //* DESCRIPTION:
  460. //* Initializes the extension configuration for all loaded providers by calling FaxExtInitializeConfig()
  461. //* If the initialization fails the FSP is unloaded.
  462. //*
  463. //* PARAMETERS:
  464. //* None.
  465. //*
  466. //* RETURN VALUE:
  467. //* TRUE if the initialization succeeded for ALL providers. FALSE otherwise.
  468. //*********************************************************************************
  469. BOOL
  470. InitializeDeviceProvidersConfiguration(
  471. VOID
  472. )
  473. {
  474. PLIST_ENTRY Next;
  475. PDEVICE_PROVIDER pDeviceProvider;
  476. BOOL bAllSucceeded = TRUE;
  477. HRESULT hr;
  478. DEBUG_FUNCTION_NAME(TEXT("InitializeDeviceProvidersConfiguration"));
  479. Next = g_DeviceProvidersListHead.Flink;
  480. Assert (Next);
  481. while ((ULONG_PTR)Next != (ULONG_PTR)&g_DeviceProvidersListHead)
  482. {
  483. pDeviceProvider = CONTAINING_RECORD( Next, DEVICE_PROVIDER, ListEntry );
  484. Next = pDeviceProvider->ListEntry.Flink;
  485. if (pDeviceProvider->Status != FAX_PROVIDER_STATUS_SUCCESS)
  486. {
  487. //
  488. // This FSP wasn't loaded successfully - skip it
  489. //
  490. continue;
  491. }
  492. //
  493. // Assert the loading succeeded
  494. //
  495. Assert (ERROR_SUCCESS == pDeviceProvider->dwLastError);
  496. //
  497. // Start with ext. configuration initialization call
  498. //
  499. if (!pDeviceProvider->pFaxExtInitializeConfig)
  500. {
  501. //
  502. // This FSP does not export FaxExtInitializeConfig - skip it
  503. //
  504. continue;
  505. }
  506. //
  507. // If the FSP exports FaxExtInitializeConfig(), call it 1st before any other call.
  508. //
  509. __try
  510. {
  511. hr = pDeviceProvider->pFaxExtInitializeConfig(
  512. FaxExtGetData,
  513. FaxExtSetData,
  514. FaxExtRegisterForEvents,
  515. FaxExtUnregisterForEvents,
  516. FaxExtFreeBuffer);
  517. }
  518. __except (HandleFaxExtensionFault(EXCEPTION_SOURCE_FSP, pDeviceProvider->FriendlyName, GetExceptionCode()))
  519. {
  520. ASSERT_FALSE;
  521. }
  522. if (FAILED(hr))
  523. {
  524. DebugPrintEx(
  525. DEBUG_ERR,
  526. TEXT("FaxExtInitializeConfig() failed (hr = 0x%08x) for provider [%s]"),
  527. hr,
  528. pDeviceProvider->FriendlyName );
  529. pDeviceProvider->Status = FAX_PROVIDER_STATUS_CANT_INIT;
  530. pDeviceProvider->dwLastError = hr;
  531. bAllSucceeded = FALSE;
  532. //
  533. // handle the initialization failure
  534. //
  535. HandleFSPInitializationFailure(pDeviceProvider, TRUE);
  536. }
  537. }
  538. return bAllSucceeded;
  539. } // InitializeDeviceProvidersConfiguration
  540. //*********************************************************************************
  541. //* Name: InitializeDeviceProviders()
  542. //* Author: Ronen Barenboim
  543. //* Date: May 19, 1999
  544. //*********************************************************************************
  545. //* DESCRIPTION:
  546. //* Initializes all loaded providers by calling FaxDevInitialize()
  547. //* If the initialization fails the FSP is unloaded.
  548. //* For legacy virtual FSP the function also removes all the vitrual devices
  549. //* that belong to the FSP that failed to initialize.
  550. //*
  551. //* PARAMETERS:
  552. //* None.
  553. //*
  554. //* RETURN VALUE:
  555. //* TRUE if the initialization succeeded for ALL providers. FALSE otherwise.
  556. //*********************************************************************************
  557. BOOL
  558. InitializeDeviceProviders(
  559. VOID
  560. )
  561. {
  562. PLIST_ENTRY Next;
  563. PDEVICE_PROVIDER pDeviceProvider;
  564. BOOL bAllSucceeded = TRUE;
  565. DWORD ec = ERROR_SUCCESS;
  566. DEBUG_FUNCTION_NAME(TEXT("InitializeDeviceProviders"));
  567. Next = g_DeviceProvidersListHead.Flink;
  568. Assert (Next);
  569. while ((ULONG_PTR)Next != (ULONG_PTR)&g_DeviceProvidersListHead)
  570. {
  571. BOOL bRes = FALSE;
  572. pDeviceProvider = CONTAINING_RECORD( Next, DEVICE_PROVIDER, ListEntry );
  573. Next = pDeviceProvider->ListEntry.Flink;
  574. if (pDeviceProvider->Status != FAX_PROVIDER_STATUS_SUCCESS)
  575. {
  576. //
  577. // This FSP wasn't loaded successfully or failed to initilaize extension configuration - skip it
  578. //
  579. continue;
  580. }
  581. //
  582. // the device provider exports ALL the requisite functions
  583. // now try to initialize it
  584. // Assert the loading succeeded
  585. //
  586. Assert (ERROR_SUCCESS == pDeviceProvider->dwLastError);
  587. __try
  588. {
  589. bRes = pDeviceProvider->FaxDevInitialize(
  590. g_hLineApp,
  591. pDeviceProvider->HeapHandle,
  592. &pDeviceProvider->FaxDevCallback,
  593. FaxDeviceProviderCallback);
  594. }
  595. __except (HandleFaxExtensionFault(EXCEPTION_SOURCE_FSP, pDeviceProvider->FriendlyName, GetExceptionCode()))
  596. {
  597. ASSERT_FALSE;
  598. }
  599. if (TRUE == bRes)
  600. {
  601. //
  602. // all is ok
  603. //
  604. DebugPrintEx(
  605. DEBUG_MSG,
  606. TEXT("Device provider [%s] initialized "),
  607. pDeviceProvider->FriendlyName );
  608. //
  609. // mark the fact that FaxDevInitialize was called, so the service will call
  610. // FaxDevShutDown when it is going down
  611. //
  612. pDeviceProvider->bInitializationSucceeded = TRUE;
  613. }
  614. else
  615. {
  616. ec = GetLastError();
  617. //
  618. // initialization failed
  619. //
  620. DebugPrintEx(
  621. DEBUG_ERR,
  622. TEXT("FaxDevInitialize FAILED for provider [%s] (ec: %ld)"),
  623. pDeviceProvider->FriendlyName,
  624. ec);
  625. pDeviceProvider->Status = FAX_PROVIDER_STATUS_CANT_INIT;
  626. pDeviceProvider->dwLastError = ec;
  627. bAllSucceeded = FALSE;
  628. //
  629. // handle the initialization failure
  630. //
  631. HandleFSPInitializationFailure(pDeviceProvider, FALSE);
  632. }
  633. }
  634. return bAllSucceeded;
  635. } // InitializeDeviceProviders
  636. PDEVICE_PROVIDER
  637. FindDeviceProvider(
  638. LPTSTR lptstrProviderName,
  639. BOOL bSuccessfullyLoaded /* = TRUE */
  640. )
  641. /*++
  642. Routine Description:
  643. Locates a device provider in the linked list
  644. of device providers based on the provider name (TSP name).
  645. The device provider name is case insensitive.
  646. Arguments:
  647. lptstrProviderName - Specifies the device provider name to locate.
  648. bSuccessfullyLoaded - To we only look for successfuly loaded providers?
  649. Return Value:
  650. Pointer to a DEVICE_PROVIDER structure, or NULL for failure.
  651. --*/
  652. {
  653. PLIST_ENTRY pNext;
  654. PDEVICE_PROVIDER pProvider;
  655. if (!lptstrProviderName || !lstrlen (lptstrProviderName))
  656. {
  657. //
  658. // NULL TSP name or empty string TSP name never matches any list entry.
  659. //
  660. return NULL;
  661. }
  662. pNext = g_DeviceProvidersListHead.Flink;
  663. if (!pNext)
  664. {
  665. return NULL;
  666. }
  667. while ((ULONG_PTR)pNext != (ULONG_PTR)&g_DeviceProvidersListHead)
  668. {
  669. pProvider = CONTAINING_RECORD( pNext, DEVICE_PROVIDER, ListEntry );
  670. pNext = pProvider->ListEntry.Flink;
  671. if (bSuccessfullyLoaded &&
  672. (FAX_PROVIDER_STATUS_SUCCESS != pProvider->Status))
  673. {
  674. //
  675. // We're only looking for successfully loaded providers and this one isn't
  676. //
  677. continue;
  678. }
  679. if (!lstrcmpi( pProvider->ProviderName, lptstrProviderName ))
  680. {
  681. //
  682. // Match found
  683. //
  684. return pProvider;
  685. }
  686. }
  687. return NULL;
  688. }
  689. BOOL CALLBACK
  690. FaxDeviceProviderCallback(
  691. IN HANDLE FaxHandle,
  692. IN DWORD DeviceId,
  693. IN DWORD_PTR Param1,
  694. IN DWORD_PTR Param2,
  695. IN DWORD_PTR Param3
  696. )
  697. {
  698. return TRUE;
  699. }
  700. #ifdef DBG
  701. //*********************************************************************************
  702. //* Name: DebugDumpProviderRegistryInfo()
  703. //* Author: Ronen Barenboim
  704. //* Date: May 19, 1999
  705. //*********************************************************************************
  706. //* DESCRIPTION:
  707. //* Dumps the information for a legacy or new FSP.
  708. //* PARAMETERS:
  709. //* [IN] const REG_DEVICE_PROVIDER * lpcProviderInfo
  710. //*
  711. //* [IN] LPTSTR lptstrPrefix
  712. //*
  713. //* RETURN VALUE:
  714. //* TRUE
  715. //*
  716. //* FALSE
  717. //*
  718. //*********************************************************************************
  719. BOOL DebugDumpProviderRegistryInfoFunc(const REG_DEVICE_PROVIDER * lpcProviderInfo, LPTSTR lptstrPrefix)
  720. {
  721. Assert(lpcProviderInfo);
  722. Assert(lptstrPrefix);
  723. DEBUG_FUNCTION_NAME(TEXT("DebugDumpProviderRegistryInfo"));
  724. DebugPrintEx(
  725. DEBUG_MSG,
  726. TEXT("%sProvider GUID: %s"),
  727. lptstrPrefix,
  728. lpcProviderInfo->lptstrGUID);
  729. DebugPrintEx(
  730. DEBUG_MSG,
  731. TEXT("%sProvider Name: %s"),
  732. lptstrPrefix,
  733. lpcProviderInfo->FriendlyName);
  734. DebugPrintEx(
  735. DEBUG_MSG,
  736. TEXT("%sProvider image: %s"),
  737. lptstrPrefix,
  738. lpcProviderInfo->ImageName);
  739. DebugPrintEx(
  740. DEBUG_MSG,
  741. TEXT("%sFSPI Version: 0x%08X"),
  742. lptstrPrefix,
  743. lpcProviderInfo->dwAPIVersion);
  744. DebugPrintEx(
  745. DEBUG_MSG,
  746. TEXT("%sTAPI Provider : %s"),
  747. lptstrPrefix,
  748. lpcProviderInfo->ProviderName);
  749. return TRUE;
  750. }
  751. #endif
  752. //*********************************************************************************
  753. //* Name: GetLegacyProviderEntryPoints()
  754. //* Author: Ronen Barenboim
  755. //* Date: May 19, 1999
  756. //*********************************************************************************
  757. //* DESCRIPTION:
  758. //* Sets the legacy function entry points in the DEVICE_PROVIDER structure.
  759. //* PARAMETERS:
  760. //* [IN] HMODULE hModule
  761. //* The instance handle for the DLL from which the entry points are to be
  762. //* set.
  763. //* [OUT] PDEVICE_PROVIDER lpProvider
  764. //* A pointer to a Legacy DEVICE_PROVIDER structure whose function entry points
  765. //* are to be set.
  766. //*
  767. //* RETURN VALUE:
  768. //* TRUE
  769. //*
  770. //* FALSE
  771. //*
  772. //*********************************************************************************
  773. BOOL GetLegacyProviderEntryPoints(HMODULE hModule, PDEVICE_PROVIDER lpProvider)
  774. {
  775. DEBUG_FUNCTION_NAME(TEXT("GetLegacyProviderEntryPoints"));
  776. Assert(hModule);
  777. Assert(lpProvider);
  778. lpProvider->FaxDevInitialize = (PFAXDEVINITIALIZE) GetProcAddress(
  779. hModule,
  780. "FaxDevInitialize"
  781. );
  782. if (!lpProvider->FaxDevInitialize) {
  783. DebugPrintEx(
  784. DEBUG_ERR,
  785. TEXT("GetProcAddress(FaxDevInitialize) failed (ec: %ld)"),
  786. GetLastError());
  787. goto Error;
  788. }
  789. lpProvider->FaxDevStartJob = (PFAXDEVSTARTJOB) GetProcAddress(
  790. hModule,
  791. "FaxDevStartJob"
  792. );
  793. if (!lpProvider->FaxDevStartJob) {
  794. DebugPrintEx(
  795. DEBUG_ERR,
  796. TEXT("GetProcAddress(FaxDevStartJob) failed (ec: %ld)"),
  797. GetLastError());
  798. goto Error;
  799. }
  800. lpProvider->FaxDevEndJob = (PFAXDEVENDJOB) GetProcAddress(
  801. hModule,
  802. "FaxDevEndJob"
  803. );
  804. if (!lpProvider->FaxDevEndJob) {
  805. DebugPrintEx(
  806. DEBUG_ERR,
  807. TEXT("GetProcAddress(FaxDevEndJob) failed (ec: %ld)"),
  808. GetLastError());
  809. goto Error;
  810. }
  811. lpProvider->FaxDevSend = (PFAXDEVSEND) GetProcAddress(
  812. hModule,
  813. "FaxDevSend"
  814. );
  815. if (!lpProvider->FaxDevSend) {
  816. DebugPrintEx(
  817. DEBUG_ERR,
  818. TEXT("GetProcAddress(FaxDevSend) failed (ec: %ld)"),
  819. GetLastError());
  820. goto Error;
  821. }
  822. lpProvider->FaxDevReceive = (PFAXDEVRECEIVE) GetProcAddress(
  823. hModule,
  824. "FaxDevReceive"
  825. );
  826. if (!lpProvider->FaxDevReceive) {
  827. DebugPrintEx(
  828. DEBUG_ERR,
  829. TEXT("GetProcAddress(FaxDevReceive) failed (ec: %ld)"),
  830. GetLastError());
  831. goto Error;
  832. }
  833. lpProvider->FaxDevReportStatus = (PFAXDEVREPORTSTATUS) GetProcAddress(
  834. hModule,
  835. "FaxDevReportStatus"
  836. );
  837. if (!lpProvider->FaxDevReportStatus) {
  838. DebugPrintEx(
  839. DEBUG_ERR,
  840. TEXT("GetProcAddress(FaxDevReportStatus) failed (ec: %ld)"),
  841. GetLastError());
  842. goto Error;
  843. }
  844. lpProvider->FaxDevAbortOperation = (PFAXDEVABORTOPERATION) GetProcAddress(
  845. hModule,
  846. "FaxDevAbortOperation"
  847. );
  848. if (!lpProvider->FaxDevAbortOperation) {
  849. DebugPrintEx(
  850. DEBUG_ERR,
  851. TEXT("GetProcAddress(FaxDevAbortOperation) failed (ec: %ld)"),
  852. GetLastError());
  853. goto Error;
  854. }
  855. lpProvider->FaxDevVirtualDeviceCreation = (PFAXDEVVIRTUALDEVICECREATION) GetProcAddress(
  856. hModule,
  857. "FaxDevVirtualDeviceCreation"
  858. );
  859. //
  860. // lpProvider->FaxDevVirtualDeviceCreation is optional so we don't fail if it does
  861. // not exist.
  862. if (!lpProvider->FaxDevVirtualDeviceCreation) {
  863. DebugPrintEx(
  864. DEBUG_MSG,
  865. TEXT("FaxDevVirtualDeviceCreation() not found. This is not a virtual FSP."));
  866. }
  867. lpProvider->pFaxExtInitializeConfig = (PFAX_EXT_INITIALIZE_CONFIG) GetProcAddress(
  868. hModule,
  869. "FaxExtInitializeConfig"
  870. );
  871. //
  872. // lpProvider->pFaxExtInitializeConfig is optional so we don't fail if it does
  873. // not exist.
  874. //
  875. if (!lpProvider->pFaxExtInitializeConfig)
  876. {
  877. DebugPrintEx(
  878. DEBUG_MSG,
  879. TEXT("FaxExtInitializeConfig() not found. This is not an error."));
  880. }
  881. lpProvider->FaxDevShutdown = (PFAXDEVSHUTDOWN) GetProcAddress(
  882. hModule,
  883. "FaxDevShutdown"
  884. );
  885. if (!lpProvider->FaxDevShutdown) {
  886. DebugPrintEx(
  887. DEBUG_MSG,
  888. TEXT("FaxDevShutdown() not found. This is not an error."));
  889. }
  890. goto Exit;
  891. Error:
  892. return FALSE;
  893. Exit:
  894. return TRUE;
  895. }
  896. //*********************************************************************************
  897. //* Name: GetSuccessfullyLoadedProvidersCount()
  898. //* Author: Ronen Barenboim
  899. //* Date: May 19, 1999
  900. //*********************************************************************************
  901. //* DESCRIPTION:
  902. //* Returns the number of loaded providers in the DeviceProviders list.
  903. //* PARAMETERS:
  904. //* NONE
  905. //* RETURN VALUE:
  906. //* a DWORD containing the number of elements (providers) in the
  907. //* DeviceProviders list.
  908. //*********************************************************************************
  909. DWORD GetSuccessfullyLoadedProvidersCount()
  910. {
  911. PLIST_ENTRY Next;
  912. DWORD dwCount;
  913. Next = g_DeviceProvidersListHead.Flink;
  914. Assert (Next);
  915. dwCount = 0;
  916. while ((ULONG_PTR)Next != (ULONG_PTR)&g_DeviceProvidersListHead)
  917. {
  918. PDEVICE_PROVIDER DeviceProvider;
  919. DeviceProvider = CONTAINING_RECORD( Next, DEVICE_PROVIDER, ListEntry );
  920. if (FAX_PROVIDER_STATUS_SUCCESS == DeviceProvider->Status)
  921. {
  922. //
  923. // Count only successfuly loaded FSPs
  924. //
  925. dwCount++;
  926. }
  927. Next = Next->Flink;
  928. Assert(Next);
  929. }
  930. return dwCount;
  931. }
  932. //*********************************************************************************
  933. //* Name: ShutdownDeviceProviders()
  934. //* Author: Ronen Barenboim
  935. //* Date: May 19, 1999
  936. //*********************************************************************************
  937. //* DESCRIPTION:
  938. //* Calls FaxDevShutdown() for each FSP
  939. //* PARAMETERS:
  940. //* NONE
  941. //* RETURN VALUE:
  942. //* ERROR_SUCCESS
  943. //* FaxDevShutdown() succeeded for all FSPs
  944. //* ERROR_FUNCTION_FAILED
  945. //* FaxDevShutdown() failed for at least one FSP.
  946. //*********************************************************************************
  947. DWORD ShutdownDeviceProviders(LPVOID lpvUnused)
  948. {
  949. PLIST_ENTRY Next;
  950. PDEVICE_PROVIDER DeviceProvider = NULL;
  951. DWORD dwAllSucceeded = ERROR_SUCCESS;
  952. DEBUG_FUNCTION_NAME(TEXT("ShutdownDeviceProviders"));
  953. Next = g_DeviceProvidersListHead.Flink;
  954. if (!Next)
  955. {
  956. DebugPrintEx( DEBUG_WRN,
  957. _T("There are no Providers at shutdown! this is valid only if startup failed"));
  958. return dwAllSucceeded;
  959. }
  960. while ((ULONG_PTR)Next != (ULONG_PTR)&g_DeviceProvidersListHead)
  961. {
  962. DeviceProvider = CONTAINING_RECORD( Next, DEVICE_PROVIDER, ListEntry );
  963. Next = Next->Flink;
  964. if (!DeviceProvider->bInitializationSucceeded)
  965. {
  966. //
  967. // This FSP wasn't initialized successfully - skip it
  968. //
  969. continue;
  970. }
  971. if (DeviceProvider->FaxDevShutdown && !DeviceProvider->bShutDownAttempted)
  972. {
  973. Assert(DeviceProvider->FaxDevShutdown);
  974. DebugPrintEx(
  975. DEBUG_MSG,
  976. TEXT("Calling FaxDevShutdown() for FSP [%s] [GUID: %s]"),
  977. DeviceProvider->FriendlyName,
  978. DeviceProvider->szGUID);
  979. __try
  980. {
  981. HRESULT hr;
  982. DeviceProvider->bShutDownAttempted = TRUE;
  983. hr = DeviceProvider->FaxDevShutdown();
  984. if (FAILED(hr))
  985. {
  986. DebugPrintEx(
  987. DEBUG_ERR,
  988. TEXT("FaxDevShutdown() failed (hr: 0x%08X) for FSP [%s] [GUID: %s]"),
  989. hr,
  990. DeviceProvider->FriendlyName,
  991. DeviceProvider->szGUID);
  992. dwAllSucceeded = ERROR_FUNCTION_FAILED;
  993. }
  994. }
  995. __except (HandleFaxExtensionFault(EXCEPTION_SOURCE_FSP, DeviceProvider->FriendlyName, GetExceptionCode()))
  996. {
  997. ASSERT_FALSE;
  998. }
  999. }
  1000. }
  1001. return dwAllSucceeded;
  1002. }
  1003. //*********************************************************************************
  1004. //* Name: FreeFSPIJobStatus()
  1005. //* Author: Ronen Barenboim
  1006. //* Date: June 03, 1999
  1007. //*********************************************************************************
  1008. //* DESCRIPTION:
  1009. //* Frees the content of a FSPI_JOB_STATUS structure. Can be instructre to
  1010. //* free the structure itself too.
  1011. //*
  1012. //* PARAMETERS:
  1013. //* [IN ] LPFSPI_JOB_STATUS lpJobStatus
  1014. //* A pointer to the structure to free.
  1015. //*
  1016. //* [IN ] BOOL bDestroy
  1017. //* TRUE if the memory occupied by the structure itself should be freed.
  1018. //* FALSE if only the memeory occupied by the structure fields should
  1019. //* be freed.
  1020. //*
  1021. //* RETURN VALUE:
  1022. //* TRUE if the operation succeeded.
  1023. //* FALSE if it failed. Call GetLastError() for extended error information.
  1024. //*********************************************************************************
  1025. BOOL FreeFSPIJobStatus(LPFSPI_JOB_STATUS lpJobStatus, BOOL bDestroy)
  1026. {
  1027. if (!lpJobStatus)
  1028. {
  1029. return TRUE;
  1030. }
  1031. Assert(lpJobStatus);
  1032. MemFree(lpJobStatus->lpwstrRemoteStationId);
  1033. lpJobStatus->lpwstrRemoteStationId = NULL;
  1034. MemFree(lpJobStatus->lpwstrCallerId);
  1035. lpJobStatus->lpwstrCallerId = NULL;
  1036. MemFree(lpJobStatus->lpwstrRoutingInfo);
  1037. lpJobStatus->lpwstrRoutingInfo = NULL;
  1038. if (bDestroy)
  1039. {
  1040. MemFree(lpJobStatus);
  1041. }
  1042. return TRUE;
  1043. }
  1044. //*********************************************************************************
  1045. //* Name: DuplicateFSPIJobStatus()
  1046. //* Author: Ronen Barenboim
  1047. //* Date: June 03, 1999
  1048. //*********************************************************************************
  1049. //* DESCRIPTION:
  1050. //* Allocates a new FSPI_JOB_STATUS structure and initializes with
  1051. //* a copy of the specified FSPI_JOB_STATUS structure fields.
  1052. //*
  1053. //* PARAMETERS:
  1054. //* [IN ] LPCFSPI_JOB_STATUS lpcSrc
  1055. //* The structure to duplicated.
  1056. //*
  1057. //* RETURN VALUE:
  1058. //* On success teh function returns a pointer to the newly allocated
  1059. //* structure. On failure it returns NULL.
  1060. //*********************************************************************************
  1061. LPFSPI_JOB_STATUS DuplicateFSPIJobStatus(LPCFSPI_JOB_STATUS lpcSrc)
  1062. {
  1063. LPFSPI_JOB_STATUS lpDst;
  1064. DWORD ec = 0;
  1065. DEBUG_FUNCTION_NAME(TEXT("DuplicateFSPIJobStatus"));
  1066. Assert(lpcSrc);
  1067. lpDst = (LPFSPI_JOB_STATUS)MemAlloc(sizeof(FSPI_JOB_STATUS));
  1068. if (!lpDst)
  1069. {
  1070. ec = GetLastError();
  1071. DebugPrintEx(
  1072. DEBUG_ERR,
  1073. TEXT("Failed to allocate FSPI_JOB_STATUS (ec: %ld)"),
  1074. GetLastError());
  1075. goto Error;
  1076. }
  1077. memset(lpDst, 0, sizeof(FSPI_JOB_STATUS));
  1078. if (!CopyFSPIJobStatus(lpDst,lpcSrc, sizeof(FSPI_JOB_STATUS)))
  1079. {
  1080. ec = GetLastError();
  1081. DebugPrintEx(
  1082. DEBUG_ERR,
  1083. TEXT("CopyFSPIJobStatus() failed (ec: %ld)"),
  1084. GetLastError());
  1085. goto Error;
  1086. }
  1087. Assert(0 == ec);
  1088. goto Exit;
  1089. Error:
  1090. Assert (0 != ec);
  1091. FreeFSPIJobStatus(lpDst, TRUE);
  1092. lpDst = NULL;
  1093. Exit:
  1094. if (ec)
  1095. {
  1096. SetLastError(ec);
  1097. }
  1098. return lpDst;
  1099. }
  1100. //*********************************************************************************
  1101. //* Name: CopyFSPIJobStatus()
  1102. //* Author: Ronen Barenboim
  1103. //* Date: June 03, 1999
  1104. //*********************************************************************************
  1105. //* DESCRIPTION:
  1106. //* Copies a FSPI_JOB_STATUS content into the a destination (pre allocated)
  1107. //* FSPI_JOB_STATUS structure.
  1108. //*
  1109. //* PARAMETERS:
  1110. //* [IN ] LPFSPI_JOB_STATUS lpDst
  1111. //* The destinatione structure for the copy operation. This structure must
  1112. //* be allocated before this function is called.
  1113. //*
  1114. //* [IN ] LPCFSPI_JOB_STATUS lpcSrc
  1115. //* The source structure for the copy operation.
  1116. //*
  1117. //* [IN ] DWORD dwDstSize
  1118. //* The size, in bytes, of the buffer pointed by lpDst
  1119. //*
  1120. //* RETURN VALUE:
  1121. //* TRUE
  1122. //* If the operation succeeded.
  1123. //* FALSE
  1124. //* If the operation failed. Call GetLastError() for extended information.
  1125. //* In case of a failure the destination structure is all set to 0.
  1126. //*********************************************************************************
  1127. BOOL CopyFSPIJobStatus(LPFSPI_JOB_STATUS lpDst, LPCFSPI_JOB_STATUS lpcSrc, DWORD dwDstSize)
  1128. {
  1129. STRING_PAIR pairs[]=
  1130. {
  1131. {lpcSrc->lpwstrCallerId, &lpDst->lpwstrCallerId},
  1132. {lpcSrc->lpwstrRoutingInfo, &lpDst->lpwstrRoutingInfo},
  1133. {lpcSrc->lpwstrRemoteStationId, &lpDst->lpwstrRemoteStationId}
  1134. };
  1135. int nRes;
  1136. DEBUG_FUNCTION_NAME(TEXT("CopyFSPIJobStatus"));
  1137. Assert (sizeof(FSPI_JOB_STATUS) == dwDstSize);
  1138. if (dwDstSize < sizeof(FSPI_JOB_STATUS))
  1139. {
  1140. SetLastError (ERROR_INVALID_PARAMETER);
  1141. return FALSE;
  1142. }
  1143. memcpy(lpDst, lpcSrc, sizeof(FSPI_JOB_STATUS));
  1144. nRes=MultiStringDup(pairs, sizeof(pairs)/sizeof(STRING_PAIR));
  1145. if (nRes!=0)
  1146. {
  1147. DWORD ec=GetLastError();
  1148. // MultiStringDup takes care of freeing the memory for the pairs for which the copy succeeded
  1149. DebugPrintEx(
  1150. DEBUG_ERR,
  1151. TEXT("MultiStringDup failed to copy string with index %d. (ec: %ld)"),
  1152. nRes-1,
  1153. ec);
  1154. memset(lpDst, 0 , sizeof(FSPI_JOB_STATUS));
  1155. return FALSE;
  1156. }
  1157. return TRUE;
  1158. }
  1159. DWORD
  1160. MapFSPIJobExtendedStatusToJS_EX (DWORD dwFSPIExtendedStatus)
  1161. //*********************************************************************************
  1162. //* Name: MapFSPIJobExtendedStatusToJS_EX()
  1163. //* Author: Oded sacher
  1164. //* Date: Jan 2000
  1165. //*********************************************************************************
  1166. //* DESCRIPTION:
  1167. //* Maps FSPI extended job status codes to a Fax Client API extended
  1168. //* status (one of the JS_EX_* codes).
  1169. //* PARAMETERS:
  1170. //* [IN ] DWORD dwFSPIExtendedStatus
  1171. //* The FSPI extended Status code.
  1172. //*
  1173. //* RETURN VALUE:
  1174. //* The corresponding JS_EX_* status code.
  1175. //*
  1176. //*********************************************************************************
  1177. {
  1178. DWORD dwExtendedStatus = 0;
  1179. DEBUG_FUNCTION_NAME(TEXT("MapFSPIJobExtendedStatusToJS_EX"));
  1180. if (FSPI_ES_PROPRIETARY <= dwFSPIExtendedStatus ||
  1181. 0 == dwFSPIExtendedStatus)
  1182. {
  1183. return dwFSPIExtendedStatus;
  1184. }
  1185. switch (dwFSPIExtendedStatus)
  1186. {
  1187. case FSPI_ES_DISCONNECTED:
  1188. dwExtendedStatus = JS_EX_DISCONNECTED;
  1189. break;
  1190. case FSPI_ES_INITIALIZING:
  1191. dwExtendedStatus = JS_EX_INITIALIZING;
  1192. break;
  1193. case FSPI_ES_DIALING:
  1194. dwExtendedStatus = JS_EX_DIALING;
  1195. break;
  1196. case FSPI_ES_TRANSMITTING:
  1197. dwExtendedStatus = JS_EX_TRANSMITTING;
  1198. break;
  1199. case FSPI_ES_ANSWERED:
  1200. dwExtendedStatus = JS_EX_ANSWERED;
  1201. break;
  1202. case FSPI_ES_RECEIVING:
  1203. dwExtendedStatus = JS_EX_RECEIVING;
  1204. break;
  1205. case FSPI_ES_LINE_UNAVAILABLE:
  1206. dwExtendedStatus = JS_EX_LINE_UNAVAILABLE;
  1207. break;
  1208. case FSPI_ES_BUSY:
  1209. dwExtendedStatus = JS_EX_BUSY;
  1210. break;
  1211. case FSPI_ES_NO_ANSWER:
  1212. dwExtendedStatus = JS_EX_NO_ANSWER;
  1213. break;
  1214. case FSPI_ES_BAD_ADDRESS:
  1215. dwExtendedStatus = JS_EX_BAD_ADDRESS;
  1216. break;
  1217. case FSPI_ES_NO_DIAL_TONE:
  1218. dwExtendedStatus = JS_EX_NO_DIAL_TONE;
  1219. break;
  1220. case FSPI_ES_FATAL_ERROR:
  1221. dwExtendedStatus = JS_EX_FATAL_ERROR;
  1222. break;
  1223. case FSPI_ES_CALL_DELAYED:
  1224. dwExtendedStatus = JS_EX_CALL_DELAYED;
  1225. break;
  1226. case FSPI_ES_CALL_BLACKLISTED:
  1227. dwExtendedStatus = JS_EX_CALL_BLACKLISTED;
  1228. break;
  1229. case FSPI_ES_NOT_FAX_CALL:
  1230. dwExtendedStatus = JS_EX_NOT_FAX_CALL;
  1231. break;
  1232. case FSPI_ES_PARTIALLY_RECEIVED:
  1233. dwExtendedStatus = JS_EX_PARTIALLY_RECEIVED;
  1234. break;
  1235. case FSPI_ES_HANDLED:
  1236. dwExtendedStatus = JS_EX_HANDLED;
  1237. break;
  1238. case FSPI_ES_CALL_ABORTED:
  1239. dwExtendedStatus = JS_EX_CALL_ABORTED;
  1240. break;
  1241. case FSPI_ES_CALL_COMPLETED:
  1242. dwExtendedStatus = JS_EX_CALL_COMPLETED;
  1243. break;
  1244. default:
  1245. DebugPrintEx(
  1246. DEBUG_WRN,
  1247. TEXT("Invalid extended job status 0x%08X"),
  1248. dwFSPIExtendedStatus);
  1249. }
  1250. return dwExtendedStatus;
  1251. }
  1252. PDEVICE_PROVIDER
  1253. FindFSPByGUID (
  1254. LPCWSTR lpcwstrGUID
  1255. )
  1256. /*++
  1257. Routine name : FindFSPByGUID
  1258. Routine description:
  1259. Finds an FSP by its GUID string
  1260. Author:
  1261. Eran Yariv (EranY), Dec, 1999
  1262. Arguments:
  1263. lpcwstrGUID [in ] - GUID string to search with
  1264. Return Value:
  1265. Pointer to FSP or NULL if FSP not found.
  1266. --*/
  1267. {
  1268. PLIST_ENTRY pNext;
  1269. DEBUG_FUNCTION_NAME(TEXT("FindFSPByGUID"));
  1270. pNext = g_DeviceProvidersListHead.Flink;
  1271. Assert (pNext);
  1272. while ((ULONG_PTR)pNext != (ULONG_PTR)&g_DeviceProvidersListHead)
  1273. {
  1274. PDEVICE_PROVIDER pDeviceProvider;
  1275. pDeviceProvider = CONTAINING_RECORD( pNext, DEVICE_PROVIDER, ListEntry );
  1276. if (!lstrcmpi (lpcwstrGUID, pDeviceProvider->szGUID))
  1277. {
  1278. //
  1279. // Found match
  1280. //
  1281. return pDeviceProvider;
  1282. }
  1283. pNext = pNext->Flink;
  1284. Assert(pNext);
  1285. }
  1286. //
  1287. // No match
  1288. //
  1289. return NULL;
  1290. } // FindFSPByGUID