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.

1140 lines
27 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. This file implements utility functions.
  7. Environment:
  8. WIN32 User Mode
  9. Author:
  10. Wesley Witt (wesw) 17-Feb-1996
  11. --*/
  12. #include "faxocm.h"
  13. #include "tchar.h"
  14. #pragma hdrstop
  15. typedef struct _STRING_TABLE {
  16. DWORD ResourceId;
  17. BOOL UseTitle;
  18. LPWSTR String;
  19. } STRING_TABLE, *PSTRING_TABLE;
  20. static STRING_TABLE StringTable[] =
  21. {
  22. { IDS_TITLE_WKS, FALSE, NULL },
  23. { IDS_TITLE_SRV, FALSE, NULL },
  24. { IDS_TITLE_PP, FALSE, NULL },
  25. { IDS_TITLE_RA, FALSE, NULL },
  26. { IDS_WRN_TITLE, TRUE, NULL },
  27. { IDS_ERR_TITLE, TRUE, NULL },
  28. { IDS_COULD_NOT_CREATE_PRINTER, FALSE, NULL },
  29. { IDS_COULD_SET_REG_DATA, FALSE, NULL },
  30. { IDS_CREATING_FAXPRT, FALSE, NULL },
  31. { IDS_CREATING_GROUPS, FALSE, NULL },
  32. { IDS_DEFAULT_CSID, FALSE, NULL },
  33. { IDS_DEFAULT_DIR, FALSE, NULL },
  34. { IDS_DEFAULT_PRINTER_NAME, FALSE, NULL },
  35. { IDS_DEFAULT_TSID, FALSE, NULL },
  36. { IDS_DELETING_FAX_SERVICE, FALSE, NULL },
  37. { IDS_DELETING_GROUPS, FALSE, NULL },
  38. { IDS_DELETING_REGISTRY, FALSE, NULL },
  39. { IDS_INBOUND_DIR, FALSE, NULL },
  40. { IDS_INSTALLING_EXCHANGE, FALSE, NULL },
  41. { IDS_INSTALLING_FAXSVC, FALSE, NULL },
  42. { IDS_QUERY_CANCEL, FALSE, NULL },
  43. { IDS_SETTING_REGISTRY, FALSE, NULL },
  44. { IDS_EULA_SUBTITLE, FALSE, NULL },
  45. { IDS_EULA_TITLE, FALSE, NULL },
  46. { IDS_FAX_DISPLAY_NAME, FALSE, NULL },
  47. { IDS_FAXAB_DISPLAY_NAME, FALSE, NULL },
  48. { IDS_FAXXP_DISPLAY_NAME, FALSE, NULL },
  49. { IDS_MODEM_PROVIDER_NAME, FALSE, NULL },
  50. { IDS_FAX_UNINSTALL_NAME, FALSE, NULL },
  51. { IDS_PERSONAL_COVERPAGE, FALSE, NULL },
  52. { IDS_RECEIVE_DIR, FALSE, NULL },
  53. { IDS_ARCHIVE_DIR, FALSE, NULL },
  54. { IDS_COMMONAPPDIR, FALSE, NULL },
  55. { IDS_COVERPAGE, FALSE, NULL },
  56. { IDS_COVERPAGEDESC, FALSE, NULL },
  57. { IDS_MONITOR, FALSE, NULL },
  58. { IDS_INCOMING, FALSE, NULL },
  59. { IDS_OUTGOING, FALSE, NULL },
  60. { IDS_SERVICE_DESCRIPTION, FALSE, NULL },
  61. { IDS_COVERPAGE_DIR, FALSE, NULL },
  62. { IDS_RT_EMAIL_FRIENDLY, FALSE, NULL },
  63. { IDS_RT_FOLDER_FRIENDLY, FALSE, NULL },
  64. { IDS_RT_INBOX_FRIENDLY, FALSE, NULL },
  65. { IDS_RT_PRINT_FRIENDLY, FALSE, NULL }
  66. };
  67. #define CountStringTable (sizeof(StringTable)/sizeof(STRING_TABLE))
  68. VOID
  69. SetTitlesInStringTable(
  70. VOID
  71. )
  72. {
  73. DWORD i;
  74. WCHAR Buffer[1024];
  75. DWORD Index = 0;
  76. for (i=0; i<CountStringTable; i++) {
  77. if (StringTable[i].UseTitle) {
  78. if (LoadString(
  79. hInstance,
  80. StringTable[i].ResourceId,
  81. Buffer,
  82. sizeof(Buffer)/sizeof(WCHAR)
  83. ))
  84. {
  85. if (StringTable[i].String) {
  86. MemFree( StringTable[i].String );
  87. }
  88. StringTable[i].String = (LPWSTR) MemAlloc( StringSize( Buffer ) + 256 );
  89. if (StringTable[i].String) {
  90. if (NtWorkstation) {
  91. Index = 0;
  92. } else {
  93. Index = 1;
  94. }
  95. swprintf( StringTable[i].String, Buffer, StringTable[Index].String );
  96. }
  97. }
  98. }
  99. }
  100. }
  101. VOID
  102. InitializeStringTable(
  103. VOID
  104. )
  105. {
  106. DWORD i;
  107. WCHAR Buffer[512];
  108. SYSTEM_INFO SystemInfo;
  109. GetSystemInfo( &SystemInfo );
  110. switch (SystemInfo.wProcessorArchitecture) {
  111. case PROCESSOR_ARCHITECTURE_INTEL:
  112. swprintf(ThisPlatformName, L"i386" );
  113. break;
  114. case PROCESSOR_ARCHITECTURE_ALPHA:
  115. swprintf(ThisPlatformName, L"alpha" );
  116. break;
  117. case PROCESSOR_ARCHITECTURE_MIPS:
  118. swprintf(ThisPlatformName, L"mips" );
  119. break;
  120. case PROCESSOR_ARCHITECTURE_PPC:
  121. swprintf(ThisPlatformName, L"ppc" );
  122. break;
  123. default:
  124. DebugPrint(( L"Unsupported platform!" ));
  125. break;
  126. }
  127. for (i=0; i<CountStringTable; i++) {
  128. if (LoadString(
  129. hInstance,
  130. StringTable[i].ResourceId,
  131. Buffer,
  132. sizeof(Buffer)/sizeof(WCHAR)
  133. )) {
  134. StringTable[i].String = (LPWSTR) MemAlloc( StringSize( Buffer ) + 256 );
  135. if (!StringTable[i].String) {
  136. StringTable[i].String = L"";
  137. } else {
  138. wcscpy( StringTable[i].String, Buffer );
  139. }
  140. } else {
  141. StringTable[i].String = L"";
  142. }
  143. }
  144. SetTitlesInStringTable();
  145. }
  146. LPWSTR
  147. GetString(
  148. DWORD ResourceId
  149. )
  150. {
  151. DWORD i;
  152. for (i=0; i<CountStringTable; i++) {
  153. if (StringTable[i].ResourceId == ResourceId) {
  154. return StringTable[i].String;
  155. }
  156. }
  157. return NULL;
  158. }
  159. extern "C"
  160. LPWSTR
  161. MyGetString(
  162. DWORD ResourceId
  163. )
  164. {
  165. DWORD i;
  166. for (i=0; i<CountStringTable; i++) {
  167. if (StringTable[i].ResourceId == ResourceId) {
  168. return StringTable[i].String;
  169. }
  170. }
  171. return NULL;
  172. }
  173. int
  174. PopUpMsg(
  175. HWND hwnd,
  176. DWORD ResourceId,
  177. BOOL Error,
  178. DWORD Type
  179. )
  180. {
  181. if (NtGuiMode) {
  182. WCHAR Buffer[256];
  183. wsprintf(Buffer, L"%s : %s\n", GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ), GetString(ResourceId) );
  184. OutputDebugString(Buffer);
  185. return 0;
  186. }
  187. return MessageBox(
  188. hwnd,
  189. GetString( ResourceId ),
  190. GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ),
  191. MB_SETFOREGROUND | (Error ? MB_ICONEXCLAMATION : MB_ICONINFORMATION) | (Type == 0 ? MB_OK : Type)
  192. );
  193. }
  194. int
  195. PopUpMsgFmt(
  196. HWND hwnd,
  197. DWORD ResourceId,
  198. BOOL Error,
  199. DWORD Type,
  200. ...
  201. )
  202. {
  203. WCHAR buf[1024];
  204. va_list arg_ptr;
  205. va_start(arg_ptr, Type);
  206. _vsnwprintf( buf, sizeof(buf), GetString( ResourceId ), arg_ptr );
  207. if (NtGuiMode) {
  208. WCHAR Buffer[1024];
  209. wsprintf(Buffer, L"%s : %s\n", GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ), buf );
  210. OutputDebugString(Buffer);
  211. return 0;
  212. }
  213. return MessageBox(
  214. hwnd,
  215. buf,
  216. GetString( Error ? IDS_ERR_TITLE : IDS_WRN_TITLE ),
  217. MB_SETFOREGROUND | (Error ? MB_ICONEXCLAMATION : MB_ICONINFORMATION) | (Type == 0 ? MB_OK : Type)
  218. );
  219. }
  220. LPWSTR
  221. GetProductName(
  222. VOID
  223. )
  224. {
  225. DWORD Index;
  226. if (NtWorkstation) {
  227. Index = 0;
  228. } else {
  229. Index = 1;
  230. }
  231. return StringTable[Index].String;
  232. }
  233. VOID
  234. DoExchangeInstall(
  235. HWND hwnd
  236. )
  237. {
  238. TCHAR SystemPath[MAX_PATH];
  239. ExpandEnvironmentStrings(L"%systemroot%\\system32",SystemPath,sizeof(SystemPath));
  240. //
  241. // we don't install the fax address book anymore
  242. //
  243. //AddFaxAbToMapiSvcInf();
  244. AddFaxXpToMapiSvcInf(SystemPath);
  245. InstallExchangeClientExtension(
  246. EXCHANGE_CLIENT_EXT_NAME,
  247. "Extensions",
  248. EXCHANGE_CLIENT_EXT_FILE,
  249. EXCHANGE_CONTEXT_MASK
  250. );
  251. #ifdef WX86
  252. TCHAR Wx86SystemPath[MAX_PATH];
  253. Wx86GetX86SystemDirectory(Wx86SystemPath, sizeof(Wx86SystemPath));
  254. //AddFaxAbToMapiSvcInf();
  255. AddFaxXpToMapiSvcInf(Wx86SystemPath);
  256. InstallExchangeClientExtension(
  257. EXCHANGE_CLIENT_EXT_NAME,
  258. "Extensions (x86)",
  259. EXCHANGE_CLIENT_EXT_FILE,
  260. EXCHANGE_CONTEXT_MASK
  261. );
  262. #endif
  263. }
  264. BOOL
  265. CreateNetworkShare(
  266. LPWSTR Path,
  267. LPWSTR ShareName,
  268. LPWSTR Comment
  269. )
  270. {
  271. SHARE_INFO_2 ShareInfo;
  272. NET_API_STATUS rVal;
  273. WCHAR ExpandedPath[MAX_PATH*2];
  274. ExpandEnvironmentStrings( Path, ExpandedPath, sizeof(ExpandedPath) );
  275. ShareInfo.shi2_netname = ShareName;
  276. ShareInfo.shi2_type = STYPE_DISKTREE;
  277. ShareInfo.shi2_remark = Comment;
  278. ShareInfo.shi2_permissions = ACCESS_ALL;
  279. ShareInfo.shi2_max_uses = (DWORD) -1,
  280. ShareInfo.shi2_current_uses = (DWORD) -1;
  281. ShareInfo.shi2_path = ExpandedPath;
  282. ShareInfo.shi2_passwd = NULL;
  283. rVal = NetShareAdd(
  284. NULL,
  285. 2,
  286. (LPBYTE) &ShareInfo,
  287. NULL
  288. );
  289. return rVal == 0;
  290. }
  291. BOOL
  292. DeleteNetworkShare(
  293. LPWSTR ShareName
  294. )
  295. {
  296. NET_API_STATUS rVal;
  297. rVal = NetShareDel(
  298. NULL,
  299. ShareName,
  300. 0
  301. );
  302. return rVal == 0;
  303. }
  304. BOOL
  305. DeleteDirectoryTree(
  306. LPWSTR Root
  307. )
  308. {
  309. WCHAR FileName[MAX_PATH*2];
  310. WIN32_FIND_DATA FindData;
  311. HANDLE hFind;
  312. swprintf( FileName, L"%s\\*", Root );
  313. hFind = FindFirstFile( FileName, &FindData );
  314. if (hFind == INVALID_HANDLE_VALUE) {
  315. return FALSE;
  316. }
  317. do {
  318. if (FindData.cFileName[0] == L'.') {
  319. continue;
  320. }
  321. if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  322. DeleteDirectoryTree( FindData.cFileName );
  323. } else {
  324. MyDeleteFile( FindData.cFileName );
  325. }
  326. } while (FindNextFile( hFind, &FindData ));
  327. FindClose( hFind );
  328. RemoveDirectory( Root );
  329. return TRUE;
  330. }
  331. BOOL
  332. MyDeleteFile(
  333. LPWSTR FileName
  334. )
  335. {
  336. if (GetFileAttributes( FileName ) == 0xffffffff) {
  337. //
  338. // the file does not exists
  339. //
  340. return TRUE;
  341. }
  342. if (!DeleteFile( FileName )) {
  343. if (MoveFileEx( FileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT )) {
  344. RebootRequired = TRUE;
  345. return TRUE;
  346. } else {
  347. return FALSE;
  348. }
  349. } else {
  350. return TRUE;
  351. }
  352. }
  353. VOID
  354. FitRectToScreen(
  355. PRECT prc
  356. )
  357. {
  358. INT cxScreen;
  359. INT cyScreen;
  360. INT delta;
  361. cxScreen = GetSystemMetrics(SM_CXSCREEN);
  362. cyScreen = GetSystemMetrics(SM_CYSCREEN);
  363. if (prc->right > cxScreen) {
  364. delta = prc->right - prc->left;
  365. prc->right = cxScreen;
  366. prc->left = prc->right - delta;
  367. }
  368. if (prc->left < 0) {
  369. delta = prc->right - prc->left;
  370. prc->left = 0;
  371. prc->right = prc->left + delta;
  372. }
  373. if (prc->bottom > cyScreen) {
  374. delta = prc->bottom - prc->top;
  375. prc->bottom = cyScreen;
  376. prc->top = prc->bottom - delta;
  377. }
  378. if (prc->top < 0) {
  379. delta = prc->bottom - prc->top;
  380. prc->top = 0;
  381. prc->bottom = prc->top + delta;
  382. }
  383. }
  384. VOID
  385. CenterWindow(
  386. HWND hwnd,
  387. HWND hwndToCenterOver
  388. )
  389. {
  390. RECT rc;
  391. RECT rcOwner;
  392. RECT rcCenter;
  393. HWND hwndOwner;
  394. GetWindowRect( hwnd, &rc );
  395. if (hwndToCenterOver) {
  396. hwndOwner = hwndToCenterOver;
  397. GetClientRect( hwndOwner, &rcOwner );
  398. } else {
  399. hwndOwner = GetWindow( hwnd, GW_OWNER );
  400. if (!hwndOwner) {
  401. hwndOwner = GetDesktopWindow();
  402. }
  403. GetWindowRect( hwndOwner, &rcOwner );
  404. }
  405. //
  406. // Calculate the starting x,y for the new
  407. // window so that it would be centered.
  408. //
  409. rcCenter.left = rcOwner.left +
  410. (((rcOwner.right - rcOwner.left) -
  411. (rc.right - rc.left))
  412. / 2);
  413. rcCenter.top = rcOwner.top +
  414. (((rcOwner.bottom - rcOwner.top) -
  415. (rc.bottom - rc.top))
  416. / 2);
  417. rcCenter.right = rcCenter.left + (rc.right - rc.left);
  418. rcCenter.bottom = rcCenter.top + (rc.bottom - rc.top);
  419. FitRectToScreen( &rcCenter );
  420. SetWindowPos(hwnd, NULL, rcCenter.left, rcCenter.top, 0, 0,
  421. SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
  422. }
  423. BOOL
  424. CreateLocalFaxPrinter(
  425. LPWSTR FaxPrinterName
  426. )
  427. {
  428. STARTUPINFO si;
  429. PROCESS_INFORMATION pi;
  430. WCHAR TmpCmdLine[512];
  431. WCHAR CmdLine[512];
  432. DWORD ExitCode;
  433. BOOL Rval = TRUE;
  434. MONITOR_INFO_2 MonitorInfo;
  435. PPRINTER_INFO_2 PrinterInfo;
  436. DWORD i;
  437. DWORD Count;
  438. WCHAR SourcePath[MAX_PATH];
  439. //
  440. // check to see if a fax printer already exists
  441. // if so, do nothing but return success
  442. //
  443. PrinterInfo = (PPRINTER_INFO_2) MyEnumPrinters( NULL, 2, &Count, PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS );
  444. if (PrinterInfo) {
  445. for (i=0; i<Count; i++) {
  446. if (_wcsicmp( PrinterInfo[i].pDriverName, FAX_DRIVER_NAME ) == 0) {
  447. MemFree( PrinterInfo );
  448. return TRUE;
  449. }
  450. }
  451. MemFree( PrinterInfo );
  452. }
  453. //
  454. // create the print monitor
  455. //
  456. MonitorInfo.pName = FAX_MONITOR_NAME;
  457. MonitorInfo.pEnvironment = NULL;
  458. MonitorInfo.pDLLName = FAX_MONITOR_FILE;
  459. if ((!AddMonitor( NULL, 2, (LPBYTE) &MonitorInfo )) &&
  460. (GetLastError() != ERROR_PRINT_MONITOR_ALREADY_INSTALLED))
  461. {
  462. DebugPrint(( L"AddMonitor() failed, ec=%d", GetLastError() ));
  463. return FALSE;
  464. }
  465. ExpandEnvironmentStrings( L"%windir%\\system32", &SourcePath[0], MAX_PATH );
  466. DebugPrint((L"faxocm - CreateLocalFaxPrinter SourcePath = %s", SourcePath));
  467. swprintf(
  468. TmpCmdLine,
  469. L"rundll32 printui.dll,PrintUIEntry %s /q /if /b \"%s\" /f \"%%windir%%\\inf\\ntprint.inf\" /r \"MSFAX:\" /m \"%s\" /l \"%s\"",
  470. IsProductSuite() ? L"/Z" : L"/z",
  471. FaxPrinterName,
  472. FAX_DRIVER_NAME,
  473. SourcePath
  474. );
  475. ExpandEnvironmentStrings( TmpCmdLine, CmdLine, sizeof(CmdLine)/sizeof(WCHAR) );
  476. GetStartupInfo( &si );
  477. if (!CreateProcess(
  478. NULL,
  479. CmdLine,
  480. NULL,
  481. NULL,
  482. FALSE,
  483. DETACHED_PROCESS,
  484. NULL,
  485. NULL,
  486. &si,
  487. &pi
  488. ))
  489. {
  490. return FALSE;
  491. }
  492. if (WaitForSingleObject( pi.hProcess, MinToNano(3) ) == WAIT_TIMEOUT) {
  493. TerminateProcess( pi.hProcess, 0 );
  494. }
  495. if (!GetExitCodeProcess( pi.hProcess, &ExitCode ) || ExitCode != 0) {
  496. Rval = FALSE;
  497. }
  498. CloseHandle( pi.hProcess );
  499. CloseHandle( pi.hThread );
  500. return Rval;
  501. }
  502. PVOID
  503. MyEnumPortMonitors(
  504. LPTSTR pServerName,
  505. DWORD level,
  506. PDWORD pcMonitors
  507. )
  508. {
  509. PBYTE pMonitorInfo = NULL;
  510. DWORD cb = 0;
  511. DWORD Error;
  512. if (!EnumMonitors(pServerName, level, NULL, 0, &cb, pcMonitors)){
  513. Error = GetLastError();
  514. if(Error == ERROR_INSUFFICIENT_BUFFER && (pMonitorInfo = (PBYTE) MemAlloc(cb)) != NULL){
  515. EnumMonitors(pServerName, level, pMonitorInfo, cb, &cb, pcMonitors);
  516. return pMonitorInfo;
  517. }
  518. }
  519. MemFree(pMonitorInfo);
  520. return NULL;
  521. }
  522. BOOL
  523. RecreateNt5Beta3FaxPrinters(
  524. VOID
  525. )
  526. {
  527. PMONITOR_INFO_2 MonitorInfo;
  528. MONITOR_INFO_2 MonitorStruct;
  529. PPRINTER_INFO_2 PrinterInfo;
  530. HANDLE hPrinter;
  531. DWORD Count, i, j = -1;
  532. PRINTER_DEFAULTS PrinterDefaults = {
  533. NULL,
  534. NULL,
  535. PRINTER_ALL_ACCESS
  536. };
  537. BOOL Result;
  538. WCHAR szDllPath[MAX_PATH];
  539. DebugPrint(( TEXT("faxocm inside RecreateNt5Beta3FaxPrinters") ));
  540. // Get the path for faxmon.dll
  541. ZeroMemory(szDllPath, sizeof(szDllPath));
  542. if (GetSystemDirectory(szDllPath, sizeof(szDllPath)) == 0) {
  543. DebugPrint(( TEXT("GetSystemDirectory() failed, ec = 0x%08x"), GetLastError() ));
  544. return FALSE;
  545. }
  546. wcscat(szDllPath, L"\\faxmon.dll");
  547. //
  548. // check to see if old port monitor exists
  549. // if so, delete all fax printers and recreate them
  550. //
  551. MonitorInfo = (PMONITOR_INFO_2) MyEnumPortMonitors( NULL, 2, &Count );
  552. if (!MonitorInfo) {
  553. return TRUE;
  554. }
  555. for (i=0; i<Count; i++) {
  556. if (_wcsicmp( MonitorInfo[i].pName, FAX_MONITOR_NAME ) == 0 &&
  557. _wcsicmp( MonitorInfo[i].pDLLName, L"faxmon.dll" ) == 0) {
  558. DebugPrint(( TEXT("faxocm found old port monitor") ));
  559. break;
  560. }
  561. }
  562. MemFree(MonitorInfo);
  563. if (i>=Count) {
  564. DebugPrint(( TEXT("faxocm did not find old port monitor") ));
  565. return TRUE;
  566. }
  567. PrinterInfo = (PPRINTER_INFO_2) MyEnumPrinters( NULL, 2, &Count, PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS );
  568. if (!PrinterInfo) {
  569. goto e0;
  570. }
  571. for (i=0; i<Count; i++) {
  572. if (_wcsicmp( PrinterInfo[i].pDriverName, FAX_DRIVER_NAME ) == 0 &&
  573. _wcsicmp( PrinterInfo[i].pPortName, FAX_PORT_NAME ) == 0) {
  574. if (OpenPrinter( PrinterInfo[i].pPrinterName, &hPrinter, &PrinterDefaults)) {
  575. DebugPrint(( TEXT("faxocm deleting printer %s"), PrinterInfo[i].pPrinterName ));
  576. Result = DeletePrinter( hPrinter );
  577. j = i;
  578. ClosePrinter( hPrinter );
  579. }
  580. }
  581. }
  582. MemFree( PrinterInfo );
  583. e0:
  584. //
  585. // Delete the port monitor which will delete the port
  586. //
  587. DeleteMonitor( NULL, NULL, FAX_MONITOR_NAME);
  588. //
  589. // Mark faxmon.dll for deletion
  590. //
  591. MoveFileEx(szDllPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  592. //
  593. // create the print monitor
  594. //
  595. MonitorStruct.pName = FAX_MONITOR_NAME;
  596. MonitorStruct.pEnvironment = NULL;
  597. MonitorStruct.pDLLName = FAX_MONITOR_FILE;
  598. if ((!AddMonitor( NULL, 2, (LPBYTE) &MonitorStruct )) &&
  599. (GetLastError() != ERROR_PRINT_MONITOR_ALREADY_INSTALLED))
  600. {
  601. DebugPrint(( L"AddMonitor() failed, ec=%d", GetLastError() ));
  602. return FALSE;
  603. }
  604. if ( j != -1 ) {
  605. //
  606. // create the fax printer which will create the port monitor
  607. //
  608. Result = CreateLocalFaxPrinter( GetString( IDS_DEFAULT_PRINTER_NAME ) );
  609. if (Result) {
  610. DebugPrint(( TEXT("faxocm created printer %s"), GetString( IDS_DEFAULT_PRINTER_NAME ) ));
  611. } else {
  612. DebugPrint(( TEXT("faxocm FAILED trying to create printer %s"), GetString( IDS_DEFAULT_PRINTER_NAME ) ));
  613. }
  614. }
  615. return TRUE;
  616. }
  617. BOOL
  618. RecreateNt4FaxPrinters(
  619. VOID
  620. )
  621. {
  622. PPRINTER_INFO_2 PrinterInfo;
  623. HANDLE hPrinter;
  624. DWORD Count, i, j = -1;
  625. PRINTER_DEFAULTS PrinterDefaults = {
  626. NULL,
  627. NULL,
  628. PRINTER_ALL_ACCESS
  629. };
  630. BOOL Result;
  631. DebugPrint(( TEXT("faxocm inside RecreateNt4FaxPrinters") ));
  632. //
  633. // check to see if a fax printer already exists
  634. // if so, delete it and create it
  635. //
  636. PrinterInfo = (PPRINTER_INFO_2) MyEnumPrinters( NULL, 2, &Count, PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS );
  637. if (PrinterInfo) {
  638. for (i=0; i<Count; i++) {
  639. if (_wcsicmp( PrinterInfo[i].pDriverName, FAX_DRIVER_NAME ) == 0 &&
  640. _wcsicmp( PrinterInfo[i].pPortName, FAX_PORT_NAME ) != 0) {
  641. if (OpenPrinter( PrinterInfo[i].pPrinterName, &hPrinter, &PrinterDefaults)) {
  642. DebugPrint(( TEXT("faxocm deleting printer %s"), PrinterInfo[i].pPrinterName ));
  643. Result = DeletePrinter( hPrinter );
  644. j = i;
  645. ClosePrinter( hPrinter );
  646. }
  647. }
  648. }
  649. if ( j != -1 ) {
  650. //
  651. // create the fax printer which will create the port monitor
  652. //
  653. Result = CreateLocalFaxPrinter( GetString( IDS_DEFAULT_PRINTER_NAME ) );
  654. if (Result) {
  655. DebugPrint(( TEXT("faxocm created printer %s"), GetString( IDS_DEFAULT_PRINTER_NAME ) ));
  656. } else {
  657. DebugPrint(( TEXT("faxocm FAILED trying to create printer %s"), GetString( IDS_DEFAULT_PRINTER_NAME ) ));
  658. }
  659. }
  660. MemFree( PrinterInfo );
  661. }
  662. return TRUE;
  663. }
  664. BOOL
  665. RegisterOleControlDlls(
  666. HINF InfHandle
  667. )
  668. {
  669. typedef VOID (WINAPI *PREGISTERROUTINE)(VOID);
  670. INFCONTEXT InfLine;
  671. WCHAR Filename[MAX_PATH];
  672. WCHAR FullPath[MAX_PATH];
  673. BOOL b = TRUE;
  674. HMODULE ControlDll;
  675. DWORD d;
  676. LPCWSTR szOleControlDlls = L"OleControlDlls";
  677. WCHAR OldCD[MAX_PATH];
  678. PREGISTERROUTINE RegisterRoutine;
  679. //
  680. // Preserve current directory just in case
  681. //
  682. d = GetCurrentDirectory(MAX_PATH,OldCD);
  683. if(!d || (d >= MAX_PATH)) {
  684. OldCD[0] = 0;
  685. }
  686. OleInitialize(NULL);
  687. if (SetupFindFirstLine(InfHandle,szOleControlDlls,NULL,&InfLine)) {
  688. do {
  689. SetupGetStringField( &InfLine, 1, Filename, sizeof(Filename)/sizeof(WCHAR), &d );
  690. if (Filename[0]) {
  691. //
  692. // Form a full path to the dll
  693. //
  694. ExpandEnvironmentStrings( L"%windir%\\system32\\", FullPath, sizeof(FullPath)/sizeof(WCHAR) );
  695. SetCurrentDirectory( FullPath );
  696. wcscat( FullPath, Filename );
  697. if(ControlDll = LoadLibrary(FullPath)) {
  698. if (RegisterRoutine = (PREGISTERROUTINE) GetProcAddress(ControlDll,"DllRegisterServer")) {
  699. __try {
  700. RegisterRoutine();
  701. } __except (EXCEPTION_EXECUTE_HANDLER) {
  702. b = FALSE;
  703. }
  704. } else {
  705. b = FALSE;
  706. }
  707. FreeLibrary(ControlDll);
  708. } else {
  709. b = FALSE;
  710. }
  711. } else {
  712. b = FALSE;
  713. }
  714. } while(SetupFindNextLine(&InfLine,&InfLine));
  715. }
  716. if(OldCD[0]) {
  717. SetCurrentDirectory(OldCD);
  718. }
  719. OleUninitialize();
  720. return b;
  721. }
  722. LPWSTR
  723. VerifyInstallPath(
  724. LPWSTR SourcePath
  725. )
  726. {
  727. HKEY hKey;
  728. WCHAR SourceFile[MAX_PATH];
  729. int len;
  730. //
  731. // make sure our source path contains necessary files.
  732. //
  733. wcscpy(SourceFile,SourcePath);
  734. len = wcslen(SourcePath);
  735. if (SourceFile[len-1] != '\\' ) {
  736. SourceFile[len] = '\\';
  737. SourceFile[len+1] = (WCHAR) 0;
  738. }
  739. wcscat(SourceFile,L"faxdrv.dll");
  740. if (GetFileAttributes(SourceFile) != (DWORD) -1 ) {
  741. return SourcePath;
  742. }
  743. //
  744. // our source path must be incorrect, use the registered NT source path
  745. //
  746. MemFree(SourcePath);
  747. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,REGKEY_WINDOWSNT_CURRVER,FALSE,0);
  748. if (!hKey) {
  749. DebugPrint(( TEXT("Could'nt OpenRegistryKey, ec = %d\n"),GetLastError() ));
  750. return NULL;
  751. }
  752. SourcePath = GetRegistryString(hKey,REGVAL_SOURCE_PATH,NULL);
  753. RegCloseKey(hKey);
  754. return SourcePath;
  755. }
  756. BOOL
  757. SetFaxShellExtension(
  758. LPCWSTR Path
  759. )
  760. {
  761. WCHAR FileName[MAX_PATH];
  762. DWORD attrib;
  763. //
  764. // create the file
  765. //
  766. wsprintf(FileName, L"%s\\desktop.ini", Path);
  767. WritePrivateProfileString( L".ShellClassInfo",
  768. L"UICLSID",
  769. FAXSHELL_CLSID,
  770. FileName
  771. );
  772. //
  773. // hide it
  774. //
  775. attrib = GetFileAttributes( FileName );
  776. attrib |= FILE_ATTRIBUTE_HIDDEN;
  777. if (SetFileAttributes( FileName, attrib ) ) {
  778. //
  779. // better to use PathMakeSystemFolder, but don't want to get shlwapi involved,
  780. // so we just set the system flag for the folder.
  781. //
  782. attrib = GetFileAttributes( Path );
  783. attrib |= FILE_ATTRIBUTE_SYSTEM;
  784. return ( SetFileAttributes( Path, attrib ) );
  785. } else {
  786. return FALSE;
  787. }
  788. }
  789. BOOL
  790. IsNt4or351Upgrade(
  791. VOID
  792. )
  793. {
  794. //
  795. // we know that after installing NT5, the pid3.0 digital product id should be stored. we can
  796. // determine if nt5 was installed by looking for this value
  797. //
  798. HKEY hKey;
  799. LONG rslt;
  800. BYTE data[1000];
  801. DWORD dwType;
  802. DWORD cbData = sizeof(data);
  803. rslt = RegOpenKey(HKEY_LOCAL_MACHINE,WINNT_CURVER,&hKey);
  804. if (rslt != ERROR_SUCCESS) {
  805. return FALSE;
  806. }
  807. rslt = RegQueryValueEx(hKey,DIGID,NULL,&dwType,data,&cbData);
  808. RegCloseKey(hKey);
  809. return (rslt != ERROR_SUCCESS);
  810. }
  811. BOOL
  812. MyGetSpecialPath(
  813. INT Id,
  814. LPWSTR Buffer
  815. )
  816. {
  817. WCHAR TempBuffer[MAX_PATH];
  818. HKEY hKey;
  819. LONG rslt;
  820. BYTE data[1000];
  821. DWORD dwType;
  822. DWORD cbData = sizeof(data);
  823. if (GetSpecialPath(Id,Buffer)) {
  824. return TRUE;
  825. }
  826. //
  827. // if it fails, then let's try to hack hack hack our way around this
  828. //
  829. rslt = RegOpenKey(HKEY_LOCAL_MACHINE,WINNT_CURVER REGKEY_PROFILES ,&hKey);
  830. if (rslt != ERROR_SUCCESS) {
  831. return FALSE;
  832. }
  833. rslt = RegQueryValueEx(hKey,REGVAL_PROFILES,NULL,&dwType,data,&cbData);
  834. RegCloseKey(hKey);
  835. if (rslt != ERROR_SUCCESS) {
  836. //
  837. //
  838. //
  839. return FALSE;
  840. }
  841. ExpandEnvironmentStrings((LPCTSTR) data,TempBuffer,sizeof(TempBuffer));
  842. if (Id == CSIDL_COMMON_APPDATA) {
  843. ConcatenatePaths( TempBuffer, GetString(IDS_COMMONAPPDIR) );
  844. lstrcpy( Buffer, TempBuffer);
  845. return TRUE;
  846. }
  847. return FALSE;
  848. }
  849. BOOL
  850. SuperHideDirectory(
  851. PWSTR Directory
  852. )
  853. {
  854. //
  855. // super-hide means that even if the user says "show all files", the directory won't show up.
  856. //
  857. DWORD attrib;
  858. if (!Directory) {
  859. return FALSE;
  860. }
  861. //
  862. // hide it
  863. //
  864. attrib = GetFileAttributes( Directory );
  865. attrib |= (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
  866. return ( SetFileAttributes( Directory, attrib ) );
  867. }
  868. BOOL
  869. MyInitializeMapi(
  870. BOOL MinimalInit
  871. )
  872. {
  873. HKEY hKey = NULL;
  874. LPTSTR szNoMailClient = NULL;
  875. LPTSTR szPreFirstRun = NULL;
  876. BOOL bRslt = FALSE;
  877. hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Clients\\Mail"), FALSE, KEY_ALL_ACCESS);
  878. if (hKey != NULL) {
  879. szNoMailClient = GetRegistryString(hKey, TEXT("NoMailClient"), TEXT(""));
  880. if (_tcscmp(szNoMailClient, TEXT("")) == 0) {
  881. MemFree(szNoMailClient);
  882. szNoMailClient = NULL;
  883. }
  884. else {
  885. RegDeleteValue(hKey, TEXT("NoMailClient"));
  886. }
  887. szPreFirstRun = GetRegistryString(hKey, TEXT("PreFirstRun"), TEXT(""));
  888. if (_tcscmp(szPreFirstRun, TEXT("")) == 0) {
  889. MemFree(szPreFirstRun);
  890. szPreFirstRun = NULL;
  891. }
  892. else {
  893. RegDeleteValue(hKey, TEXT("PreFirstRun"));
  894. }
  895. }
  896. bRslt = InitializeMapi(MinimalInit);
  897. if (szNoMailClient != NULL) {
  898. SetRegistryString(hKey, TEXT("NoMailClient"), szNoMailClient);
  899. MemFree(szNoMailClient);
  900. }
  901. if (szPreFirstRun != NULL) {
  902. SetRegistryString(hKey, TEXT("PreFirstRun"), szPreFirstRun);
  903. MemFree(szPreFirstRun);
  904. }
  905. if (hKey != NULL) {
  906. RegCloseKey(hKey);
  907. }
  908. return bRslt;
  909. }