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.

1127 lines
29 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. install.c
  5. Abstract:
  6. This module contains installation functions.
  7. Author:
  8. Andrew Ritz (andrewr) 9-Dec-1997
  9. Revision History:
  10. 4-Dec-1999 Danl Remove CreatePrinterandGroups
  11. --*/
  12. #include "faxapi.h"
  13. #pragma hdrstop
  14. extern HINSTANCE g_MyhInstance;
  15. //
  16. // Notice: FaxRegisterServiceProvider and FaxUnregisterServiceProvider are
  17. // implemented directly in winfax.dll since it must exist
  18. // even before the fax optional component is installed.
  19. //
  20. #ifdef UNICODE
  21. BOOL AddMethodKey(
  22. HKEY hKey,
  23. LPCWSTR MethodName,
  24. LPCWSTR FriendlyName,
  25. LPCWSTR FunctionName,
  26. LPCWSTR Guid,
  27. DWORD Priority
  28. ) ;
  29. #endif // #ifdef UNICODE
  30. #ifdef UNICODE
  31. WINFAXAPI
  32. BOOL
  33. WINAPI
  34. FaxRegisterRoutingExtensionW(
  35. IN HANDLE hFaxHandle,
  36. IN LPCWSTR lpcwstrExtensionName,
  37. IN LPCWSTR lpcwstrFriendlyName,
  38. IN LPCWSTR lpcwstrImageName,
  39. IN PFAX_ROUTING_INSTALLATION_CALLBACKW pCallBack,
  40. IN LPVOID lpvContext
  41. )
  42. {
  43. HKEY hKey = NULL;
  44. BOOL bRetVal = FALSE;
  45. DWORD dwRet;
  46. WCHAR szKeyName[2000];
  47. PFAX_GLOBAL_ROUTING_INFO pRoutingInfo;
  48. DWORD dwMethods;
  49. DWORD dwLastError = ERROR_SUCCESS;
  50. WCHAR wszMethodName[101];
  51. WCHAR wszMethodFriendlyName[101];
  52. WCHAR wszMethodFunctionName[101];
  53. WCHAR wszMethodGuid[101];
  54. DEBUG_FUNCTION_NAME(TEXT("FaxRegisterRoutingExtensionW"));
  55. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  56. {
  57. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed"));
  58. SetLastError(ERROR_INVALID_HANDLE);
  59. return FALSE;
  60. }
  61. if (!lpcwstrExtensionName ||
  62. !lpcwstrFriendlyName ||
  63. !lpcwstrImageName ||
  64. !pCallBack)
  65. {
  66. SetLastError(ERROR_INVALID_PARAMETER);
  67. DebugPrintEx(DEBUG_ERR, _T("At least one of the given pointers is NULL."));
  68. return FALSE;
  69. }
  70. //
  71. // Local installation only
  72. //
  73. if (!IsLocalFaxConnection(hFaxHandle) )
  74. {
  75. DebugPrintEx(DEBUG_ERR, _T("Not a local fax connection"));
  76. SetLastError(ERROR_INVALID_FUNCTION);
  77. return FALSE;
  78. }
  79. if ((_wcsicmp( lpcwstrExtensionName, REGKEY_ROUTING_EXTENSION ) != 0) &&
  80. TRUE == IsDesktopSKU())
  81. {
  82. DebugPrintEx(
  83. DEBUG_ERR,
  84. TEXT("We do not support non MS routing extensions on desktop SKUs"));
  85. SetLastError (FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU);
  86. return FALSE;
  87. }
  88. //
  89. // Get the number of current methods for priority
  90. //
  91. if (!FaxEnumGlobalRoutingInfo(hFaxHandle, &pRoutingInfo, &dwMethods) )
  92. {
  93. DebugPrintEx(DEBUG_ERR,
  94. TEXT("FaxEnumGlobalRoutingInfo() failed, ec = %d"),
  95. GetLastError());
  96. return FALSE;
  97. }
  98. //
  99. // Store number of methods returned by EnumGlobalRoutingInfo()
  100. //
  101. DWORD dwRegisteredMethods = dwMethods;
  102. //
  103. // Return Value of the Function
  104. //
  105. BOOL bResult = TRUE;
  106. //
  107. // Variables to deal with newly registered Guids, to check their uniqueness
  108. //
  109. LPTSTR *plptstrNewGuids = NULL;
  110. LPTSTR lptstrGuid = NULL;
  111. LPTSTR *pTmp = NULL;
  112. //
  113. // Variable for different FOR cycles
  114. //
  115. DWORD i = 0;
  116. if (0 > _snwprintf(szKeyName,
  117. ARR_SIZE(szKeyName) -1,
  118. TEXT("%s\\%s\\%s"),
  119. REGKEY_SOFTWARE,
  120. REGKEY_ROUTING_EXTENSIONS,
  121. lpcwstrExtensionName))
  122. {
  123. //
  124. // Extension name exceeds size
  125. //
  126. DebugPrintEx(DEBUG_ERR, _T("Extension name \"%s\" exceeds size"), lpcwstrExtensionName);
  127. dwLastError = ERROR_INVALID_PARAMETER;
  128. bResult = FALSE;
  129. goto FreeRoutingInfo;
  130. }
  131. szKeyName[ARR_SIZE(szKeyName) -1] = _T('\0');
  132. //
  133. // Try to open registry key with the Extension Name
  134. //
  135. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
  136. szKeyName,
  137. FALSE,
  138. 0);
  139. if (!hKey)
  140. {
  141. //
  142. // This is new Routing Extension, let's register it
  143. //
  144. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
  145. szKeyName,
  146. TRUE,
  147. 0);
  148. if (!hKey)
  149. {
  150. dwLastError = GetLastError();
  151. DebugPrintEx(DEBUG_ERR,
  152. _T("OpenRegistryKey(%s) failed. ec=%ld"),
  153. szKeyName,
  154. dwLastError);
  155. bResult = FALSE;
  156. goto FreeRoutingInfo;
  157. }
  158. }
  159. else
  160. {
  161. //
  162. // Such Routing Extension is already registered
  163. //
  164. RegCloseKey(hKey);
  165. DebugPrintEx(DEBUG_ERR, _T("Routing Extension Name is duplicated : %s"), szKeyName);
  166. dwLastError = ERROR_INVALID_PARAMETER;
  167. bResult = FALSE;
  168. goto FreeRoutingInfo;
  169. }
  170. //
  171. // Add values
  172. //
  173. if (! (SetRegistryString(hKey, REGVAL_FRIENDLY_NAME, lpcwstrFriendlyName) &&
  174. SetRegistryStringExpand(hKey, REGVAL_IMAGE_NAME, lpcwstrImageName) ))
  175. {
  176. dwLastError = GetLastError();
  177. DebugPrintEx(DEBUG_ERR, _T("SetRegistryString failed. ec=%ld"), dwLastError);
  178. goto error_exit;
  179. }
  180. dwRet = RegCloseKey (hKey);
  181. if (ERROR_SUCCESS != dwRet)
  182. {
  183. DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
  184. }
  185. wcscat(szKeyName, L"\\");
  186. wcscat(szKeyName, REGKEY_ROUTING_METHODS);
  187. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,
  188. szKeyName,
  189. TRUE,
  190. 0);
  191. if (!hKey)
  192. {
  193. dwLastError = GetLastError();
  194. DebugPrintEx(DEBUG_ERR, _T("OpenRegistryKey(%s) failed. ec=%ld"), szKeyName, dwLastError);
  195. goto error_exit;
  196. }
  197. while (TRUE)
  198. {
  199. ZeroMemory( wszMethodName, sizeof(wszMethodName) );
  200. ZeroMemory( wszMethodFriendlyName, sizeof(wszMethodFriendlyName) );
  201. ZeroMemory( wszMethodFunctionName, sizeof(wszMethodFunctionName) );
  202. ZeroMemory( wszMethodGuid, sizeof(wszMethodGuid) );
  203. __try
  204. {
  205. bRetVal = pCallBack(hFaxHandle,
  206. lpvContext,
  207. wszMethodName,
  208. wszMethodFriendlyName,
  209. wszMethodFunctionName,
  210. wszMethodGuid
  211. );
  212. if (!bRetVal)
  213. {
  214. break;
  215. }
  216. }
  217. __except (EXCEPTION_EXECUTE_HANDLER)
  218. {
  219. dwLastError = GetExceptionCode();
  220. DebugPrintEx(DEBUG_ERR, _T("pCallBack caused exception. ec=%ld"), dwLastError);
  221. goto error_exit;
  222. }
  223. //
  224. // Check that Method Name is existing
  225. //
  226. if (wcslen(wszMethodName) < 1)
  227. {
  228. DebugPrintEx(DEBUG_ERR, _T("Callback returned empty MethodName"));
  229. dwLastError = ERROR_INVALID_PARAMETER;
  230. goto error_exit;
  231. }
  232. //
  233. // Check that new Guid is valid GUID
  234. //
  235. if ( ERROR_SUCCESS != (dwRet = IsValidGUID(wszMethodGuid)) )
  236. {
  237. DebugPrintEx(DEBUG_ERR,
  238. _T("IsValidGUID failed: %s, ec=%d"),
  239. wszMethodGuid,
  240. dwRet);
  241. dwLastError = dwRet;
  242. goto error_exit;
  243. }
  244. //
  245. // Check that new Guid is unique between all already registered Routing Methods
  246. //
  247. for ( i = 0 ; i < dwRegisteredMethods ; i++ )
  248. {
  249. if ( _tcsicmp(pRoutingInfo[i].Guid, wszMethodGuid) == 0 )
  250. {
  251. //
  252. // Such Guid already registered
  253. //
  254. DebugPrintEx(DEBUG_ERR, _T("Duplicated Guid : %s."), wszMethodGuid);
  255. dwLastError = ERROR_DS_OBJ_GUID_EXISTS;
  256. goto error_exit;
  257. }
  258. }
  259. //
  260. // Check that new Guid is unique between newly added Routing Methods
  261. //
  262. if ( plptstrNewGuids )
  263. {
  264. //
  265. // There is ( dwMethods - dwRegisteredMethods ) new Methods
  266. //
  267. for( i = 0 ; i < (dwMethods - dwRegisteredMethods) ; i++ )
  268. {
  269. if ( _tcsicmp(plptstrNewGuids[i], wszMethodGuid) == 0 )
  270. {
  271. //
  272. // Such Guid already registered
  273. //
  274. DebugPrintEx(DEBUG_ERR, _T("Duplicated Guid : %s."), wszMethodGuid);
  275. dwLastError = ERROR_DS_OBJ_GUID_EXISTS;
  276. goto error_exit;
  277. }
  278. }
  279. }
  280. //
  281. // We're using the dwMethods as priority for new methods
  282. //
  283. dwMethods++;
  284. if (!AddMethodKey(hKey,
  285. wszMethodName,
  286. wszMethodFriendlyName,
  287. wszMethodFunctionName,
  288. wszMethodGuid,
  289. dwMethods))
  290. {
  291. dwLastError = GetLastError();
  292. DebugPrintEx(DEBUG_ERR, _T("AddMethodKey failed. ec=%ld"), dwLastError);
  293. goto error_exit;
  294. }
  295. //
  296. // We succeded to add a method. Store its Guid to compare with next Methods
  297. //
  298. lptstrGuid = (LPTSTR)MemAlloc( ( _tcslen(wszMethodGuid) + 1 ) * sizeof(TCHAR));
  299. if (!lptstrGuid)
  300. {
  301. dwLastError = ERROR_NOT_ENOUGH_MEMORY;
  302. DebugPrintEx(DEBUG_ERR, _T("MemAlloc failed"));
  303. goto error_exit;
  304. }
  305. _tcscpy(lptstrGuid, wszMethodGuid);
  306. //
  307. // ReAllocate Memory for extended pNewGuids
  308. //
  309. if (plptstrNewGuids)
  310. {
  311. pTmp = (LPTSTR *)MemReAlloc(plptstrNewGuids,
  312. (sizeof(LPTSTR)) * (dwMethods - dwRegisteredMethods));
  313. }
  314. else
  315. {
  316. pTmp = (LPTSTR *)MemAlloc((sizeof(LPTSTR)) * (dwMethods - dwRegisteredMethods));
  317. }
  318. if (!pTmp)
  319. {
  320. dwLastError = ERROR_NOT_ENOUGH_MEMORY;
  321. DebugPrintEx(DEBUG_ERR, _T("MemReAlloc failed"));
  322. goto error_exit;
  323. }
  324. plptstrNewGuids = pTmp;
  325. //
  326. // Put also last added Method's Guid
  327. //
  328. plptstrNewGuids[ (dwMethods - dwRegisteredMethods - 1) ] = lptstrGuid;
  329. }
  330. dwRet = RegCloseKey (hKey);
  331. if (ERROR_SUCCESS != dwRet)
  332. {
  333. dwLastError = dwRet;
  334. DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
  335. }
  336. goto FreeRoutingInfo;
  337. error_exit:
  338. if (hKey)
  339. {
  340. dwRet = RegCloseKey (hKey);
  341. if (ERROR_SUCCESS != dwRet)
  342. {
  343. DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
  344. }
  345. }
  346. //
  347. // Delete the subkey on failure
  348. //
  349. wsprintf(szKeyName, L"%s\\%s", REGKEY_SOFTWARE, REGKEY_ROUTING_EXTENSIONS);
  350. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, szKeyName, FALSE, 0);
  351. if (hKey)
  352. {
  353. //
  354. // Delete the Extension Routing Key and all its Subkeys
  355. //
  356. dwRet = DeleteRegistryKey(hKey, lpcwstrExtensionName );
  357. if (ERROR_SUCCESS != dwRet)
  358. {
  359. DebugPrintEx(DEBUG_ERR,
  360. _T("DeleteRegistryKey (%s) failed. ec=%ld"),
  361. lpcwstrExtensionName,
  362. dwRet);
  363. }
  364. dwRet = RegCloseKey (hKey);
  365. if (ERROR_SUCCESS != dwRet)
  366. {
  367. DebugPrintEx(DEBUG_ERR, _T("RegCloseKey failed. ec=%ld"), dwRet);
  368. }
  369. }
  370. bResult = FALSE;
  371. FreeRoutingInfo:
  372. FaxFreeBuffer(pRoutingInfo);
  373. if (plptstrNewGuids)
  374. {
  375. for ( i = 0 ; i < ( dwMethods - dwRegisteredMethods ) ; i++ )
  376. {
  377. MemFree(plptstrNewGuids[i]);
  378. }
  379. MemFree(plptstrNewGuids);
  380. }
  381. if (ERROR_SUCCESS != dwLastError)
  382. {
  383. SetLastError(dwLastError);
  384. }
  385. return bResult;
  386. } // FaxRegisterRoutingExtensionW
  387. BOOL AddMethodKey(
  388. HKEY hKey,
  389. LPCWSTR lpcwstrMethodName,
  390. LPCWSTR lpcwstrFriendlyName,
  391. LPCWSTR lpcwstrFunctionName,
  392. LPCWSTR lpcwstrGuid,
  393. DWORD dwPriority
  394. )
  395. {
  396. HKEY hKeyNew;
  397. DWORD dwRet;
  398. DEBUG_FUNCTION_NAME(TEXT("AddMethodKey"));
  399. hKeyNew = OpenRegistryKey(hKey,
  400. lpcwstrMethodName,
  401. TRUE,
  402. 0);
  403. if (!hKeyNew)
  404. {
  405. DebugPrintEx(DEBUG_ERR,
  406. TEXT("OpenRegistryKey(%s) failed. ec=%ld"),
  407. lpcwstrMethodName,
  408. GetLastError ());
  409. return FALSE;
  410. }
  411. //
  412. // Add values
  413. //
  414. if (!(SetRegistryString(hKeyNew, REGVAL_FRIENDLY_NAME, lpcwstrFriendlyName) &&
  415. SetRegistryString(hKeyNew, REGVAL_FUNCTION_NAME, lpcwstrFunctionName) &&
  416. SetRegistryString(hKeyNew, REGVAL_GUID, lpcwstrGuid) &&
  417. SetRegistryDword (hKeyNew, REGVAL_ROUTING_PRIORITY, dwPriority)
  418. ))
  419. {
  420. DebugPrintEx(DEBUG_ERR,
  421. TEXT("SetRegistry failed. ec=%ld"),
  422. GetLastError ());
  423. goto error_exit;
  424. }
  425. dwRet = RegCloseKey (hKeyNew);
  426. if (ERROR_SUCCESS != dwRet)
  427. {
  428. DebugPrintEx(DEBUG_ERR,
  429. TEXT("RegCloseKey failed. ec=%ld"),
  430. dwRet);
  431. }
  432. return TRUE;
  433. error_exit:
  434. dwRet = RegCloseKey (hKeyNew);
  435. if (ERROR_SUCCESS != dwRet)
  436. {
  437. DebugPrintEx(DEBUG_ERR,
  438. TEXT("RegCloseKey failed. ec=%ld"),
  439. dwRet);
  440. }
  441. dwRet = RegDeleteKey (hKey, lpcwstrMethodName);
  442. if (ERROR_SUCCESS != dwRet)
  443. {
  444. DebugPrintEx(DEBUG_ERR,
  445. TEXT("RegDeleteKey (%s) failed. ec=%ld"),
  446. lpcwstrMethodName,
  447. dwRet);
  448. }
  449. return FALSE;
  450. } // AddMethodKey
  451. #else
  452. WINFAXAPI
  453. BOOL
  454. WINAPI
  455. FaxRegisterRoutingExtensionW(
  456. IN HANDLE FaxHandle,
  457. IN LPCWSTR ExtensionName,
  458. IN LPCWSTR FriendlyName,
  459. IN LPCWSTR ImageName,
  460. IN PFAX_ROUTING_INSTALLATION_CALLBACKW CallBack,
  461. IN LPVOID Context
  462. )
  463. {
  464. UNREFERENCED_PARAMETER (FaxHandle);
  465. UNREFERENCED_PARAMETER (ExtensionName);
  466. UNREFERENCED_PARAMETER (FriendlyName);
  467. UNREFERENCED_PARAMETER (ImageName);
  468. UNREFERENCED_PARAMETER (CallBack);
  469. UNREFERENCED_PARAMETER (Context);
  470. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  471. return FALSE;
  472. }
  473. #endif // #ifdef UNICODE
  474. WINFAXAPI
  475. BOOL
  476. WINAPI
  477. FaxUnregisterRoutingExtensionA(
  478. IN HANDLE hFaxHandle,
  479. IN LPCSTR lpctstrExtensionName
  480. )
  481. /*++
  482. Routine name : FaxUnregisterRoutingExtensionA
  483. Routine description:
  484. Unregisters a routing extension - ANSI version
  485. Author:
  486. Eran Yariv (EranY), Dec, 1999
  487. Arguments:
  488. hFaxHandle [in] - Handle to fax server
  489. lpctstrExtensionName [in] - Extension unique name
  490. Return Value:
  491. TRUE - Success
  492. FALSE - Failure, call GetLastError() for more error information.
  493. --*/
  494. {
  495. DWORD dwRes;
  496. BOOL bRes;
  497. LPCWSTR lpcwstrExtensionName = NULL;
  498. DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterRoutingExtensionA"));
  499. if (lpctstrExtensionName)
  500. {
  501. if (NULL ==
  502. (lpcwstrExtensionName = AnsiStringToUnicodeString(lpctstrExtensionName))
  503. )
  504. {
  505. dwRes = GetLastError ();
  506. DebugPrintEx(
  507. DEBUG_ERR,
  508. TEXT("Failed to convert Extension unique name to UNICODE (ec = %ld)"),
  509. dwRes);
  510. return dwRes;
  511. }
  512. }
  513. bRes = FaxUnregisterRoutingExtensionW (hFaxHandle, lpcwstrExtensionName);
  514. MemFree((PVOID)lpcwstrExtensionName);
  515. return bRes;
  516. } // FaxUnregisterRoutingExtensionA
  517. WINFAXAPI
  518. BOOL
  519. WINAPI
  520. FaxUnregisterRoutingExtensionW(
  521. IN HANDLE hFaxHandle,
  522. IN LPCWSTR lpctstrExtensionName
  523. )
  524. /*++
  525. Routine name : FaxUnregisterRoutingExtensionW
  526. Routine description:
  527. Unregisters a routing extension - UNICODE version
  528. Author:
  529. Eran Yariv (EranY), Dec, 1999
  530. Arguments:
  531. hFaxHandle [in] - Handle to fax server
  532. lpctstrExtensionName [in] - Extension unique name
  533. Return Value:
  534. TRUE - Success
  535. FALSE - Failure, call GetLastError() for more error information.
  536. --*/
  537. {
  538. error_status_t ec;
  539. DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterRoutingExtensionW"));
  540. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  541. {
  542. SetLastError (ERROR_INVALID_HANDLE);
  543. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed."));
  544. return FALSE;
  545. }
  546. if (!lpctstrExtensionName)
  547. {
  548. SetLastError (ERROR_INVALID_PARAMETER);
  549. DebugPrintEx(DEBUG_ERR, _T("lpctstrExtensionName is NULL."));
  550. return FALSE;
  551. }
  552. __try
  553. {
  554. ec = FAX_UnregisterRoutingExtension(
  555. FH_FAX_HANDLE(hFaxHandle),
  556. lpctstrExtensionName);
  557. }
  558. __except (EXCEPTION_EXECUTE_HANDLER)
  559. {
  560. //
  561. // For some reason we got an exception.
  562. //
  563. ec = GetExceptionCode();
  564. DebugPrintEx(
  565. DEBUG_ERR,
  566. TEXT("Exception on RPC call to FAX_UnregisterRoutingExtension. (ec: %ld)"),
  567. ec);
  568. }
  569. if (ERROR_SUCCESS != ec)
  570. {
  571. DumpRPCExtendedStatus ();
  572. SetLastError (ec);
  573. return FALSE;
  574. }
  575. return TRUE;
  576. } // FaxUnregisterRoutingExtensionW
  577. #ifndef UNICODE
  578. WINFAXAPI
  579. BOOL
  580. WINAPI
  581. FaxUnregisterRoutingExtensionX(
  582. IN HANDLE hFaxHandle,
  583. IN LPCWSTR lpctstrExtensionName
  584. )
  585. {
  586. UNREFERENCED_PARAMETER (hFaxHandle);
  587. UNREFERENCED_PARAMETER (lpctstrExtensionName);
  588. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  589. return FALSE;
  590. } // FaxUnregisterRoutingExtensionX
  591. #endif // #ifndef UNICODE
  592. //********************************************
  593. //* FSP registration
  594. //********************************************
  595. WINFAXAPI
  596. BOOL
  597. WINAPI
  598. FaxRegisterServiceProviderExA(
  599. IN HANDLE hFaxHandle,
  600. IN LPCSTR lpctstrGUID,
  601. IN LPCSTR lpctstrFriendlyName,
  602. IN LPCSTR lpctstrImageName,
  603. IN LPCSTR lpctstrTspName,
  604. IN DWORD dwFSPIVersion,
  605. IN DWORD dwCapabilities
  606. )
  607. /*++
  608. Routine name : FaxRegisterServiceProviderExA
  609. Routine description:
  610. Registers an FSP - ANSI version
  611. Author:
  612. Eran Yariv (EranY), Dec, 1999
  613. Arguments:
  614. hFaxHandle [in] - Handle to fax server
  615. lpctstrGUID [in] - GUID of FSP
  616. lpctstrFriendlyName [in] - Friendly name of FSP
  617. lpctstrImageName [in] - Image name of FSP. May contain environment variables
  618. lpctstrTspName [in] - TSP name of FSP.
  619. dwFSPIVersion [in] - FSP's API version.
  620. dwCapabilities [in] - FSP's extended capabilities.
  621. Return Value:
  622. TRUE - Success
  623. FALSE - Failure, call GetLastError() for more error information.
  624. --*/
  625. {
  626. DWORD dwRes = ERROR_SUCCESS;
  627. LPCWSTR lpcwstrGUID = NULL;
  628. LPCWSTR lpcwstrFriendlyName = NULL;
  629. LPCWSTR lpcwstrImageName = NULL;
  630. LPCWSTR lpcwstrTspName = NULL;
  631. BOOL bRes = FALSE;
  632. DEBUG_FUNCTION_NAME(TEXT("FaxRegisterServiceProviderExA"));
  633. if (lpctstrGUID)
  634. {
  635. if (NULL ==
  636. (lpcwstrGUID = AnsiStringToUnicodeString(lpctstrGUID))
  637. )
  638. {
  639. dwRes = GetLastError ();
  640. DebugPrintEx(
  641. DEBUG_ERR,
  642. TEXT("Failed to convert GUID to UNICODE (ec = %ld)"),
  643. dwRes);
  644. goto exit;
  645. }
  646. }
  647. if (lpctstrFriendlyName)
  648. {
  649. if (NULL ==
  650. (lpcwstrFriendlyName = AnsiStringToUnicodeString(lpctstrFriendlyName))
  651. )
  652. {
  653. dwRes = GetLastError ();
  654. DebugPrintEx(
  655. DEBUG_ERR,
  656. TEXT("Failed to convert Friendly Name to UNICODE (ec = %ld)"),
  657. dwRes);
  658. goto exit;
  659. }
  660. }
  661. if (lpctstrImageName)
  662. {
  663. if (NULL ==
  664. (lpcwstrImageName = AnsiStringToUnicodeString(lpctstrImageName))
  665. )
  666. {
  667. dwRes = GetLastError ();
  668. DebugPrintEx(
  669. DEBUG_ERR,
  670. TEXT("Failed to convert Image Name to UNICODE (ec = %ld)"),
  671. dwRes);
  672. goto exit;
  673. }
  674. }
  675. if (lpctstrTspName)
  676. {
  677. if (NULL ==
  678. (lpcwstrTspName = AnsiStringToUnicodeString(lpctstrTspName))
  679. )
  680. {
  681. dwRes = GetLastError ();
  682. DebugPrintEx(
  683. DEBUG_ERR,
  684. TEXT("Failed to convert TSP name to UNICODE (ec = %ld)"),
  685. dwRes);
  686. goto exit;
  687. }
  688. }
  689. Assert (ERROR_SUCCESS == dwRes);
  690. bRes = FaxRegisterServiceProviderExW (
  691. hFaxHandle,
  692. lpcwstrGUID,
  693. lpcwstrFriendlyName,
  694. lpcwstrImageName,
  695. lpcwstrTspName,
  696. dwFSPIVersion,
  697. dwCapabilities);
  698. exit:
  699. MemFree((PVOID)lpcwstrGUID);
  700. MemFree((PVOID)lpcwstrFriendlyName);
  701. MemFree((PVOID)lpcwstrImageName);
  702. MemFree((PVOID)lpcwstrTspName);
  703. return bRes;
  704. } // FaxRegisterServiceProviderExA
  705. WINFAXAPI
  706. BOOL
  707. WINAPI
  708. FaxRegisterServiceProviderExW(
  709. IN HANDLE hFaxHandle,
  710. IN LPCWSTR lpctstrGUID,
  711. IN LPCWSTR lpctstrFriendlyName,
  712. IN LPCWSTR lpctstrImageName,
  713. IN LPCWSTR lpctstrTspName,
  714. IN DWORD dwFSPIVersion,
  715. IN DWORD dwCapabilities
  716. )
  717. /*++
  718. Routine name : FaxRegisterServiceProviderExW
  719. Routine description:
  720. Registers an FSP - UNICODE version
  721. Author:
  722. Eran Yariv (EranY), Dec, 1999
  723. Arguments:
  724. hFaxHandle [in] - Handle to fax server
  725. lpctstrGUID [in] - GUID of FSP
  726. lpctstrFriendlyName [in] - Friendly name of FSP
  727. lpctstrImageName [in] - Image name of FSP. May contain environment variables
  728. lpctstrTspName [in] - TSP name of FSP.
  729. dwFSPIVersion [in] - FSP's API version.
  730. dwCapabilities [in] - FSP's extended capabilities.
  731. Return Value:
  732. TRUE - Success
  733. FALSE - Failure, call GetLastError() for more error information.
  734. --*/
  735. {
  736. error_status_t ec;
  737. DEBUG_FUNCTION_NAME(TEXT("FaxRegisterServiceProviderExW"));
  738. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  739. {
  740. SetLastError (ERROR_INVALID_HANDLE);
  741. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed."));
  742. return FALSE;
  743. }
  744. //
  745. // Verify version field range
  746. //
  747. if (FSPI_API_VERSION_1 != dwFSPIVersion ||
  748. dwCapabilities)
  749. {
  750. DebugPrintEx(
  751. DEBUG_ERR,
  752. TEXT("dwFSPIVersion invalid (0x%08x), or not valid capability (0x%08x)"),
  753. dwFSPIVersion,
  754. dwCapabilities);
  755. return ERROR_INVALID_PARAMETER;
  756. }
  757. ec = IsValidGUID (lpctstrGUID);
  758. if (ERROR_SUCCESS != ec)
  759. {
  760. DebugPrintEx(
  761. DEBUG_ERR,
  762. TEXT("Invalid GUID (ec: %ld)"),
  763. ec);
  764. SetLastError (ec);
  765. return FALSE;
  766. }
  767. __try
  768. {
  769. ec = FAX_RegisterServiceProviderEx(
  770. FH_FAX_HANDLE(hFaxHandle),
  771. lpctstrGUID,
  772. lpctstrFriendlyName,
  773. lpctstrImageName,
  774. lpctstrTspName ? lpctstrTspName : L"",
  775. dwFSPIVersion,
  776. dwCapabilities);
  777. }
  778. __except (EXCEPTION_EXECUTE_HANDLER)
  779. {
  780. //
  781. // For some reason we got an exception.
  782. //
  783. ec = GetExceptionCode();
  784. DebugPrintEx(
  785. DEBUG_ERR,
  786. TEXT("Exception on RPC call to FAX_RegisterServiceProviderEx. (ec: %ld)"),
  787. ec);
  788. }
  789. if (ERROR_SUCCESS != ec)
  790. {
  791. DumpRPCExtendedStatus ();
  792. SetLastError (ec);
  793. return FALSE;
  794. }
  795. else if (IsLocalFaxConnection(hFaxHandle))
  796. {
  797. //
  798. // Adding a local FSP.
  799. // If we don't have a fax printer installed, this is the time to install one.
  800. //
  801. AddOrVerifyLocalFaxPrinter();
  802. }
  803. return TRUE;
  804. } // FaxRegisterServiceProviderExW
  805. #ifndef UNICODE
  806. WINFAXAPI
  807. BOOL
  808. WINAPI
  809. FaxRegisterServiceProviderExX(
  810. IN HANDLE hFaxHandle,
  811. IN LPCWSTR lpctstrGUID,
  812. IN LPCWSTR lpctstrFriendlyName,
  813. IN LPCWSTR lpctstrImageName,
  814. IN LPCWSTR lpctstrTspName,
  815. IN DWORD dwFSPIVersion,
  816. IN DWORD dwCapabilities
  817. )
  818. {
  819. UNREFERENCED_PARAMETER (hFaxHandle);
  820. UNREFERENCED_PARAMETER (lpctstrGUID);
  821. UNREFERENCED_PARAMETER (lpctstrFriendlyName);
  822. UNREFERENCED_PARAMETER (lpctstrImageName);
  823. UNREFERENCED_PARAMETER (lpctstrTspName);
  824. UNREFERENCED_PARAMETER (dwFSPIVersion);
  825. UNREFERENCED_PARAMETER (dwCapabilities);
  826. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  827. return FALSE;
  828. } // FaxRegisterServiceProviderExX
  829. #endif // #ifndef UNICODE
  830. WINFAXAPI
  831. BOOL
  832. WINAPI
  833. FaxUnregisterServiceProviderExA(
  834. IN HANDLE hFaxHandle,
  835. IN LPCSTR lpctstrGUID
  836. )
  837. /*++
  838. Routine name : FaxUnregisterServiceProviderExA
  839. Routine description:
  840. Unregisters an FSP - ANSI version
  841. Author:
  842. Eran Yariv (EranY), Dec, 1999
  843. Arguments:
  844. hFaxHandle [in] - Handle to fax server
  845. lpctstrGUID [in] - GUID of FSP
  846. (or provider name for legacy FSPs registered
  847. through FaxRegisterServiceProvider)
  848. Return Value:
  849. TRUE - Success
  850. FALSE - Failure, call GetLastError() for more error information.
  851. --*/
  852. {
  853. DWORD dwRes;
  854. LPCWSTR lpcwstrGUID = NULL;
  855. BOOL bRes;
  856. DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterServiceProviderExA"));
  857. if (lpctstrGUID)
  858. {
  859. if (NULL ==
  860. (lpcwstrGUID = AnsiStringToUnicodeString(lpctstrGUID))
  861. )
  862. {
  863. dwRes = GetLastError ();
  864. DebugPrintEx(
  865. DEBUG_ERR,
  866. TEXT("Failed to convert GUID to UNICODE (ec = %ld)"),
  867. dwRes);
  868. return dwRes;
  869. }
  870. }
  871. bRes = FaxUnregisterServiceProviderExW (hFaxHandle, lpcwstrGUID);
  872. MemFree((PVOID)lpcwstrGUID);
  873. return bRes;
  874. } // FaxUnregisterServiceProviderExA
  875. WINFAXAPI
  876. BOOL
  877. WINAPI
  878. FaxUnregisterServiceProviderExW(
  879. IN HANDLE hFaxHandle,
  880. IN LPCWSTR lpctstrGUID
  881. )
  882. /*++
  883. Routine name : FaxUnregisterServiceProviderExW
  884. Routine description:
  885. Unregisters an FSP - UNICODE version
  886. Author:
  887. Eran Yariv (EranY), Dec, 1999
  888. Arguments:
  889. hFaxHandle [in] - Handle to fax server
  890. lpctstrGUID [in] - GUID of FSP
  891. (or provider name for legacy FSPs registered
  892. through FaxRegisterServiceProvider)
  893. Return Value:
  894. TRUE - Success
  895. FALSE - Failure, call GetLastError() for more error information.
  896. --*/
  897. {
  898. error_status_t ec;
  899. DEBUG_FUNCTION_NAME(TEXT("FaxUnregisterServiceProviderExW"));
  900. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  901. {
  902. SetLastError (ERROR_INVALID_HANDLE);
  903. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  904. return FALSE;
  905. }
  906. if (!lpctstrGUID)
  907. {
  908. SetLastError (ERROR_INVALID_PARAMETER);
  909. DebugPrintEx(DEBUG_ERR, _T("lpctstrGUID is NULL."));
  910. return FALSE;
  911. }
  912. __try
  913. {
  914. ec = FAX_UnregisterServiceProviderEx(
  915. FH_FAX_HANDLE(hFaxHandle),
  916. lpctstrGUID);
  917. }
  918. __except (EXCEPTION_EXECUTE_HANDLER)
  919. {
  920. //
  921. // For some reason we got an exception.
  922. //
  923. ec = GetExceptionCode();
  924. DebugPrintEx(
  925. DEBUG_ERR,
  926. TEXT("Exception on RPC call to FAX_UnregisterServiceProviderEx. (ec: %ld)"),
  927. ec);
  928. }
  929. if (ERROR_SUCCESS != ec)
  930. {
  931. DumpRPCExtendedStatus ();
  932. SetLastError (ec);
  933. return FALSE;
  934. }
  935. return TRUE;
  936. } // FaxUnregisterServiceProviderExW
  937. #ifndef UNICODE
  938. WINFAXAPI
  939. BOOL
  940. WINAPI
  941. FaxUnregisterServiceProviderExX(
  942. IN HANDLE hFaxHandle,
  943. IN LPCWSTR lpctstrGUID
  944. )
  945. {
  946. UNREFERENCED_PARAMETER (hFaxHandle);
  947. UNREFERENCED_PARAMETER (lpctstrGUID);
  948. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  949. return FALSE;
  950. } // FaxUnregisterServiceProviderExX
  951. #endif // #ifndef UNICODE