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.

555 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. product.c
  5. Abstract:
  6. This file implements product type api for fax.
  7. Author:
  8. Wesley Witt (wesw) 12-Feb-1997
  9. Environment:
  10. User Mode
  11. --*/
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <tchar.h>
  16. #include <Commdlg.h>
  17. #include "faxreg.h"
  18. #include "faxutil.h"
  19. BOOL
  20. IsWinXPOS()
  21. {
  22. DWORD dwVersion, dwMajorWinVer, dwMinorWinVer;
  23. dwVersion = GetVersion();
  24. dwMajorWinVer = (DWORD)(LOBYTE(LOWORD(dwVersion)));
  25. dwMinorWinVer = (DWORD)(HIBYTE(LOWORD(dwVersion)));
  26. return (dwMajorWinVer == 5 && dwMinorWinVer >= 1);
  27. }
  28. ///////////////////////////////////////////////////////////////////////////////////////
  29. // Function:
  30. // GetProductSKU
  31. //
  32. // Purpose:
  33. // Checks what's the product SKU we're running on
  34. //
  35. // Params:
  36. // None
  37. //
  38. // Return Value:
  39. // one of PRODUCT_SKU_TYPE - declared in faxreg.h
  40. // PRODUCT_SKU_UNKNOWN - in case of failure
  41. //
  42. // Author:
  43. // Mooly Beery (MoolyB) 02-JAN-2000
  44. ///////////////////////////////////////////////////////////////////////////////////////
  45. PRODUCT_SKU_TYPE GetProductSKU()
  46. {
  47. #ifdef DEBUG
  48. HKEY hKey;
  49. DWORD dwRes;
  50. DWORD dwDebugSKU = 0;
  51. #endif
  52. OSVERSIONINFOEX osv = {0};
  53. DEBUG_FUNCTION_NAME(TEXT("GetProductSKU"))
  54. #ifdef DEBUG
  55. //
  56. // For DEBUG version try to read SKU type from the registry
  57. //
  58. dwRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_FAX_CLIENT, 0, KEY_READ, &hKey);
  59. if (dwRes == ERROR_SUCCESS)
  60. {
  61. GetRegistryDwordEx(hKey, REGVAL_DBG_SKU, &dwDebugSKU);
  62. RegCloseKey(hKey);
  63. if(PRODUCT_SKU_PERSONAL == dwDebugSKU ||
  64. PRODUCT_SKU_PROFESSIONAL == dwDebugSKU ||
  65. PRODUCT_SKU_SERVER == dwDebugSKU ||
  66. PRODUCT_SKU_ADVANCED_SERVER == dwDebugSKU ||
  67. PRODUCT_SKU_DATA_CENTER == dwDebugSKU ||
  68. PRODUCT_SKU_DESKTOP_EMBEDDED == dwDebugSKU ||
  69. PRODUCT_SKU_WEB_SERVER == dwDebugSKU ||
  70. PRODUCT_SKU_SERVER_EMBEDDED == dwDebugSKU)
  71. {
  72. return (PRODUCT_SKU_TYPE)dwDebugSKU;
  73. }
  74. }
  75. else
  76. {
  77. DebugPrintEx(DEBUG_ERR,TEXT("RegOpenKeyEx(REGKEY_FAXSERVER) failed with %ld."),dwRes);
  78. }
  79. #endif
  80. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  81. if (!GetVersionEx(((OSVERSIONINFO*)&osv)))
  82. {
  83. DebugPrintEx(DEBUG_ERR,TEXT("GetVersionEx failed with %ld."),GetLastError());
  84. ASSERT_FALSE;
  85. return PRODUCT_SKU_UNKNOWN;
  86. }
  87. if (osv.dwPlatformId != VER_PLATFORM_WIN32_NT)
  88. {
  89. DebugPrintEx(DEBUG_WRN, TEXT("Can't tell SKU for W9X Platforms"));
  90. return PRODUCT_SKU_UNKNOWN;
  91. }
  92. if (osv.dwMajorVersion < 5)
  93. {
  94. DebugPrintEx(DEBUG_WRN, TEXT("Can't tell SKU for NT4 Platform"));
  95. return PRODUCT_SKU_UNKNOWN;
  96. }
  97. // This is the matching between the different SKUs and the constants returned by GetVersionEx
  98. // Personal VER_SUITE_PERSONAL
  99. // Professional VER_NT_WORKSTATION
  100. // Server VER_NT_SERVER
  101. // Advanced Server VER_SUITE_ENTERPRISE
  102. // DataCanter VER_SUITE_DATACENTER
  103. // Embedded NT VER_SUITE_EMBEDDEDNT
  104. // Web server (AKA Blade) VER_SUITE_BLADE
  105. // First, lets see if this is embedded system
  106. if (osv.wSuiteMask & VER_SUITE_EMBEDDEDNT)
  107. {
  108. if (VER_NT_WORKSTATION == osv.wProductType)
  109. {
  110. return PRODUCT_SKU_DESKTOP_EMBEDDED;
  111. }
  112. else
  113. {
  114. return PRODUCT_SKU_SERVER_EMBEDDED;
  115. }
  116. }
  117. if (osv.wSuiteMask & VER_SUITE_PERSONAL)
  118. {
  119. return PRODUCT_SKU_PERSONAL;
  120. }
  121. if (osv.wSuiteMask & VER_SUITE_ENTERPRISE)
  122. {
  123. return PRODUCT_SKU_ADVANCED_SERVER;
  124. }
  125. if (osv.wSuiteMask & VER_SUITE_DATACENTER)
  126. {
  127. return PRODUCT_SKU_DATA_CENTER;
  128. }
  129. if (osv.wSuiteMask & VER_SUITE_BLADE)
  130. {
  131. return PRODUCT_SKU_WEB_SERVER;
  132. }
  133. if (osv.wProductType == VER_NT_WORKSTATION)
  134. {
  135. return PRODUCT_SKU_PROFESSIONAL;
  136. }
  137. if ((osv.wProductType == VER_NT_SERVER) || (osv.wProductType == VER_NT_DOMAIN_CONTROLLER))
  138. {
  139. return PRODUCT_SKU_SERVER;
  140. }
  141. ASSERT_FALSE;
  142. return PRODUCT_SKU_UNKNOWN;
  143. } // GetProductSKU
  144. ///////////////////////////////////////////////////////////////////////////////////////
  145. // Function:
  146. // IsDesktopSKU
  147. //
  148. // Purpose:
  149. // Checks if we're running on PERSONAL or PROFESSIONAL SKUs
  150. //
  151. // Params:
  152. // None
  153. //
  154. // Return Value:
  155. // TRUE - current SKU is PER/PRO
  156. // FALSE - different SKU
  157. //
  158. // Author:
  159. // Mooly Beery (MoolyB) 07-JAN-2000
  160. ///////////////////////////////////////////////////////////////////////////////////////
  161. BOOL IsDesktopSKU()
  162. {
  163. PRODUCT_SKU_TYPE pst = GetProductSKU();
  164. return (IsDesktopSKUFromSKU(pst));
  165. }
  166. ///////////////////////////////////////////////////////////////////////////////////////
  167. // Function:
  168. // IsFaxShared
  169. //
  170. // Purpose:
  171. // Checks if this is a SKU which supports fax sharing over the network
  172. //
  173. // Params:
  174. // None
  175. //
  176. // Return Value:
  177. // TRUE - current SKU supports network fax sharing
  178. // FALSE - otherwise
  179. //
  180. // Author:
  181. // Eran Yariv (EranY) 31-DEC-2001
  182. ///////////////////////////////////////////////////////////////////////////////////////
  183. BOOL IsFaxShared()
  184. {
  185. if (IsDesktopSKU())
  186. {
  187. //
  188. // Desktop SKUs (Home edition, Professional, Embedded desktop) don't support fax sharing
  189. //
  190. return FALSE;
  191. }
  192. if (PRODUCT_SKU_WEB_SERVER == GetProductSKU())
  193. {
  194. //
  195. // Blade (AKA Web Server) doesn't support fax sharing
  196. //
  197. return FALSE;
  198. }
  199. return TRUE;
  200. } // IsFaxShared
  201. ///////////////////////////////////////////////////////////////////////////////////////
  202. // Function:
  203. // GetDeviceLimit
  204. //
  205. // Purpose:
  206. // Get maximum number of the fax devices for the current Windows version
  207. //
  208. // Params:
  209. // None
  210. //
  211. // Return Value:
  212. // maximum number of the fax devices
  213. ///////////////////////////////////////////////////////////////////////////////////////
  214. DWORD
  215. GetDeviceLimit()
  216. {
  217. DWORD dwDeviceLimit = 0;
  218. PRODUCT_SKU_TYPE typeSKU = GetProductSKU();
  219. switch(typeSKU)
  220. {
  221. case PRODUCT_SKU_PERSONAL: // Windows XP Personal
  222. case PRODUCT_SKU_DESKTOP_EMBEDDED: // Windows XP embedded
  223. case PRODUCT_SKU_PROFESSIONAL: // Windows XP Professional
  224. case PRODUCT_SKU_WEB_SERVER: // Blade - Windows Server 2003 Web Server
  225. dwDeviceLimit = 1;
  226. break;
  227. case PRODUCT_SKU_SERVER_EMBEDDED: // Windows Server 2003 embedded
  228. case PRODUCT_SKU_SERVER: // Windows Server 2003 Server
  229. dwDeviceLimit = 4;
  230. break;
  231. case PRODUCT_SKU_ADVANCED_SERVER: // Windows Server 2003 Enterprise Server
  232. case PRODUCT_SKU_DATA_CENTER: // Windows Server 2003 Data Center Server
  233. dwDeviceLimit = INFINITE;
  234. break;
  235. default:
  236. ASSERT_FALSE;
  237. break;
  238. }
  239. return dwDeviceLimit;
  240. }
  241. ///////////////////////////////////////////////////////////////////////////////////////
  242. // Function:
  243. // IsFaxComponentInstalled
  244. //
  245. // Purpose:
  246. // Check if specific fax component is installed
  247. //
  248. // Params:
  249. // Fax component ID
  250. //
  251. // Return Value:
  252. // TRUE if the fax component is installed
  253. // FALSE otherwize
  254. ///////////////////////////////////////////////////////////////////////////////////////
  255. BOOL
  256. IsFaxComponentInstalled(
  257. FAX_COMPONENT_TYPE component
  258. )
  259. {
  260. HKEY hKey;
  261. DWORD dwRes;
  262. DWORD dwComponent = 0;
  263. BOOL bComponentInstalled = FALSE;
  264. DEBUG_FUNCTION_NAME(TEXT("IsFaxComponentInstalled"))
  265. PRODUCT_SKU_TYPE skuType = GetProductSKU();
  266. if (
  267. (skuType == PRODUCT_SKU_DESKTOP_EMBEDDED) ||
  268. (skuType == PRODUCT_SKU_SERVER_EMBEDDED)
  269. )
  270. {
  271. // In case this is an embedded system we have to check in the registry
  272. // what are the installed components
  273. dwRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_FAX_SETUP, 0, KEY_READ, &hKey);
  274. if (dwRes == ERROR_SUCCESS)
  275. {
  276. dwRes = GetRegistryDwordEx(hKey, REGVAL_INSTALLED_COMPONENTS, &dwComponent);
  277. if (dwRes != ERROR_SUCCESS)
  278. {
  279. DebugPrintEx(DEBUG_ERR,TEXT("GetRegistryDwordEx failed with %ld."), dwRes);
  280. }
  281. RegCloseKey(hKey);
  282. }
  283. else
  284. {
  285. DebugPrintEx(DEBUG_ERR,TEXT("RegOpenKeyEx failed with %ld."), dwRes);
  286. }
  287. bComponentInstalled = (dwComponent & component);
  288. }
  289. else
  290. {
  291. // the system is not embedded
  292. //
  293. if (IsDesktopSKU())
  294. {
  295. // DESKTOP skus -> Admin and Admin help is not installed
  296. if (
  297. (component != FAX_COMPONENT_ADMIN) &&
  298. (component != FAX_COMPONENT_HELP_ADMIN_HLP) &&
  299. (component != FAX_COMPONENT_HELP_ADMIN_CHM)
  300. )
  301. {
  302. bComponentInstalled = TRUE;
  303. }
  304. }
  305. else
  306. {
  307. // SERVER skus -> all components are installed
  308. bComponentInstalled = TRUE;
  309. }
  310. }
  311. return bComponentInstalled;
  312. } // IsFaxComponentInstalled
  313. ///////////////////////////////////////////////////////////////////////////////////////
  314. // Function:
  315. // GetOpenFileNameStructSize
  316. //
  317. // Purpose:
  318. // return correct size of OPENFILENAME passed to GetOpenFileName() and GetSaveFileName()
  319. // according to current OS version
  320. //
  321. // Return Value:
  322. // Size of OPENFILENAME struct
  323. ///////////////////////////////////////////////////////////////////////////////////////
  324. DWORD
  325. GetOpenFileNameStructSize()
  326. {
  327. DWORD dwVersion = GetVersion();
  328. if(LOBYTE(LOWORD(dwVersion)) >= 5)
  329. {
  330. //
  331. // W2K or above
  332. //
  333. return sizeof(OPENFILENAME);
  334. }
  335. return sizeof(OPENFILENAME_NT4);
  336. } // GetOpenFileNameStructSize
  337. ///////////////////////////////////////////////////////////////////////////////////////
  338. // Function:
  339. // IsDesktopSKUFromSKU
  340. //
  341. // Purpose:
  342. // Checks if we're accessing a desktop sku
  343. //
  344. // Params:
  345. // pst - the product sku
  346. //
  347. // Return Value:
  348. // TRUE - current SKU is desktop
  349. // FALSE - different SKU
  350. //
  351. // Author:
  352. // Oded Sacher (OdedS) 01-JAN-2001
  353. ///////////////////////////////////////////////////////////////////////////////////////
  354. BOOL IsDesktopSKUFromSKU(
  355. PRODUCT_SKU_TYPE pst
  356. )
  357. {
  358. return (
  359. (pst==PRODUCT_SKU_PERSONAL) ||
  360. (pst==PRODUCT_SKU_PROFESSIONAL) ||
  361. (pst==PRODUCT_SKU_DESKTOP_EMBEDDED)
  362. );
  363. }
  364. const TCHAR gszPRODUCT_SKU_UNKNOWN[] = _T("Unknown");
  365. const TCHAR gszPRODUCT_SKU_PERSONAL[] = _T("Personal");
  366. const TCHAR gszPRODUCT_SKU_PROFESSIONAL[] = _T("Professional");
  367. const TCHAR gszPRODUCT_SKU_SERVER[] = _T("Standard Server");
  368. const TCHAR gszPRODUCT_SKU_ADVANCED_SERVER[] = _T("Advanced Server");
  369. const TCHAR gszPRODUCT_SKU_DATA_CENTER[] = _T("Data Center");
  370. const TCHAR gszPRODUCT_SKU_DESKTOP_EMBEDDED[] = _T("Embedded Desktop");
  371. const TCHAR gszPRODUCT_SKU_SERVER_EMBEDDED[] = _T("Embedded Server");
  372. const TCHAR gszPRODUCT_SKU_WEB_SERVER[] = _T("Web Server");
  373. ///////////////////////////////////////////////////////////////////////////////////////
  374. // Function:
  375. // StringFromSKU
  376. //
  377. // Purpose:
  378. // Get the product SKU as a string
  379. //
  380. // Params:
  381. // None
  382. //
  383. // Author:
  384. // Mooly Beeri (MoolyB) 06-JAN-2001
  385. ///////////////////////////////////////////////////////////////////////////////////////
  386. LPCTSTR StringFromSKU(PRODUCT_SKU_TYPE pst)
  387. {
  388. switch (pst)
  389. {
  390. case PRODUCT_SKU_PERSONAL: return gszPRODUCT_SKU_PERSONAL;
  391. case PRODUCT_SKU_PROFESSIONAL: return gszPRODUCT_SKU_PROFESSIONAL;
  392. case PRODUCT_SKU_SERVER: return gszPRODUCT_SKU_SERVER;
  393. case PRODUCT_SKU_ADVANCED_SERVER: return gszPRODUCT_SKU_ADVANCED_SERVER;
  394. case PRODUCT_SKU_DATA_CENTER: return gszPRODUCT_SKU_DATA_CENTER;
  395. case PRODUCT_SKU_DESKTOP_EMBEDDED: return gszPRODUCT_SKU_DESKTOP_EMBEDDED;
  396. case PRODUCT_SKU_SERVER_EMBEDDED: return gszPRODUCT_SKU_SERVER_EMBEDDED;
  397. case PRODUCT_SKU_WEB_SERVER: return gszPRODUCT_SKU_WEB_SERVER;
  398. default: return gszPRODUCT_SKU_UNKNOWN;
  399. }
  400. }
  401. ///////////////////////////////////////////////////////////////////////////////////////
  402. // Function:
  403. // GetProductBuild
  404. //
  405. // Purpose:
  406. // Get the product's build number. retreives the file version of FXSOCM.DLL
  407. // that resides under %system32%\setup
  408. // This function should be called on XP/Server 2003 platforms only
  409. //
  410. // Params:
  411. // None
  412. //
  413. // Return Value:
  414. // Product major build - in case of success
  415. // 0 - otherwise
  416. //
  417. // Author:
  418. // Mooly Beeri (MoolyB) 06-JAN-2001
  419. ///////////////////////////////////////////////////////////////////////////////////////
  420. DWORD GetProductBuild()
  421. {
  422. TCHAR szBuffer[MAX_PATH] = {0};
  423. FAX_VERSION Version = {0};
  424. DWORD dwRet = ERROR_SUCCESS;
  425. DEBUG_FUNCTION_NAME(TEXT("GetProductBuild"))
  426. // get the system directory
  427. if (!GetSystemDirectory(szBuffer,MAX_PATH-_tcslen(FAX_SETUP_DLL_PATH)-1))
  428. {
  429. DebugPrintEx(DEBUG_ERR,TEXT("GetSystemDirectory failed with %ld."),GetLastError());
  430. return 0;
  431. }
  432. // append \\setup\\fxsocm.dll to the system directory
  433. _tcscat(szBuffer,FAX_SETUP_DLL_PATH);
  434. DebugPrintEx(DEBUG_MSG,TEXT("Getting file version for %s."),szBuffer);
  435. Version.dwSizeOfStruct = sizeof(FAX_VERSION);
  436. dwRet = GetFileVersion(szBuffer,&Version);
  437. if (dwRet!=ERROR_SUCCESS)
  438. {
  439. DebugPrintEx(DEBUG_ERR,TEXT("GetFileVersion failed with %ld."),dwRet);
  440. return 0;
  441. }
  442. DebugPrintEx(DEBUG_MSG,TEXT("Fax product build is %d."),Version.wMajorBuildNumber);
  443. return Version.wMajorBuildNumber;
  444. } // GetProductBuild
  445. DWORD
  446. IsFaxInstalled (
  447. LPBOOL lpbInstalled
  448. )
  449. /*++
  450. Routine name : IsFaxInstalled
  451. Routine description:
  452. Determines if the fax service is installed by looking into the OCM registry
  453. Author:
  454. Eran Yariv (EranY), Jul, 2000
  455. Arguments:
  456. lpbInstalled [out] - Result flag
  457. Return Value:
  458. Standard Win32 error code
  459. --*/
  460. {
  461. DWORD dwRes = ERROR_SUCCESS;
  462. DWORD dwVal;
  463. HKEY hKey;
  464. DEBUG_FUNCTION_NAME(TEXT("IsFaxInstalled"))
  465. hKey = OpenRegistryKey (HKEY_LOCAL_MACHINE,
  466. REGKEY_FAX_SETUP,
  467. FALSE,
  468. KEY_READ);
  469. if (!hKey)
  470. {
  471. dwRes = GetLastError ();
  472. DebugPrintEx(DEBUG_ERR,
  473. TEXT("OpenRegistryKey failed with %ld."),
  474. dwRes);
  475. //
  476. // Key couldn't be opened => Fax isn't installed
  477. //
  478. *lpbInstalled = FALSE;
  479. dwRes = ERROR_SUCCESS;
  480. return dwRes;
  481. }
  482. dwVal = GetRegistryDword (hKey, REGVAL_FAXINSTALLED);
  483. RegCloseKey (hKey);
  484. DebugPrintEx(DEBUG_MSG,
  485. TEXT("Fax is%s installed on the system"),
  486. dwVal ? L"" : L" not");
  487. *lpbInstalled = dwVal ? TRUE : FALSE;
  488. return dwRes;
  489. } // IsFaxInstalled