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.

1220 lines
45 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File Name: fxUnatnd.cpp
  4. //
  5. // Abstract: Fax OCM Setup unattended file processing
  6. //
  7. // Environment: Windows XP / User Mode
  8. //
  9. // Copyright (c) 2000 Microsoft Corporation
  10. //
  11. // Revision History:
  12. //
  13. // Date: Developer: Comments:
  14. // ----- ---------- ---------
  15. // 27-Mar-2000 Oren Rosenbloom (orenr) Created
  16. //////////////////////////////////////////////////////////////////////////////
  17. #include "faxocm.h"
  18. #pragma hdrstop
  19. static DWORD SaveSettingsFromAnswerFile();
  20. #define prv_VALID_BOOL_VALUE_YES _T("yes")
  21. #define prv_VALID_BOOL_VALUE_NO _T("no")
  22. #define prv_VALID_BOOL_VALUE_TRUE _T("true")
  23. #define prv_VALID_BOOL_VALUE_FALSE _T("false")
  24. #define prv_HKLM HKEY_LOCAL_MACHINE
  25. #define prv_HKCU HKEY_CURRENT_USER
  26. ///////////////////////////////
  27. // prv_GVAR
  28. //
  29. // This is used as temporary
  30. // storage so that we can
  31. // reference the individual
  32. // fields in the prv_UnattendedRules
  33. // table below.
  34. //
  35. static struct prv_GVAR
  36. {
  37. fxUnatnd_UnattendedData_t UnattendedData;
  38. } prv_GVAR;
  39. ///////////////////////////////
  40. // prv_UnattendedRule_t
  41. //
  42. // Structure used as a table
  43. // entry below.
  44. //
  45. typedef struct prv_UnattendedRule_t
  46. {
  47. DWORD dwType;
  48. const TCHAR *pszFromInfKeyName;
  49. HKEY hKeyTo;
  50. const TCHAR *pszToRegPath;
  51. const TCHAR *pszToRegKey;
  52. void *pData;
  53. BOOL bValid;
  54. } prv_UnattendedRule_t;
  55. #define RULE_CSID _T("Csid")
  56. #define RULE_TSID _T("Tsid")
  57. #define RULE_RINGS _T("Rings")
  58. #define RULE_SENDFAXES _T("SendFaxes")
  59. #define RULE_RECEIVEFAXES _T("ReceiveFaxes")
  60. #define RULE_SUPPRESSCONFIGURATIONWIZARD _T("SkipConfigWizardDeviceSettings")
  61. // this is added here since this was the rule's name at the time we shipped XP.
  62. #define RULE_SUPPRESSCONFIGWIZARD_LEGACY _T("SuppressConfigurationWizard")
  63. //
  64. #define RULE_ARCHIVEINCOMING _T("ArchiveIncoming")
  65. #define RULE_ARCHIVEINCOMINGFOLDERNAME _T("ArchiveIncomingFolderName")
  66. #define RULE_ARCHIVEOUTGOING _T("ArchiveOutgoing")
  67. #define RULE_ARCHIVEFOLDERNAME _T("ArchiveFolderName")
  68. #define RULE_ARCHIVEOUTGOINGFOLDERNAME _T("ArchiveOutgoingFolderName")
  69. #define RULE_FAXUSERNAME _T("FaxUserName")
  70. #define RULE_FAXUSERPASSWORD _T("FaxUserPassword")
  71. #define RULE_SMTPNOTIFICATIONSENABLED _T("SmtpNotificationsEnabled")
  72. #define RULE_SMTPSENDERADDRESS _T("SmtpSenderAddress")
  73. #define RULE_SMTPSERVERADDRESS _T("SmtpServerAddress")
  74. #define RULE_SMTPSERVERPORT _T("SmtpServerPort")
  75. #define RULE_SMTPSERVERAUTHENTICATIONMECHANISM _T("SmtpServerAuthenticationMechanism")
  76. #define RULE_FAXPRINTERNAME _T("FaxPrinterName")
  77. #define RULE_FAXPRINTERSHARED _T("FaxPrinterIsShared")
  78. #define RULE_ROUTETOPRINTER _T("RouteToPrinter")
  79. #define RULE_ROUTEPRINTERNAME _T("RoutePrinterName")
  80. #define RULE_ROUTETOEMAIL _T("RouteToEmail")
  81. #define RULE_ROUTETOEMAILRECIPIENT _T("RouteToEmailRecipient")
  82. #define RULE_ROUTETOFOLDER _T("RouteToFolder")
  83. #define RULE_ROUTEFOLDERNAME _T("RouteFolderName")
  84. #define ANSWER_ANONYMOUS _T("Anonymous")
  85. #define ANSWER_BASIC _T("Basic")
  86. #define ANSWER_WINDOWSSECURITY _T("WindowsSecurity")
  87. ///////////////////////////////
  88. // prv_UnattendedRules
  89. //
  90. // Simply put, these rules describe
  91. // what registry values to set
  92. // based on keywords found in an
  93. // unattended file.
  94. //
  95. // The format of these rules is
  96. // self explanatory after looking
  97. // at the structure definition above.
  98. // Basically, we read in a value from
  99. // the unattended file which is specified
  100. // in the 'pszFromInfKeyName'. This is
  101. // then stored in 'pData'. Once
  102. // "SaveUnattendedData" is called, 'pData'
  103. // is committed to the registry location
  104. // specified by 'hKeyTo' and 'pszToRegPath'
  105. // and 'pszToRegKey'.
  106. //
  107. static prv_UnattendedRule_t prv_UnattendedRules[] =
  108. {
  109. {REG_SZ, RULE_CSID, prv_HKLM, REGKEY_FAX_SETUP_ORIG, REGVAL_ROUTING_CSID, prv_GVAR.UnattendedData.szCSID, FALSE},
  110. {REG_SZ, RULE_TSID, prv_HKLM, REGKEY_FAX_SETUP_ORIG, REGVAL_ROUTING_TSID, prv_GVAR.UnattendedData.szTSID, FALSE},
  111. {REG_DWORD, RULE_RINGS, prv_HKLM, REGKEY_FAX_SETUP_ORIG, REGVAL_RINGS, &prv_GVAR.UnattendedData.dwRings, FALSE},
  112. {REG_DWORD, RULE_SENDFAXES, NULL, NULL, NULL, &prv_GVAR.UnattendedData.dwSendFaxes, FALSE},
  113. {REG_DWORD, RULE_RECEIVEFAXES, NULL, NULL, NULL, &prv_GVAR.UnattendedData.dwReceiveFaxes, FALSE},
  114. // should we run the configuration wizard for this unattended installation
  115. {REG_DWORD, RULE_SUPPRESSCONFIGURATIONWIZARD, prv_HKLM, REGKEY_FAX_CLIENT, REGVAL_CFGWZRD_DEVICE, &prv_GVAR.UnattendedData.dwSuppressConfigurationWizard, TRUE},
  116. {REG_DWORD, RULE_SUPPRESSCONFIGWIZARD_LEGACY, prv_HKLM, REGKEY_FAX_CLIENT, REGVAL_CFGWZRD_DEVICE, &prv_GVAR.UnattendedData.dwSuppressConfigurationWizard, FALSE},
  117. // Inbox configuration.
  118. {REG_DWORD, RULE_ARCHIVEINCOMING, prv_HKLM, REGKEY_FAX_INBOX, REGVAL_ARCHIVE_USE, &prv_GVAR.UnattendedData.bArchiveIncoming, FALSE},
  119. {REG_SZ, RULE_ARCHIVEINCOMINGFOLDERNAME, prv_HKLM, REGKEY_FAX_INBOX, REGVAL_ARCHIVE_FOLDER, prv_GVAR.UnattendedData.szArchiveIncomingDir, FALSE},
  120. // save outgoing faxes in a directory.
  121. {REG_DWORD, RULE_ARCHIVEOUTGOING, prv_HKLM, REGKEY_FAX_SENTITEMS, REGVAL_ARCHIVE_USE, &prv_GVAR.UnattendedData.bArchiveOutgoing, FALSE},
  122. {REG_SZ, RULE_ARCHIVEFOLDERNAME, prv_HKLM, REGKEY_FAX_SENTITEMS, REGVAL_ARCHIVE_FOLDER, prv_GVAR.UnattendedData.szArchiveOutgoingDir, FALSE},
  123. {REG_SZ, RULE_ARCHIVEOUTGOINGFOLDERNAME, prv_HKLM, REGKEY_FAX_SENTITEMS, REGVAL_ARCHIVE_FOLDER, prv_GVAR.UnattendedData.szArchiveOutgoingDir, FALSE},
  124. // SMTP receipts and server configuration
  125. {REG_SZ, RULE_FAXUSERNAME, prv_HKLM, REGKEY_FAX_RECEIPTS, REGVAL_RECEIPTS_USER, prv_GVAR.UnattendedData.szFaxUserName, FALSE},
  126. {REG_BINARY, RULE_FAXUSERPASSWORD, prv_HKLM, REGKEY_FAX_RECEIPTS, REGVAL_RECEIPTS_PASSWORD, prv_GVAR.UnattendedData.szFaxUserPassword, FALSE},
  127. {REG_DWORD, RULE_SMTPNOTIFICATIONSENABLED, NULL, NULL, NULL, &prv_GVAR.UnattendedData.bSmtpNotificationsEnabled, FALSE},
  128. {REG_SZ, RULE_SMTPSENDERADDRESS, prv_HKLM, REGKEY_FAX_RECEIPTS, REGVAL_RECEIPTS_FROM, prv_GVAR.UnattendedData.szSmtpSenderAddress, FALSE},
  129. {REG_SZ, RULE_SMTPSERVERADDRESS, prv_HKLM, REGKEY_FAX_RECEIPTS, REGVAL_RECEIPTS_SERVER, prv_GVAR.UnattendedData.szSmptServerAddress, FALSE},
  130. {REG_DWORD, RULE_SMTPSERVERPORT, prv_HKLM, REGKEY_FAX_RECEIPTS, REGVAL_RECEIPTS_PORT, &prv_GVAR.UnattendedData.dwSmtpServerPort, FALSE},
  131. {REG_SZ, RULE_SMTPSERVERAUTHENTICATIONMECHANISM, NULL, NULL, NULL, prv_GVAR.UnattendedData.szSmtpServerAuthenticationMechanism, FALSE},
  132. // user information.
  133. {REG_SZ, RULE_FAXPRINTERNAME, NULL, NULL, NULL, prv_GVAR.UnattendedData.szFaxPrinterName, FALSE},
  134. {REG_DWORD, RULE_FAXPRINTERSHARED, prv_HKLM, REGKEY_FAX_SETUP, REGVAL_IS_SHARED_FAX_PRINTER, &prv_GVAR.UnattendedData.dwIsFaxPrinterShared, FALSE},
  135. // route to printer information.
  136. {REG_DWORD, RULE_ROUTETOPRINTER, NULL, NULL, NULL, &prv_GVAR.UnattendedData.bRouteToPrinter, FALSE},
  137. {REG_BINARY, RULE_ROUTEPRINTERNAME, prv_HKLM, REGKEY_FAX_UNASS_DATA, REGVAL_RM_PRINTING_GUID, prv_GVAR.UnattendedData.szRoutePrinterName, FALSE},
  138. // route to email information.
  139. {REG_DWORD, RULE_ROUTETOEMAIL, NULL, NULL, NULL, &prv_GVAR.UnattendedData.bRouteToEmail, FALSE},
  140. {REG_BINARY, RULE_ROUTETOEMAILRECIPIENT, prv_HKLM, REGKEY_FAX_UNASS_DATA, REGVAL_RM_EMAIL_GUID, prv_GVAR.UnattendedData.szRouteEmailName, FALSE},
  141. // route to a specific directory
  142. {REG_DWORD, RULE_ROUTETOFOLDER, NULL, NULL, NULL, &prv_GVAR.UnattendedData.bRouteToDir, FALSE},
  143. {REG_BINARY, RULE_ROUTEFOLDERNAME, prv_HKLM, REGKEY_FAX_UNASS_DATA, REGVAL_RM_FOLDER_GUID, prv_GVAR.UnattendedData.szRouteDir, FALSE},
  144. // Fax Applications uninstalled during Upgrade
  145. {REG_DWORD, UNINSTALLEDFAX_INFKEY, NULL, NULL, NULL, &prv_GVAR.UnattendedData.dwUninstalledFaxApps, FALSE}
  146. };
  147. #define prv_NUM_UNATTENDED_RULES sizeof(prv_UnattendedRules) / sizeof(prv_UnattendedRules[0])
  148. ///////////////////////// Static Function Prototypes ///////////////////////
  149. static BOOL prv_FindKeyName(const TCHAR *pszID,
  150. prv_UnattendedRule_t **ppUnattendedKey);
  151. static BOOL prv_SaveKeyValue(prv_UnattendedRule_t *pUnattendedKey,
  152. TCHAR *pszValue);
  153. ///////////////////////////////
  154. // fxUnatnd_Init
  155. //
  156. // Initialize the unattended
  157. // subsystem
  158. //
  159. // Params:
  160. // - void.
  161. // Returns:
  162. // - NO_ERROR on success.
  163. // - error code otherwise.
  164. //
  165. DWORD fxUnatnd_Init(void)
  166. {
  167. prv_UnattendedRule_t *pUnattendedKey = NULL;
  168. DWORD dwRes = NO_ERROR;
  169. DBG_ENTER(_T("Init Unattended module"),dwRes);
  170. memset(&prv_GVAR, 0, sizeof(prv_GVAR));
  171. // this is always valid, and defaults to false.
  172. if (prv_FindKeyName(RULE_SUPPRESSCONFIGURATIONWIZARD, &pUnattendedKey))
  173. {
  174. if (!prv_SaveKeyValue(pUnattendedKey,_T("1")))
  175. {
  176. CALL_FAIL (GENERAL_ERR, TEXT("prv_SaveKeyValue"), GetLastError());
  177. pUnattendedKey->bValid = FALSE;
  178. }
  179. }
  180. else
  181. {
  182. CALL_FAIL (GENERAL_ERR, TEXT("prv_FindKeyName RULE_SUPPRESSCONFIGURATIONWIZARD"), GetLastError());
  183. }
  184. return dwRes;
  185. }
  186. ///////////////////////////////
  187. // fxUnatnd_Term
  188. //
  189. // Terminate the unattended subsystem
  190. //
  191. // Params:
  192. // - void.
  193. // Returns:
  194. // - NO_ERROR on success.
  195. // - error code otherwise.
  196. //
  197. DWORD fxUnatnd_Term(void)
  198. {
  199. DWORD dwRes = NO_ERROR;
  200. DBG_ENTER(_T("Term Unattended module"),dwRes);
  201. return dwRes;
  202. }
  203. ///////////////////////////////
  204. // fxUnatnd_LoadUnattendedData
  205. //
  206. // Load the unattended data found
  207. // in the unattended file according
  208. // to the rules table above.
  209. //
  210. // Basically we look in the unattended
  211. // file for the keywords in the rule
  212. // table above, and read them into the
  213. // passed in parameter.
  214. //
  215. // Params:
  216. // Returns:
  217. // - NO_ERROR on success.
  218. // - error code otherwise.
  219. //
  220. DWORD fxUnatnd_LoadUnattendedData()
  221. {
  222. DWORD dwReturn = NO_ERROR;
  223. BOOL bSuccess = TRUE;
  224. HINF hInf = faxocm_GetComponentInf();
  225. HINF hUnattendInf = INVALID_HANDLE_VALUE;
  226. OCMANAGER_ROUTINES *pHelpers = faxocm_GetComponentHelperRoutines();
  227. INFCONTEXT Context;
  228. prv_UnattendedRule_t *pUnattendedKey = NULL;
  229. TCHAR szKeyName[255 + 1];
  230. TCHAR szValue[255 + 1];
  231. TCHAR szUnattendFile[MAX_PATH] = {0};
  232. DBG_ENTER(_T("fxUnatnd_LoadUnattendedData"),dwReturn);
  233. if ((hInf == NULL) || (hInf == INVALID_HANDLE_VALUE) || (pHelpers == NULL))
  234. {
  235. return ERROR_INVALID_PARAMETER;
  236. }
  237. faxocm_GetComponentUnattendFile(szUnattendFile,sizeof(szUnattendFile)/sizeof(szUnattendFile[0]));
  238. hUnattendInf = SetupOpenInfFile (szUnattendFile, NULL, INF_STYLE_WIN4 | INF_STYLE_OLDNT, NULL);
  239. if (hUnattendInf == INVALID_HANDLE_VALUE)
  240. {
  241. VERBOSE(SETUP_ERR,
  242. _T("LoadUnattendData, Unattended ")
  243. _T("mode, but could not get Unattended file INF ")
  244. _T("handle. ec=%d"), GetLastError());
  245. return NO_ERROR;
  246. }
  247. VERBOSE(DBG_MSG, _T("Succeded to open setup unattended mode file."));
  248. if (dwReturn == NO_ERROR)
  249. {
  250. bSuccess = ::SetupFindFirstLine(hUnattendInf,
  251. UNATTEND_FAX_SECTION,
  252. NULL,
  253. &Context);
  254. if (bSuccess)
  255. {
  256. VERBOSE(DBG_MSG,
  257. _T("Found '%s' section in unattended file, ")
  258. _T("beginning unattended file processing"),
  259. UNATTEND_FAX_SECTION);
  260. while (bSuccess)
  261. {
  262. // get the keyname of the first line in the fax section of the
  263. // INF file. (Note index #0 specified in the
  264. // 'SetupGetStringField' API will actually get us the key name.
  265. // Index 1 will be the first value found after the '=' sign.
  266. memset(szKeyName, 0, sizeof(szKeyName));
  267. bSuccess = ::SetupGetStringField(
  268. &Context,
  269. 0,
  270. szKeyName,
  271. sizeof(szKeyName)/sizeof(TCHAR),
  272. NULL);
  273. if (bSuccess)
  274. {
  275. // find the key in our unattended table above.
  276. pUnattendedKey = NULL;
  277. bSuccess = prv_FindKeyName(szKeyName, &pUnattendedKey);
  278. }
  279. if (bSuccess)
  280. {
  281. VERBOSE(DBG_MSG, _T("Found '%s' key in 'Fax' section."), szKeyName);
  282. //
  283. // get the keyname's value. Notice now we get index #1
  284. // which is the first value found after the '=' sign.
  285. //
  286. memset(szValue, 0, sizeof(szValue));
  287. bSuccess = ::SetupGetStringField(
  288. &Context,
  289. 1,
  290. szValue,
  291. sizeof(szValue)/sizeof(TCHAR),
  292. NULL);
  293. VERBOSE(DBG_MSG, _T("The value we read is : %s."), szValue);
  294. }
  295. if (bSuccess)
  296. {
  297. //
  298. // save the keyname's value in the dataptr
  299. //
  300. bSuccess = prv_SaveKeyValue(pUnattendedKey, szValue);
  301. }
  302. // move to the next line in the unattended file fax section.
  303. bSuccess = ::SetupFindNextLine(&Context, &Context);
  304. }
  305. }
  306. else
  307. {
  308. dwReturn = GetLastError();
  309. VERBOSE(DBG_WARNING, _T("::SetupFindFirstLine() failed, ec = %ld"), dwReturn);
  310. }
  311. }
  312. SetupCloseInfFile(hUnattendInf);
  313. return dwReturn;
  314. }
  315. ///////////////////////////////
  316. // fxUnatnd_SaveUnattendedData
  317. //
  318. // Commit the unattended data
  319. // we read from the file to the
  320. // registry.
  321. //
  322. // Params:
  323. // Returns:
  324. // - NO_ERROR on success.
  325. // - error code otherwise.
  326. //
  327. DWORD fxUnatnd_SaveUnattendedData()
  328. {
  329. DWORD dwReturn = NO_ERROR;
  330. DWORD i = 0;
  331. HKEY hKey = NULL;
  332. DWORD dwDataSize = 0;
  333. LRESULT lResult = ERROR_SUCCESS;
  334. prv_UnattendedRule_t *pRule = NULL;
  335. DWORD dwDisposition;
  336. DBG_ENTER(_T("fxUnatnd_SaveUnattendedData"),dwReturn);
  337. // Iterate through each unattended rule.
  338. // If the hKeyTo is not NULL, then write the value of pData to the
  339. // specified registry location.
  340. for (i = 0; i < prv_NUM_UNATTENDED_RULES; i++)
  341. {
  342. pRule = &prv_UnattendedRules[i];
  343. if ((pRule->hKeyTo != NULL) && (pRule->bValid))
  344. {
  345. lResult = ::RegCreateKeyEx(
  346. pRule->hKeyTo, // handle to open key
  347. pRule->pszToRegPath, // subkey name
  348. 0, // reserved
  349. NULL, // class string
  350. REG_OPTION_NON_VOLATILE, // special options
  351. KEY_WRITE, // desired security access
  352. NULL, // inheritance
  353. &hKey, // key handle
  354. &dwDisposition // disposition value buffer
  355. );
  356. if (lResult == ERROR_SUCCESS)
  357. {
  358. dwDataSize = 0;
  359. if (pRule->dwType == REG_SZ ||
  360. pRule->dwType == REG_BINARY) // Binary data must be NULL terminated.
  361. {
  362. dwDataSize = sizeof(TCHAR) * (StringSize((TCHAR*) pRule->pData));
  363. // write the value to the registry.
  364. lResult = ::RegSetValueEx(hKey,
  365. pRule->pszToRegKey,
  366. 0,
  367. pRule->dwType,
  368. (BYTE*) pRule->pData,
  369. dwDataSize);
  370. }
  371. else if (pRule->dwType == REG_DWORD)
  372. {
  373. dwDataSize = sizeof(DWORD);
  374. // write the value to the registry.
  375. lResult = ::RegSetValueEx(hKey,
  376. pRule->pszToRegKey,
  377. 0,
  378. pRule->dwType,
  379. (BYTE*) &(pRule->pData),
  380. dwDataSize);
  381. }
  382. else
  383. {
  384. VERBOSE(SETUP_ERR,
  385. _T("SaveUnattendedData ")
  386. _T("do not recognize data type = '%lu'"),
  387. pRule->dwType);
  388. }
  389. if (ERROR_SUCCESS != lResult)
  390. {
  391. VERBOSE(SETUP_ERR,_T("RegSetValueEx failed (ec=%d). value name :%s"),lResult, pRule->pszToRegKey);
  392. }
  393. }
  394. else
  395. {
  396. VERBOSE(SETUP_ERR,_T("RegCreateKeyEx failed (ec=%d). Key:%s"),lResult, pRule->pszToRegPath);
  397. }
  398. if (hKey)
  399. {
  400. ::RegCloseKey(hKey);
  401. }
  402. }
  403. }
  404. // now save dynamic data...
  405. lResult = SaveSettingsFromAnswerFile();
  406. if (lResult!=ERROR_SUCCESS)
  407. {
  408. VERBOSE(SETUP_ERR,_T("SaveSettingsFromAnswerFile failed (ec=%d)"),GetLastError());
  409. }
  410. //
  411. // Mark which Fax Applications were installed before the upgrade
  412. //
  413. prv_UnattendedRule_t* pUnattendedKey = NULL;
  414. if ((prv_FindKeyName(UNINSTALLEDFAX_INFKEY, &pUnattendedKey)) && (pUnattendedKey->bValid))
  415. {
  416. fxocUpg_WhichFaxWasUninstalled((DWORD)(PtrToUlong(pUnattendedKey->pData)));
  417. }
  418. return dwReturn;
  419. }
  420. TCHAR* fxUnatnd_GetPrinterName()
  421. {
  422. TCHAR* retValue = NULL;
  423. prv_UnattendedRule_t* pUnattendedKey = NULL;
  424. if (prv_FindKeyName(
  425. RULE_FAXPRINTERNAME,
  426. &pUnattendedKey))
  427. {
  428. retValue = (TCHAR *) (pUnattendedKey->pData);
  429. }
  430. return retValue;
  431. }
  432. /*++
  433. Return value:
  434. TRUE - FaxPrinterIsShared was defined in answer file
  435. FALSE - FaxPrinterIsShared was not defined in answer file
  436. --*/
  437. BOOL fxUnatnd_IsPrinterRuleDefined()
  438. {
  439. prv_UnattendedRule_t* pUnattendedKey = NULL;
  440. return (prv_FindKeyName(RULE_FAXPRINTERSHARED,&pUnattendedKey) && (pUnattendedKey->bValid));
  441. }
  442. /*++
  443. Return value:
  444. TRUE - Printer should be shared (because FaxPrinterIsShared was defined
  445. in answer file as true/etc.)
  446. FALSE - Printer should not be shared (because FaxPrinterIsShared was defined in answer
  447. file as false/etc., or because FaxPrinterIsShared was not defined at all)
  448. --*/
  449. BOOL fxUnatnd_GetIsPrinterShared()
  450. {
  451. prv_UnattendedRule_t* pUnattendedKey = NULL;
  452. if (prv_FindKeyName(RULE_FAXPRINTERSHARED,&pUnattendedKey) && (pUnattendedKey->bValid))
  453. {
  454. return (BOOL)PtrToUlong(pUnattendedKey->pData);
  455. }
  456. return FALSE;
  457. }
  458. ///////////////////////////////
  459. // prv_FindKeyName
  460. //
  461. // Find specified key name in our table
  462. //
  463. // Params:
  464. // - pszKeyName - key name to search for.
  465. // - ppUnattendedKey - OUT - rule we found.
  466. // Returns:
  467. // - TRUE if we found the keyname
  468. // - FALSE otherwise.
  469. //
  470. static BOOL prv_FindKeyName(const TCHAR *pszKeyName,
  471. prv_UnattendedRule_t **ppUnattendedKey)
  472. {
  473. BOOL bFound = FALSE;
  474. DWORD i = 0;
  475. if ((pszKeyName == NULL) ||
  476. (ppUnattendedKey == NULL))
  477. {
  478. return FALSE;
  479. }
  480. for (i = 0; (i < prv_NUM_UNATTENDED_RULES) && (!bFound); i++)
  481. {
  482. if (_tcsicmp(pszKeyName, prv_UnattendedRules[i].pszFromInfKeyName) == 0)
  483. {
  484. bFound = TRUE;
  485. *ppUnattendedKey = &prv_UnattendedRules[i];
  486. }
  487. }
  488. return bFound;
  489. }
  490. ///////////////////////////////
  491. // prv_SaveKeyValue
  492. //
  493. // Store the specified value
  494. // with the specified rule
  495. //
  496. // Params:
  497. // - pUnattendedKey - rule where the value will be stored
  498. // - pszValue - value to store.
  499. // Returns:
  500. // - TRUE on success.
  501. // - FALSE otherwise.
  502. //
  503. static BOOL prv_SaveKeyValue(prv_UnattendedRule_t *pUnattendedKey,
  504. TCHAR *pszValue)
  505. {
  506. BOOL bSuccess = TRUE;
  507. //DWORD dwBufferSize = 0;
  508. DBG_ENTER(_T("prv_SaveKeyValue"), bSuccess);
  509. if ((pUnattendedKey == NULL) ||
  510. (pszValue == NULL))
  511. {
  512. return ERROR_INVALID_PARAMETER;
  513. }
  514. if (bSuccess)
  515. {
  516. switch (pUnattendedKey->dwType)
  517. {
  518. case REG_SZ:
  519. case REG_BINARY: // binary data must be NULL terminated.
  520. _tcsncpy((TCHAR*) pUnattendedKey->pData,
  521. pszValue,
  522. _MAX_PATH
  523. );
  524. break;
  525. case REG_DWORD:
  526. // check if we got a true/false, or yes/no.
  527. if ((!_tcsicmp(pszValue, prv_VALID_BOOL_VALUE_YES)) ||
  528. (!_tcsicmp(pszValue, prv_VALID_BOOL_VALUE_TRUE)))
  529. {
  530. pUnattendedKey->pData = (void*) TRUE;
  531. }
  532. else if ((!_tcsicmp(pszValue, prv_VALID_BOOL_VALUE_NO)) ||
  533. (!_tcsicmp(pszValue, prv_VALID_BOOL_VALUE_FALSE)))
  534. {
  535. pUnattendedKey->pData = (void*) FALSE;
  536. }
  537. else
  538. {
  539. // assume the value if an integer.
  540. pUnattendedKey->pData = ULongToPtr(_tcstoul(pszValue, NULL, 10));
  541. }
  542. break;
  543. }
  544. }
  545. pUnattendedKey->bValid = TRUE;
  546. return bSuccess;
  547. }
  548. ///////////////////////////////////////////////////////////////////////////////////////
  549. // Function:
  550. // ConfigureSMTPFromAnswerFile
  551. //
  552. // Purpose: Get all the answers that are applicable for SMTP
  553. // receipts and try to set the server configuration
  554. //
  555. // Params:
  556. // HANDLE hFaxHandle - handle from FaxConnectFaxServer
  557. //
  558. // Return Value:
  559. // Win32 Error code
  560. //
  561. // Author:
  562. // Mooly Beery (MoolyB) 22-Apr-2001
  563. ///////////////////////////////////////////////////////////////////////////////////////
  564. BOOL ConfigureSMTPFromAnswerFile(HANDLE hFaxHandle)
  565. {
  566. BOOL bRet = TRUE;
  567. DWORD dwErr = NO_ERROR;
  568. PFAX_RECEIPTS_CONFIGW pFaxReceiptsConfigW = NULL;
  569. prv_UnattendedRule_t* pUnattendedKey = NULL;
  570. DWORD dwSMTPAuthOption = 0xffffffff;
  571. BOOL bAllowEmail = FALSE;
  572. HKEY hKey = NULL;
  573. DBG_ENTER(_T("ConfigureSMTPFromAnswerFile"),bRet);
  574. // get SmtpServerAuthenticationMechanism
  575. if ((prv_FindKeyName(RULE_SMTPSERVERAUTHENTICATIONMECHANISM,&pUnattendedKey)) && (pUnattendedKey->bValid))
  576. {
  577. if (_tcsicmp((TCHAR*)pUnattendedKey->pData,ANSWER_ANONYMOUS)==0)
  578. {
  579. dwSMTPAuthOption = FAX_SMTP_AUTH_ANONYMOUS;
  580. }
  581. else if (_tcsicmp((TCHAR*)pUnattendedKey->pData,ANSWER_BASIC)==0)
  582. {
  583. dwSMTPAuthOption = FAX_SMTP_AUTH_BASIC;
  584. }
  585. else if (_tcsicmp((TCHAR*)pUnattendedKey->pData,ANSWER_WINDOWSSECURITY)==0)
  586. {
  587. dwSMTPAuthOption = FAX_SMTP_AUTH_NTLM;
  588. }
  589. }
  590. // get SmtpNotificationsEnabled
  591. if ((prv_FindKeyName(RULE_SMTPNOTIFICATIONSENABLED,&pUnattendedKey)) && (pUnattendedKey->bValid))
  592. {
  593. bAllowEmail = TRUE;
  594. }
  595. if (NULL == hFaxHandle)
  596. {
  597. //
  598. // No connection to the fax service.
  599. // The unattended data is stored directly in the registry.
  600. // Just add the data that could not be written in the general section of fxUnatnd_SaveUnattendedData()
  601. // Open the Receipts registry key
  602. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_FAX_RECEIPTS, FALSE, KEY_READ | KEY_WRITE);
  603. if (NULL == hKey)
  604. {
  605. VERBOSE(SETUP_ERR,_T("OpenRegistryKey failed (ec=%d)"),GetLastError());
  606. goto exit;
  607. }
  608. // write the values to the registry
  609. if (0xffffffff != dwSMTPAuthOption)
  610. {
  611. // write the value to the registry.
  612. if (!SetRegistryDword(hKey,
  613. REGVAL_RECEIPTS_SMTP_AUTH_TYPE,
  614. dwSMTPAuthOption))
  615. {
  616. VERBOSE(SETUP_ERR,_T("SetRegistryDword failed (ec=%d)"),GetLastError());
  617. goto exit;
  618. }
  619. }
  620. if (TRUE == bAllowEmail)
  621. {
  622. DWORD dwReceiptType;
  623. //
  624. // Add DRT_EMAIL to the current settings
  625. //
  626. dwErr = GetRegistryDwordEx(hKey,
  627. REGVAL_RECEIPTS_TYPE,
  628. &dwReceiptType);
  629. if (ERROR_SUCCESS != dwErr)
  630. {
  631. VERBOSE(SETUP_ERR,_T("GetRegistryDwordEx failed (ec=%d)"),dwErr);
  632. goto exit;
  633. }
  634. dwReceiptType |= DRT_EMAIL;
  635. // write the value to the registry.
  636. if (!SetRegistryDword(hKey,
  637. REGVAL_RECEIPTS_TYPE,
  638. dwReceiptType))
  639. {
  640. VERBOSE(SETUP_ERR,_T("SetRegistryDword failed (ec=%d)"),dwErr);
  641. goto exit;
  642. }
  643. }
  644. }
  645. else
  646. {
  647. //
  648. // We have a connection to the fax service.
  649. // Use it to configure the server.
  650. //
  651. // call FaxGetReceiptsConfiguration
  652. if (!FaxGetReceiptsConfiguration(hFaxHandle,&pFaxReceiptsConfigW))
  653. {
  654. dwErr = GetLastError();
  655. VERBOSE(SETUP_ERR,_T("FaxGetReceiptsConfigurationW failed (ec=%d)"),dwErr);
  656. goto exit;
  657. }
  658. // get FaxUserName, this is the lptstrSMTPUserName member of PFAX_RECEIPTS_CONFIGW
  659. if ((prv_FindKeyName(RULE_FAXUSERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  660. {
  661. pFaxReceiptsConfigW->lptstrSMTPUserName = (TCHAR*)pUnattendedKey->pData;
  662. }
  663. // get FaxUserPassword, this is the lptstrSMTPPassword member of PFAX_RECEIPTS_CONFIGW
  664. if ((prv_FindKeyName(RULE_FAXUSERPASSWORD,&pUnattendedKey)) && (pUnattendedKey->bValid))
  665. {
  666. pFaxReceiptsConfigW->lptstrSMTPPassword = (TCHAR*)pUnattendedKey->pData;
  667. }
  668. // get SmtpNotificationsEnabled, this is part of dwAllowedReceipts member of PFAX_RECEIPTS_CONFIGW
  669. if (TRUE == bAllowEmail)
  670. {
  671. pFaxReceiptsConfigW->dwAllowedReceipts |= DRT_EMAIL;
  672. }
  673. // get SmtpSenderAddress, this is the lptstrSMTPFrom member of PFAX_RECEIPTS_CONFIGW
  674. if ((prv_FindKeyName(RULE_SMTPSENDERADDRESS,&pUnattendedKey)) && (pUnattendedKey->bValid))
  675. {
  676. pFaxReceiptsConfigW->lptstrSMTPFrom = (TCHAR*)pUnattendedKey->pData;
  677. }
  678. // get SmptServerAddress, this is the lptstrSMTPServer member of PFAX_RECEIPTS_CONFIGW
  679. if ((prv_FindKeyName(RULE_SMTPSERVERADDRESS,&pUnattendedKey)) && (pUnattendedKey->bValid))
  680. {
  681. pFaxReceiptsConfigW->lptstrSMTPServer = (TCHAR*)pUnattendedKey->pData;
  682. }
  683. // get SmtpServerPort, this is the dwSMTPPort member of PFAX_RECEIPTS_CONFIGW
  684. if ((prv_FindKeyName(RULE_SMTPSERVERPORT,&pUnattendedKey)) && (pUnattendedKey->bValid))
  685. {
  686. pFaxReceiptsConfigW->dwSMTPPort = (DWORD)(PtrToUlong(pUnattendedKey->pData));
  687. }
  688. // get SmtpServerAuthenticationMechanism, this is the SMTPAuthOption member of PFAX_RECEIPTS_CONFIGW
  689. if (0xffffffff != dwSMTPAuthOption)
  690. {
  691. pFaxReceiptsConfigW->SMTPAuthOption = (FAX_ENUM_SMTP_AUTH_OPTIONS)dwSMTPAuthOption;
  692. }
  693. // now set the new configuration
  694. if (!FaxSetReceiptsConfiguration(hFaxHandle,pFaxReceiptsConfigW))
  695. {
  696. dwErr = GetLastError();
  697. VERBOSE(SETUP_ERR,_T("FaxSetReceiptsConfigurationW failed (ec=%d)"),dwErr);
  698. goto exit;
  699. }
  700. }
  701. exit:
  702. if (pFaxReceiptsConfigW)
  703. {
  704. FaxFreeBuffer(pFaxReceiptsConfigW);
  705. }
  706. if (hKey)
  707. {
  708. ::RegCloseKey(hKey);
  709. }
  710. return bRet;
  711. }
  712. ///////////////////////////////////////////////////////////////////////////////////////
  713. // Function:
  714. // ConfigureArchivesFromAnswerFile
  715. //
  716. // Purpose: Get all the answers that are applicable for Archives
  717. // and try to set the server configuration
  718. //
  719. // Params:
  720. // HANDLE hFaxHandle - handle from FaxConnectFaxServer
  721. //
  722. // Return Value:
  723. // Win32 Error code
  724. //
  725. // Author:
  726. // Mooly Beery (MoolyB) 22-Apr-2001
  727. ///////////////////////////////////////////////////////////////////////////////////////
  728. BOOL ConfigureArchivesFromAnswerFile(HANDLE hFaxHandle)
  729. {
  730. BOOL bRet = TRUE;
  731. DWORD dwErr = NO_ERROR;
  732. PFAX_ARCHIVE_CONFIGW pFaxInboxArchiveConfigW = NULL;
  733. PFAX_ARCHIVE_CONFIGW pFaxSentItemsArchiveConfigW = NULL;
  734. prv_UnattendedRule_t* pUnattendedKey = NULL;
  735. DBG_ENTER(_T("ConfigureArchivesFromAnswerFile"),bRet);
  736. if (NULL == hFaxHandle)
  737. {
  738. return bRet; // All data is conifigured directly to the registry.
  739. }
  740. // call FaxGetArchiveConfiguration to get the inbox configuration
  741. if (FaxGetArchiveConfiguration(hFaxHandle,FAX_MESSAGE_FOLDER_INBOX,&pFaxInboxArchiveConfigW))
  742. {
  743. // Inbox enable
  744. if ((prv_FindKeyName(RULE_ARCHIVEINCOMING,&pUnattendedKey)) && (pUnattendedKey->bValid))
  745. {
  746. pFaxInboxArchiveConfigW->bUseArchive= (BOOL)PtrToUlong(pUnattendedKey->pData);
  747. }
  748. // Inbox folder
  749. if ((prv_FindKeyName(RULE_ARCHIVEINCOMINGFOLDERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  750. {
  751. pFaxInboxArchiveConfigW->lpcstrFolder= (TCHAR*)(pUnattendedKey->pData);
  752. }
  753. // now set the new configuration
  754. if (FaxSetArchiveConfiguration(hFaxHandle,FAX_MESSAGE_FOLDER_INBOX,pFaxInboxArchiveConfigW))
  755. {
  756. dwErr = GetLastError();
  757. VERBOSE(DBG_WARNING,_T("FaxSetArchiveConfigurationW FAX_MESSAGE_FOLDER_INBOX failed (ec=%d)"),dwErr);
  758. }
  759. }
  760. else
  761. {
  762. dwErr = GetLastError();
  763. VERBOSE(DBG_WARNING,_T("FaxGetArchiveConfigurationW FAX_MESSAGE_FOLDER_INBOX failed (ec=%d)"),dwErr);
  764. }
  765. // call FaxGetArchiveConfiguration to get the SentItems configuration
  766. if (FaxGetArchiveConfiguration(hFaxHandle,FAX_MESSAGE_FOLDER_SENTITEMS,&pFaxSentItemsArchiveConfigW))
  767. {
  768. // SentItems enable
  769. if ((prv_FindKeyName(RULE_ARCHIVEOUTGOING,&pUnattendedKey)) && (pUnattendedKey->bValid))
  770. {
  771. pFaxSentItemsArchiveConfigW->bUseArchive= (BOOL)PtrToUlong(pUnattendedKey->pData);
  772. }
  773. // SentItems folder
  774. if ((prv_FindKeyName(RULE_ARCHIVEFOLDERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  775. {
  776. pFaxSentItemsArchiveConfigW->lpcstrFolder= (TCHAR*)(pUnattendedKey->pData);
  777. }
  778. // SentItems folder could also come from this rule
  779. if ((prv_FindKeyName(RULE_ARCHIVEOUTGOINGFOLDERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  780. {
  781. pFaxSentItemsArchiveConfigW->lpcstrFolder= (TCHAR*)(pUnattendedKey->pData);
  782. }
  783. // now set the new configuration
  784. if (FaxSetArchiveConfiguration(hFaxHandle,FAX_MESSAGE_FOLDER_SENTITEMS,pFaxSentItemsArchiveConfigW))
  785. {
  786. dwErr = GetLastError();
  787. VERBOSE(DBG_WARNING,_T("FaxSetArchiveConfigurationW FAX_MESSAGE_FOLDER_INBOX failed (ec=%d)"),dwErr);
  788. }
  789. }
  790. else
  791. {
  792. dwErr = GetLastError();
  793. VERBOSE(DBG_WARNING,_T("FaxGetArchiveConfigurationW FAX_MESSAGE_FOLDER_INBOX failed (ec=%d)"),dwErr);
  794. }
  795. if (pFaxInboxArchiveConfigW)
  796. {
  797. FaxFreeBuffer(pFaxInboxArchiveConfigW);
  798. }
  799. if (pFaxSentItemsArchiveConfigW)
  800. {
  801. FaxFreeBuffer(pFaxSentItemsArchiveConfigW);
  802. }
  803. return bRet;
  804. }
  805. ///////////////////////////////////////////////////////////////////////////////////////
  806. // Function:
  807. // SetPerDeviceConfigFromAnswerFile
  808. //
  809. // Purpose: Get all the answers that are applicable for device
  810. // settings and routing extension settings
  811. // and set all the existing devices.
  812. //
  813. // Params:
  814. // HANDLE hFaxHandle - handle from FaxConnectFaxServer
  815. //
  816. // Return Value:
  817. // Win32 Error code
  818. //
  819. // Author:
  820. // Mooly Beery (MoolyB) 12-mar-2001
  821. ///////////////////////////////////////////////////////////////////////////////////////
  822. static DWORD SetPerDeviceConfigFromAnswerFile(HANDLE hFaxHandle)
  823. {
  824. DWORD dwErr = ERROR_SUCCESS;
  825. PFAX_PORT_INFO_EXW pFaxPortInfoExW = NULL;
  826. DWORD dwNumPorts = 0;
  827. DWORD dwIndex = 0;
  828. DWORD dwFlags = 0;
  829. prv_UnattendedRule_t* pUnattendedKey = NULL;
  830. HKEY hKey = NULL;
  831. DBG_ENTER(_T("SetPerDeviceConfigFromAnswerFile"),dwErr);
  832. // handle Route to Folder, printer and Email- enable
  833. if ((prv_FindKeyName(RULE_ROUTETOPRINTER,&pUnattendedKey)) && (pUnattendedKey->bValid))
  834. {
  835. dwFlags |= ((BOOL)PtrToUlong(pUnattendedKey->pData)) ? LR_PRINT : 0;
  836. }
  837. if ((prv_FindKeyName(RULE_ROUTETOFOLDER,&pUnattendedKey)) && (pUnattendedKey->bValid))
  838. {
  839. dwFlags |= ((BOOL) PtrToUlong(pUnattendedKey->pData)) ? LR_STORE : 0;
  840. }
  841. if (!IsDesktopSKU())
  842. {
  843. if ((prv_FindKeyName(RULE_ROUTETOEMAIL,&pUnattendedKey)) && (pUnattendedKey->bValid))
  844. {
  845. dwFlags |= ((BOOL) PtrToUlong(pUnattendedKey->pData)) ? LR_EMAIL : 0;
  846. }
  847. }
  848. if (NULL == hFaxHandle)
  849. {
  850. //
  851. // No connection to the fax service.
  852. // The unattended data is stored directly in the registry.
  853. // Just add the data that could not be written in the general section of fxUnatnd_SaveUnattendedData()
  854. // Open the Receipts registry key
  855. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_FAX_UNASS_DATA, FALSE, KEY_WRITE);
  856. if (NULL == hKey)
  857. {
  858. VERBOSE(SETUP_ERR,_T("OpenRegistryKey failed (ec=%d)"),GetLastError());
  859. goto exit;
  860. }
  861. // write the values to the registry
  862. if (0 != dwFlags)
  863. {
  864. // write the value to the registry.
  865. if (!SetRegistryBinary(hKey,
  866. REGVAL_RM_FLAGS_GUID,
  867. (BYTE*)&dwFlags,
  868. sizeof(dwFlags)))
  869. {
  870. VERBOSE(SETUP_ERR,_T("SetRegistryBinary failed (ec=%d)"),GetLastError());
  871. goto exit;
  872. }
  873. }
  874. }
  875. else
  876. {
  877. // call EnumPortsEx
  878. if (!FaxEnumPortsEx(hFaxHandle,&pFaxPortInfoExW,&dwNumPorts))
  879. {
  880. dwErr = GetLastError();
  881. VERBOSE(SETUP_ERR,_T("FaxEnumPortsEx failed (ec=%d)"),dwErr);
  882. goto exit;
  883. }
  884. for (dwIndex=0; dwIndex<dwNumPorts; dwIndex++)
  885. {
  886. // handle CSID
  887. if ((prv_FindKeyName(RULE_CSID,&pUnattendedKey)) && (pUnattendedKey->bValid))
  888. {
  889. pFaxPortInfoExW[dwIndex].lptstrCsid = (TCHAR*)pUnattendedKey->pData;
  890. }
  891. // handle TSID
  892. if ((prv_FindKeyName(RULE_TSID,&pUnattendedKey)) && (pUnattendedKey->bValid))
  893. {
  894. pFaxPortInfoExW[dwIndex].lptstrTsid = (TCHAR*)pUnattendedKey->pData;
  895. }
  896. // handle Rings
  897. if ((prv_FindKeyName(RULE_RINGS,&pUnattendedKey)) && (pUnattendedKey->bValid))
  898. {
  899. pFaxPortInfoExW[dwIndex].dwRings = (DWORD)(PtrToUlong(pUnattendedKey->pData));
  900. }
  901. // handle Flags
  902. if ((prv_FindKeyName(RULE_SENDFAXES,&pUnattendedKey)) && (pUnattendedKey->bValid))
  903. {
  904. pFaxPortInfoExW[dwIndex].bSend = ((BOOL)PtrToUlong(pUnattendedKey->pData));
  905. }
  906. if ((prv_FindKeyName(RULE_RECEIVEFAXES,&pUnattendedKey)) && (pUnattendedKey->bValid))
  907. {
  908. pFaxPortInfoExW[dwIndex].ReceiveMode = ((BOOL)PtrToUlong(pUnattendedKey->pData)) ? FAX_DEVICE_RECEIVE_MODE_AUTO : FAX_DEVICE_RECEIVE_MODE_OFF;
  909. }
  910. // Set CSID, TSID and Rings
  911. if(!FaxSetPortEx(hFaxHandle, pFaxPortInfoExW[dwIndex].dwDeviceID, &pFaxPortInfoExW[dwIndex]))
  912. {
  913. dwErr = GetLastError();
  914. VERBOSE(SETUP_ERR,_T("Can't save fax port data. Error code is %d."),dwErr);
  915. // nothing to worry about, let's try some other answers...
  916. dwErr = ERROR_SUCCESS;
  917. }
  918. // handle Route to Folder - folder name
  919. if ((prv_FindKeyName(RULE_ROUTEFOLDERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  920. {
  921. if(!FaxSetExtensionData(hFaxHandle,
  922. pFaxPortInfoExW[dwIndex].dwDeviceID,
  923. REGVAL_RM_FOLDER_GUID,
  924. (LPBYTE)pUnattendedKey->pData,
  925. StringSize((TCHAR*)(pUnattendedKey->pData))) )
  926. {
  927. dwErr = GetLastError();
  928. VERBOSE(SETUP_ERR,
  929. _T("FaxSetExtensionData failed: Device Id=%d, routing GUID=%s, error=%d."),
  930. pFaxPortInfoExW[dwIndex].dwDeviceID,
  931. REGVAL_RM_FOLDER_GUID,
  932. dwErr);
  933. // nothing to worry about, let's try some other answers...
  934. dwErr = ERROR_SUCCESS;
  935. }
  936. }
  937. // handle Route to Printer - printer name
  938. if ((prv_FindKeyName(RULE_ROUTEPRINTERNAME,&pUnattendedKey)) && (pUnattendedKey->bValid))
  939. {
  940. if(!FaxSetExtensionData(hFaxHandle,
  941. pFaxPortInfoExW[dwIndex].dwDeviceID,
  942. REGVAL_RM_PRINTING_GUID,
  943. (LPBYTE)pUnattendedKey->pData,
  944. StringSize((TCHAR*)(pUnattendedKey->pData))) )
  945. {
  946. dwErr = GetLastError();
  947. VERBOSE(SETUP_ERR,
  948. _T("FaxSetExtensionData failed: Device Id=%d, routing GUID=%s, error=%d."),
  949. pFaxPortInfoExW[dwIndex].dwDeviceID,
  950. REGVAL_RM_FOLDER_GUID,
  951. dwErr);
  952. // nothing to worry about, let's try some other answers...
  953. dwErr = ERROR_SUCCESS;
  954. }
  955. }
  956. if (!IsDesktopSKU())
  957. {
  958. // handle Route to Email - email name
  959. if ((prv_FindKeyName(RULE_ROUTETOEMAILRECIPIENT,&pUnattendedKey)) && (pUnattendedKey->bValid))
  960. {
  961. if(!FaxSetExtensionData(hFaxHandle,
  962. pFaxPortInfoExW[dwIndex].dwDeviceID,
  963. REGVAL_RM_EMAIL_GUID,
  964. (LPBYTE)pUnattendedKey->pData,
  965. StringSize((TCHAR*)(pUnattendedKey->pData))) )
  966. {
  967. dwErr = GetLastError();
  968. VERBOSE(SETUP_ERR,
  969. _T("FaxSetExtensionData failed: Device Id=%d, routing GUID=%s, error=%d."),
  970. pFaxPortInfoExW[dwIndex].dwDeviceID,
  971. REGVAL_RM_EMAIL_GUID,
  972. dwErr);
  973. // nothing to worry about, let's try some other answers...
  974. dwErr = ERROR_SUCCESS;
  975. }
  976. }
  977. }
  978. // handle Route to Folder, printer and Email- enable
  979. if(!FaxSetExtensionData(hFaxHandle,
  980. pFaxPortInfoExW[dwIndex].dwDeviceID,
  981. REGVAL_RM_FLAGS_GUID,
  982. (LPBYTE)&dwFlags,
  983. sizeof(DWORD)) )
  984. {
  985. dwErr = GetLastError();
  986. VERBOSE(SETUP_ERR,
  987. _T("FaxSetExtensionData failed: Device Id=%d, routing GUID=%s, error=%d."),
  988. pFaxPortInfoExW[dwIndex].dwDeviceID,
  989. REGVAL_RM_FOLDER_GUID,
  990. dwErr);
  991. // nothing to worry about, let's try some other answers...
  992. dwErr = ERROR_SUCCESS;
  993. }
  994. }
  995. }
  996. exit:
  997. if (pFaxPortInfoExW)
  998. {
  999. FaxFreeBuffer(pFaxPortInfoExW);
  1000. }
  1001. if(hKey)
  1002. {
  1003. ::RegCloseKey (hKey);
  1004. }
  1005. return dwErr;
  1006. }
  1007. ///////////////////////////////////////////////////////////////////////////////////////
  1008. // Function:
  1009. // SaveSettingsFromAnswerFile
  1010. //
  1011. // Purpose: Get all the answers that are applicable for device
  1012. // settings and routing extension settings
  1013. // and set all the existing devices.
  1014. //
  1015. // Params:
  1016. // None
  1017. //
  1018. // Return Value:
  1019. // Win32 Error code
  1020. //
  1021. // Author:
  1022. // Mooly Beery (MoolyB) 12-mar-2001
  1023. ///////////////////////////////////////////////////////////////////////////////////////
  1024. static DWORD SaveSettingsFromAnswerFile()
  1025. {
  1026. DWORD dwErr = ERROR_SUCCESS;
  1027. HANDLE hFaxHandle = NULL;
  1028. prv_UnattendedRule_t* pUnattendedKey = NULL;
  1029. DBG_ENTER(_T("SaveSettingsFromAnswerFile"),dwErr);
  1030. if (fxState_IsStandAlone())
  1031. {
  1032. //
  1033. // This is a stand alone installation. Connect to the fax service and use it to configure the dynamic data.
  1034. //
  1035. if (!FaxConnectFaxServer(NULL,&hFaxHandle))
  1036. {
  1037. dwErr = GetLastError();
  1038. VERBOSE(SETUP_ERR,_T("FaxConnectFaxServer failed (ec=%d)"),dwErr);
  1039. goto exit;
  1040. }
  1041. }
  1042. else
  1043. {
  1044. //
  1045. // We are in GUI mode setup, and we should not start the service as not all system resources are available.
  1046. // Use the registry to configure the fax service.
  1047. // The fax service will read the data when it is first started after reboot (at the end of GUI mode).
  1048. //
  1049. }
  1050. // set the SMTP server configuration, on Server SKUs only
  1051. if (!IsDesktopSKU())
  1052. {
  1053. if (!ConfigureSMTPFromAnswerFile(hFaxHandle))
  1054. {
  1055. dwErr = GetLastError();
  1056. VERBOSE(DBG_WARNING,_T("ConfigureSMTPFromAnswerFile failed (ec=%d)"),dwErr);
  1057. // this is not fatal, continue...
  1058. }
  1059. }
  1060. if (!ConfigureArchivesFromAnswerFile(hFaxHandle))
  1061. {
  1062. dwErr = GetLastError();
  1063. VERBOSE(DBG_WARNING,_T("ConfigureArchivesFromAnswerFile failed (ec=%d)"),dwErr);
  1064. // this is not fatal, continue...
  1065. }
  1066. if (SetPerDeviceConfigFromAnswerFile(hFaxHandle)!=NO_ERROR)
  1067. {
  1068. dwErr = GetLastError();
  1069. VERBOSE(DBG_WARNING,_T("SetPerDeviceConfigFromAnswerFile failed (ec=%d)"),dwErr);
  1070. // this is not fatal, continue...
  1071. }
  1072. // finally set HKLM... Fax\Setup\Original Setup Data REG_DWORD Flags to configure any future device.
  1073. HKEY hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,REGKEY_FAX_SETUP_ORIG,FALSE,KEY_WRITE);
  1074. if (hKey)
  1075. {
  1076. BOOL bFound = FALSE;
  1077. DWORD dwFlags = 0;
  1078. if ((prv_FindKeyName(RULE_SENDFAXES,&pUnattendedKey)) && (pUnattendedKey->bValid))
  1079. {
  1080. dwFlags |= ((BOOL)PtrToUlong(pUnattendedKey->pData)) ? FPF_SEND : 0;
  1081. bFound = TRUE;
  1082. }
  1083. if ((prv_FindKeyName(RULE_RECEIVEFAXES,&pUnattendedKey)) && (pUnattendedKey->bValid))
  1084. {
  1085. dwFlags |= ((BOOL)PtrToUlong(pUnattendedKey->pData)) ? FPF_RECEIVE : 0;
  1086. bFound = TRUE;
  1087. }
  1088. if (bFound)
  1089. {
  1090. if (!SetRegistryDword(hKey,REGVAL_FLAGS,dwFlags))
  1091. {
  1092. CALL_FAIL (GENERAL_ERR, TEXT("SetRegistryDword(REGVAL_FLAGS)"), GetLastError());
  1093. }
  1094. }
  1095. RegCloseKey(hKey);
  1096. }
  1097. else
  1098. {
  1099. CALL_FAIL(SETUP_ERR,TEXT("OpenRegistryKey"),GetLastError());
  1100. }
  1101. exit:
  1102. if (hFaxHandle)
  1103. {
  1104. FaxClose(hFaxHandle);
  1105. }
  1106. return dwErr;
  1107. }