Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

553 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. faxocm.cpp
  5. Abstract:
  6. This file implements the setup wizard code for the
  7. FAX server setup.
  8. Environment:
  9. WIN32 User Mode
  10. Author:
  11. Wesley Witt (wesw) 10-Sept-1997
  12. --*/
  13. #include "faxocm.h"
  14. #pragma hdrstop
  15. HINSTANCE hInstance;
  16. SETUP_INIT_COMPONENT SetupInitComponent;
  17. BOOL Unattended;
  18. BOOL Upgrade; // NT upgrade
  19. BOOL Win9xUpgrade;
  20. BOOL NtGuiMode;
  21. BOOL NtWorkstation;
  22. BOOL UnInstall;
  23. BOOL RemoteAdminSetup;
  24. BOOL RebootRequired;
  25. BOOL SuppressReboot;
  26. WORD EnumPlatforms[4];
  27. BOOL PointPrintSetup;
  28. DWORD InstallThreadError;
  29. BOOL OkToCancel;
  30. DWORD CurrentCountryId;
  31. LPWSTR CurrentAreaCode;
  32. WCHAR ClientSetupServerName[MAX_PATH];
  33. WCHAR ThisPlatformName[MAX_PATH];
  34. DWORD InstalledPlatforms;
  35. DWORD InstallType;
  36. DWORD Installed;
  37. BOOL ComponentInitialized;
  38. WIZ_DATA WizData;
  39. LPWSTR SourcePath;
  40. PLATFORM_INFO Platforms[] =
  41. {
  42. { L"Windows NT x86", L"i386", 0, FAX_INSTALLED_PLATFORM_X86, NULL, FALSE },
  43. { L"Windows NT Alpha_AXP", L"alpha", 0, FAX_INSTALLED_PLATFORM_ALPHA, NULL, FALSE },
  44. };
  45. DWORD CountPlatforms = (sizeof(Platforms)/sizeof(PLATFORM_INFO));
  46. UNATTEND_ANSWER UnattendAnswer[] =
  47. {
  48. { L"FaxPrinterName", DT_STRING, 0, WizData.PrinterName },
  49. { L"FaxNumber", DT_STRING, 0, WizData.PhoneNumber },
  50. { L"RoutePrinterName", DT_STRING, 0, WizData.RoutePrinterName },
  51. { L"RouteProfileName", DT_STRING, 0, WizData.RouteProfile },
  52. { L"RouteFolderName", DT_STRING, 0, WizData.RouteDir },
  53. { L"Csid", DT_STRING, 0, WizData.Csid },
  54. { L"Tsid", DT_STRING, 0, WizData.Tsid },
  55. { L"Rings", DT_LONGINT, 0, &WizData.Rings },
  56. { L"RouteToPrinter", DT_BOOLEAN, LR_PRINT, &WizData.RoutingMask },
  57. { L"RouteToInbox", DT_BOOLEAN, LR_INBOX, &WizData.RoutingMask },
  58. { L"RouteToFolder", DT_BOOLEAN, LR_STORE, &WizData.RoutingMask },
  59. { L"ArchiveOutgoing", DT_BOOLEAN, 0, &WizData.ArchiveOutgoing },
  60. { L"ArchiveFolderName", DT_STRING, 0, WizData.ArchiveDir }
  61. };
  62. #define CountUnattendAnswers (sizeof(UnattendAnswer)/sizeof(UNATTEND_ANSWER))
  63. extern "C" INT FaxDebugLevel;
  64. extern "C"
  65. DWORD
  66. FaxOcmDllInit(
  67. HINSTANCE hInst,
  68. DWORD Reason,
  69. LPVOID Context
  70. )
  71. /*++
  72. Routine Description:
  73. DLL initialization function.
  74. Arguments:
  75. hInstance - Instance handle
  76. Reason - Reason for the entrypoint being called
  77. Context - Context record
  78. Return Value:
  79. TRUE - Initialization succeeded
  80. FALSE - Initialization failed
  81. --*/
  82. {
  83. WCHAR DllName[MAX_PATH];
  84. if (Reason == DLL_PROCESS_ATTACH) {
  85. hInstance = hInst;
  86. DisableThreadLibraryCalls( hInstance );
  87. HeapInitialize( NULL, NULL, NULL, 0 );
  88. if (!GetModuleFileName(hInstance, DllName, MAX_PATH) || !LoadLibrary(DllName)) {
  89. return FALSE;
  90. }
  91. DebugPrint(( TEXT("faxocm loaded") ));
  92. }
  93. if (Reason == DLL_PROCESS_DETACH) {
  94. HeapCleanup();
  95. }
  96. return TRUE;
  97. }
  98. VOID
  99. SetProgress(
  100. DWORD StatusString
  101. )
  102. {
  103. #ifdef NT5FAXINSTALL
  104. return;
  105. #else
  106. SetupInitComponent.HelperRoutines.SetProgressText(
  107. SetupInitComponent.HelperRoutines.OcManagerContext,
  108. GetString( StatusString )
  109. );
  110. for (DWORD i=0; i<10; i++) {
  111. SetupInitComponent.HelperRoutines.TickGauge(
  112. SetupInitComponent.HelperRoutines.OcManagerContext
  113. );
  114. }
  115. #endif
  116. }
  117. BOOL
  118. SetWizData(
  119. VOID
  120. )
  121. {
  122. HKEY hKey;
  123. LPWSTR RegisteredOwner = NULL;
  124. INFCONTEXT InfLine;
  125. WCHAR Id[128];
  126. WCHAR Value[128];
  127. DWORD i;
  128. HINF hInf;
  129. //
  130. // user name
  131. //
  132. hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_WINDOWSNT_CURRVER, TRUE, KEY_ALL_ACCESS );
  133. RegisteredOwner = GetRegistryString( hKey, REGVAL_REGISTERED_OWNER, EMPTY_STRING );
  134. RegCloseKey( hKey );
  135. if (RegisteredOwner && RegisteredOwner[0]) {
  136. wcscpy( WizData.UserName, RegisteredOwner );
  137. MemFree( RegisteredOwner );
  138. }
  139. //
  140. // fax printer name
  141. //
  142. wcscpy( WizData.PrinterName, GetString( IDS_DEFAULT_PRINTER_NAME ) );
  143. //
  144. // csid
  145. //
  146. wcscpy( WizData.Csid, GetString( IDS_DEFAULT_CSID ) );
  147. //
  148. // tsid
  149. //
  150. wcscpy( WizData.Tsid, GetString( IDS_DEFAULT_TSID ) );
  151. //
  152. // ring count
  153. //
  154. WizData.Rings = 2;
  155. //
  156. // routing mask
  157. //
  158. WizData.RoutingMask = LR_STORE;
  159. WizData.ArchiveOutgoing = TRUE;
  160. //
  161. // routing dir name
  162. //
  163. if (MyGetSpecialPath( CSIDL_COMMON_DOCUMENTS, WizData.RouteDir)) {
  164. ConcatenatePaths( WizData.RouteDir, GetString(IDS_RECEIVE_DIR) );
  165. }
  166. //
  167. // archive dir name
  168. //
  169. if (MyGetSpecialPath( CSIDL_COMMON_DOCUMENTS, WizData.ArchiveDir)) {
  170. ConcatenatePaths( WizData.ArchiveDir, GetString(IDS_ARCHIVE_DIR) );
  171. }
  172. //
  173. // process any unattend data
  174. //
  175. if (Unattended) {
  176. hInf = SetupInitComponent.HelperRoutines.GetInfHandle(
  177. INFINDEX_UNATTENDED,
  178. SetupInitComponent.HelperRoutines.OcManagerContext
  179. );
  180. if (hInf == INVALID_HANDLE_VALUE) {
  181. return FALSE;
  182. }
  183. if (SetupFindFirstLine( hInf, L"Fax", NULL, &InfLine )) {
  184. DebugPrint((L"Processing fax unattend data"));
  185. do {
  186. SetupGetStringField( &InfLine, 0, Id, sizeof(Id)/sizeof(WCHAR), NULL );
  187. for (i=0; i<CountUnattendAnswers; i++) {
  188. if (_wcsicmp( Id, UnattendAnswer[i].KeyName ) == 0) {
  189. if ((SetupGetStringField(
  190. &InfLine,
  191. 1,
  192. Value,
  193. sizeof(Value)/sizeof(WCHAR),
  194. NULL )) &&
  195. *Value) {
  196. switch (UnattendAnswer[i].DataType) {
  197. case DT_STRING:
  198. wcscpy( (LPWSTR)UnattendAnswer[i].DataPtr, Value );
  199. break;
  200. case DT_LONGINT:
  201. *((LPDWORD)UnattendAnswer[i].DataPtr) = wcstoul( Value, NULL, 0 );
  202. break;
  203. case DT_BOOLEAN:
  204. if (UnattendAnswer[i].UseMaskOnBool) {
  205. if (_wcsicmp( Value, L"yes" ) == 0 || _wcsicmp( Value, L"true" ) == 0) {
  206. *((LPDWORD)UnattendAnswer[i].DataPtr) |= UnattendAnswer[i].UseMaskOnBool;
  207. }
  208. } else {
  209. if (_wcsicmp( Value, L"yes" ) == 0 || _wcsicmp( Value, L"true" ) == 0) {
  210. *((LPDWORD)UnattendAnswer[i].DataPtr) = TRUE;
  211. } else {
  212. *((LPDWORD)UnattendAnswer[i].DataPtr) = FALSE;
  213. }
  214. }
  215. break;
  216. default:
  217. break;
  218. }
  219. }
  220. }
  221. }
  222. } while(SetupFindNextLine( &InfLine, &InfLine ));
  223. }
  224. }
  225. return TRUE;
  226. }
  227. BOOL
  228. IsGoodComponent(
  229. IN LPWSTR ComponentId,
  230. IN LPWSTR SubcomponentId,
  231. IN LPWSTR TargetId
  232. )
  233. {
  234. if (ComponentId == NULL || SubcomponentId == NULL) {
  235. return FALSE;
  236. }
  237. if (_wcsicmp( ComponentId, TargetId ) == 0 && _wcsicmp( SubcomponentId, TargetId ) == 0) {
  238. return TRUE;
  239. }
  240. return FALSE;
  241. }
  242. DWORD
  243. FaxOcmSetupProc(
  244. IN LPWSTR ComponentId,
  245. IN LPWSTR SubcomponentId,
  246. IN UINT Function,
  247. IN UINT Param1,
  248. IN OUT PVOID Param2
  249. )
  250. {
  251. DebugPrint(( TEXT("FaxOcmSetup proc called with function 0x%08x"), Function ));
  252. switch( Function ) {
  253. case OC_PREINITIALIZE:
  254. return OCFLAG_UNICODE;
  255. case OC_SET_LANGUAGE:
  256. return TRUE;
  257. case OC_INIT_COMPONENT:
  258. if (OCMANAGER_VERSION <= ((PSETUP_INIT_COMPONENT)Param2)->OCManagerVersion) {
  259. ((PSETUP_INIT_COMPONENT)Param2)->ComponentVersion = OCMANAGER_VERSION;
  260. } else {
  261. return ERROR_CALL_NOT_IMPLEMENTED;
  262. }
  263. if (SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE) {
  264. return 0;
  265. }
  266. //
  267. // eventhough this call happens once for each component that this
  268. // dll installs, we really only need to do our thing once. this is
  269. // because the data that ocm passes is really the same for all calls.
  270. //
  271. if (!ComponentInitialized) {
  272. CopyMemory( &SetupInitComponent, (LPVOID)Param2, sizeof(SETUP_INIT_COMPONENT) );
  273. Unattended = (SetupInitComponent.SetupData.OperationFlags & SETUPOP_BATCH) > 0;
  274. Upgrade = (SetupInitComponent.SetupData.OperationFlags & SETUPOP_NTUPGRADE) > 0;
  275. Win9xUpgrade = (SetupInitComponent.SetupData.OperationFlags & SETUPOP_WIN95UPGRADE) > 0;
  276. NtGuiMode = (SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE) == 0;
  277. NtWorkstation = SetupInitComponent.SetupData.ProductType == PRODUCT_WORKSTATION;
  278. SourcePath = (LPWSTR) MemAlloc( StringSize(SetupInitComponent.SetupData.SourcePath) + MAX_PATH );
  279. if (!SourcePath) {
  280. return ERROR_NOT_ENOUGH_MEMORY;
  281. }
  282. wcscpy( SourcePath, SetupInitComponent.SetupData.SourcePath );
  283. if (SourcePath[wcslen(SourcePath)-1] != L'\\') {
  284. wcscat( SourcePath, L"\\" );
  285. }
  286. if (NtGuiMode) {
  287. #ifdef _X86_
  288. wcscat( SourcePath, L"i386" );
  289. #endif
  290. #ifdef _ALPHA_
  291. wcscat( SourcePath, L"alpha" );
  292. #endif
  293. } else {
  294. SourcePath = VerifyInstallPath(SourcePath);
  295. DebugPrint(( TEXT("faxocm Sourcepath = %s\n"),SourcePath));
  296. }
  297. DebugPrint((L"faxocm - SourcePath = %s", SourcePath));
  298. if (NtGuiMode) {
  299. Unattended = TRUE;
  300. }
  301. //
  302. // make sure our inf file is opened by sysoc correctly
  303. // if it isn't then try to open it ourself
  304. //
  305. if (SetupInitComponent.ComponentInfHandle == NULL) {
  306. WCHAR InfPath[MAX_PATH];
  307. LPWSTR p;
  308. GetModuleFileName( hInstance, InfPath, sizeof(InfPath)/sizeof(WCHAR) );
  309. p = wcsrchr( InfPath, L'\\' );
  310. if (p) {
  311. wcscpy( p+1, L"faxsetup.inf" );
  312. SetupInitComponent.ComponentInfHandle = SetupOpenInfFile( InfPath, NULL, INF_STYLE_WIN4, NULL );
  313. if (SetupInitComponent.ComponentInfHandle == INVALID_HANDLE_VALUE) {
  314. return ERROR_FILE_NOT_FOUND;
  315. }
  316. } else {
  317. return ERROR_FILE_NOT_FOUND;
  318. }
  319. }
  320. SetupOpenAppendInfFile( NULL, SetupInitComponent.ComponentInfHandle, NULL );
  321. InitializeStringTable();
  322. //
  323. // do minimal mapi initialization for NtGuiMode setup
  324. //
  325. MyInitializeMapi(NtGuiMode);
  326. GetInstallationInfo( &Installed, &InstallType, &InstalledPlatforms );
  327. if (NtGuiMode && (IsNt4or351Upgrade() || Win9xUpgrade)) {
  328. //
  329. // in this case, we should treat this as a fresh install of fax
  330. //
  331. Upgrade = FALSE;
  332. }
  333. if (!NtGuiMode) {
  334. Upgrade = Installed;
  335. }
  336. EnumPlatforms[PROCESSOR_ARCHITECTURE_INTEL] = 0;
  337. EnumPlatforms[PROCESSOR_ARCHITECTURE_ALPHA] = 1;
  338. ComponentInitialized = TRUE;
  339. SYSTEM_INFO si;
  340. GetSystemInfo( &si );
  341. if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
  342. SetEnvironmentVariable( L"platform", L"i386" );
  343. } else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) {
  344. SetEnvironmentVariable( L"platform", L"alpha" );
  345. }
  346. SetWizData();
  347. }
  348. return 0;
  349. case OC_QUERY_CHANGE_SEL_STATE:
  350. if (NtGuiMode || (!Installed) || UnInstall) {
  351. return 0;
  352. }
  353. UnInstall = Param1 == 0;
  354. return 1;
  355. case OC_REQUEST_PAGES:
  356. {
  357. PSETUP_REQUEST_PAGES SetupRequestPages = (PSETUP_REQUEST_PAGES) Param2;
  358. if (NtGuiMode) {
  359. //
  360. // never return pages during gui-mode setup
  361. //
  362. return 0;
  363. }
  364. if (_wcsicmp( ComponentId, COMPONENT_FAX ) != 0) {
  365. return 0;
  366. }
  367. if (Param1 == WizPagesWelcome) {
  368. #ifdef NT5FAXINSTALL
  369. return 0;
  370. #else
  371. SetupRequestPages->Pages[0] = GetWelcomeWizardPage();
  372. return 1;
  373. #endif
  374. }
  375. if (Param1 == WizPagesMode) {
  376. #ifdef NT5FAXINSTALL
  377. return 0;
  378. #else
  379. SetupRequestPages->Pages[0] = GetEulaWizardPage();
  380. return 1;
  381. #endif
  382. }
  383. if (Param1 == WizPagesFinal) {
  384. #ifdef NT5FAXINSTALL
  385. return 0;
  386. #else
  387. SetupRequestPages->Pages[0] = GetFinalWizardPage();
  388. return 1;
  389. #endif
  390. }
  391. }
  392. break;
  393. case OC_CALC_DISK_SPACE:
  394. if (NtGuiMode && !Upgrade) {
  395. CalcServerDiskSpace(
  396. SetupInitComponent.ComponentInfHandle,
  397. (HDSKSPC) Param2,
  398. NULL,
  399. Param1
  400. );
  401. }
  402. break;
  403. case OC_QUEUE_FILE_OPS:
  404. if (!SubcomponentId || !*SubcomponentId) {
  405. return 0;
  406. }
  407. if (NtGuiMode && !Upgrade) {
  408. AddServerFilesToQueue(
  409. SetupInitComponent.ComponentInfHandle,
  410. (HSPFILEQ) Param2,
  411. NULL
  412. );
  413. }
  414. break;
  415. case OC_COMPLETE_INSTALLATION:
  416. if (!SubcomponentId || !*SubcomponentId) {
  417. return 0;
  418. }
  419. if (NtGuiMode) {
  420. ServerInstallation(
  421. SetupInitComponent.HelperRoutines.QueryWizardDialogHandle(
  422. SetupInitComponent.HelperRoutines.OcManagerContext
  423. ),
  424. SourcePath
  425. );
  426. }
  427. break;
  428. case OC_QUERY_STEP_COUNT:
  429. if (!SubcomponentId || !*SubcomponentId) {
  430. return 0;
  431. }
  432. return ServerGetStepCount() * 10;
  433. case OC_CLEANUP:
  434. break;
  435. default:
  436. break;
  437. }
  438. return 0;
  439. }