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.

644 lines
21 KiB

  1. //*************************************************************
  2. //
  3. // Global Variables
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1995
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. #include <winfoldr.h>
  12. HINSTANCE g_hDllInstance;
  13. DWORD g_dwBuildNumber;
  14. NTPRODUCTTYPE g_ProductType;
  15. HANDLE g_hProfileSetup = NULL;
  16. DWORD g_dwNumShellFolders;
  17. DWORD g_dwNumCommonShellFolders;
  18. HANDLE g_hPolicyCritMutexMach = NULL;
  19. HANDLE g_hPolicyCritMutexUser = NULL;
  20. HANDLE g_hPolicyNotifyEventMach = NULL;
  21. HANDLE g_hPolicyNotifyEventUser = NULL;
  22. HANDLE g_hPolicyNeedFGEventMach = NULL;
  23. HANDLE g_hPolicyNeedFGEventUser = NULL;
  24. HANDLE g_hPolicyDoneEventMach = NULL;
  25. HANDLE g_hPolicyDoneEventUser = NULL;
  26. HANDLE g_hPolicyForegroundDoneEventMach = 0;
  27. HANDLE g_hPolicyForegroundDoneEventUser = 0;
  28. const TCHAR c_szStarDotStar[] = TEXT("*.*");
  29. const TCHAR c_szSlash[] = TEXT("\\");
  30. const TCHAR c_szDot[] = TEXT(".");
  31. const TCHAR c_szDotDot[] = TEXT("..");
  32. const TCHAR c_szMAN[] = TEXT(".man");
  33. const TCHAR c_szUSR[] = TEXT(".usr");
  34. const TCHAR c_szLog[] = TEXT(".log");
  35. const TCHAR c_szPDS[] = TEXT(".pds");
  36. const TCHAR c_szPDM[] = TEXT(".pdm");
  37. const TCHAR c_szLNK[] = TEXT(".lnk");
  38. const TCHAR c_szBAK[] = TEXT(".bak");
  39. const TCHAR c_szNTUserTmp[] = TEXT("ntuser.tmp");
  40. const TCHAR c_szNTUserMan[] = TEXT("ntuser.man");
  41. const TCHAR c_szNTUserDat[] = TEXT("ntuser.dat");
  42. const TCHAR c_szNTUserIni[] = TEXT("ntuser.ini");
  43. const TCHAR c_szRegistryPol[] = TEXT("registry.pol");
  44. const TCHAR c_szNTUserStar[] = TEXT("ntuser.*");
  45. const TCHAR c_szUserStar[] = TEXT("user.*");
  46. const TCHAR c_szSpace[] = TEXT(" ");
  47. const TCHAR c_szDotPif[] = TEXT(".pif");
  48. const TCHAR c_szNULL[] = TEXT("");
  49. const TCHAR c_szCommonGroupsLocation[] = TEXT("Software\\Program Groups");
  50. TCHAR c_szRegistryExtName[64];
  51. //
  52. // Registry Extension guid
  53. //
  54. GUID guidRegistryExt = REGISTRY_EXTENSION_GUID;
  55. //
  56. // Special folders
  57. //
  58. FOLDER_INFO c_ShellFolders[] =
  59. {
  60. //Hidden Local Add New Within Folder Folder Folder Folder Folder
  61. // Dir? Dir CSIDl? NT5? Local Resource ID Name Location Resource Resource
  62. // Settings DLL ID
  63. {TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_APPDATA, TEXT("AppData"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_APP_DATA}, // AppData
  64. {TRUE, FALSE, TRUE, TRUE, FALSE, IDS_SH_COOKIES, TEXT("Cookies"), {0}, TEXT("shell32.dll"), 0}, // Cookies
  65. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_DESKTOP, TEXT("Desktop"), {0}, TEXT("shell32.dll"), 0}, // Desktop
  66. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_FAVORITES, TEXT("Favorites"), {0}, TEXT("shell32.dll"), 0}, // Favorites
  67. {TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_NETHOOD, TEXT("NetHood"), {0}, TEXT("shell32.dll"), 0}, // NetHood
  68. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PERSONAL, TEXT("Personal"), {0}, TEXT("shell32.dll"), 0}, // My Documents
  69. {TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PRINTHOOD, TEXT("PrintHood"), {0}, TEXT("shell32.dll"), 0}, // PrintHood
  70. {TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_RECENT, TEXT("Recent"), {0}, TEXT("shell32.dll"), 0}, // Recent
  71. {TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_SENDTO, TEXT("SendTo"), {0}, TEXT("shell32.dll"), 0}, // SendTo
  72. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_STARTMENU, TEXT("Start Menu"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_START_MENU}, // Start Menu
  73. {TRUE, FALSE, TRUE, TRUE, FALSE, IDS_SH_TEMPLATES, TEXT("Templates"), {0}, TEXT("shell32.dll"), 0}, // Templates
  74. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PROGRAMS, TEXT("Programs"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_PROGRAMS}, // Programs
  75. {FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_STARTUP, TEXT("Startup"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_STARTUP}, // Startup
  76. {TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_LOCALSETTINGS, TEXT("Local Settings"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_LOCALSETTINGS}, // Local Settings
  77. {TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_LOCALAPPDATA, TEXT("Local AppData"), {0}, TEXT("shell32.dll"), 0}, // Local AppData
  78. {TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_CACHE, TEXT("Cache"), {0}, TEXT("shell32.dll"), 0}, // Temporary Internet Files
  79. {TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_HISTORY, TEXT("History"), {0}, TEXT("shell32.dll"), 0}, // History
  80. {FALSE, TRUE, FALSE, TRUE, TRUE, IDS_SH_TEMP, TEXT("Temp"), {0}, TEXT("shell32.dll"), 0}, // Temp
  81. };
  82. FOLDER_INFO c_CommonShellFolders[] =
  83. {
  84. {FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_DESKTOP, TEXT("Common Desktop"), {0}, TEXT("shell32.dll"), 0}, // Common Desktop
  85. {FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_STARTMENU, TEXT("Common Start Menu"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_START_MENU}, // Common Start Menu
  86. {FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_PROGRAMS, TEXT("Common Programs"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_PROGRAMS}, // Common Programs
  87. {FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_STARTUP, TEXT("Common Startup"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_STARTUP}, // Common Startup
  88. {TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_APPDATA, TEXT("Common AppData"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_APP_DATA}, // Common Application Data
  89. {TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_TEMPLATES, TEXT("Common Templates"), {0}, TEXT("shell32.dll"), 0}, // Common Templates
  90. {FALSE, TRUE, TRUE, TRUE, FALSE, IDS_SH_FAVORITES, TEXT("Common Favorites"), {0}, TEXT("shell32.dll"), 0}, // Common Favorites
  91. {FALSE, TRUE, TRUE, TRUE, FALSE, IDS_SH_SHAREDDOCS, TEXT("Common Documents"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_SHARED_DOC}, // Common Documents
  92. };
  93. //
  94. // Function proto-types
  95. //
  96. void InitializeProductType (void);
  97. BOOL DetermineLocalSettingsLocation(LPTSTR szLocalSettings);
  98. //*************************************************************
  99. //
  100. // PatchLocalSettings()
  101. //
  102. // Purpose: Initializes the LocalSettingsFolder correctly
  103. //
  104. // Parameters: hInstance - DLL instance handle
  105. //
  106. // Return: void
  107. //
  108. // Comments:
  109. //
  110. // History: Date Author Comment
  111. // 10/13/95 ushaji Created
  112. //
  113. //
  114. // Comments:
  115. // Should remove this post NT5 and restructure to take care of the
  116. // NT4 Localisation Problems
  117. //
  118. //*************************************************************
  119. void PatchLocalAppData(HANDLE hToken)
  120. {
  121. TCHAR szLocalSettingsPath[MAX_PATH];
  122. TCHAR szLocalAppData[MAX_PATH];
  123. LPTSTR lpEnd = NULL, lpLocalAppDataFolder;
  124. HANDLE hTokenOld=NULL;
  125. HKEY hKeyRoot, hKey;
  126. DWORD dwIndex;
  127. if (!ImpersonateUser (hToken, &hTokenOld))
  128. return;
  129. if (RegOpenCurrentUser(KEY_READ, &hKeyRoot) == ERROR_SUCCESS) {
  130. if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  131. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  132. if (RegQueryValueEx (hKey, TEXT("Local AppData"), NULL, NULL,
  133. NULL, NULL) == ERROR_SUCCESS) {
  134. RegCloseKey(hKey);
  135. RegCloseKey(hKeyRoot);
  136. RevertToUser(&hTokenOld);
  137. return;
  138. }
  139. RegCloseKey(hKey);
  140. }
  141. RegCloseKey(hKeyRoot);
  142. }
  143. //
  144. // Impersonate and determine the user's localsettings
  145. //
  146. DetermineLocalSettingsLocation(szLocalSettingsPath);
  147. RevertToUser(&hTokenOld);
  148. lstrcpy(szLocalAppData, TEXT("%userprofile%"));
  149. //
  150. // Set the Local AppData Folder after %userprofile% so that we
  151. // we can update the global variable below.
  152. //
  153. lpEnd = lpLocalAppDataFolder = CheckSlash(szLocalAppData);
  154. lstrcat(szLocalAppData, szLocalSettingsPath);
  155. lpEnd = CheckSlash(szLocalAppData);
  156. LoadString(g_hDllInstance, IDS_SH_LOCALAPPDATA, lpEnd, MAX_FOLDER_SIZE);
  157. //
  158. // Construct the path and let it be set.
  159. //
  160. SetFolderPath(CSIDL_LOCAL_APPDATA | CSIDL_FLAG_DONT_UNEXPAND, hToken, szLocalAppData);
  161. //
  162. // the global variable should be reset by the time it gets used.
  163. // No Need to reset it here, but let us be safer.
  164. //
  165. for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++)
  166. if (c_ShellFolders[dwIndex].iFolderID == IDS_SH_LOCALAPPDATA)
  167. lstrcpy(c_ShellFolders[dwIndex].szFolderLocation, lpLocalAppDataFolder);
  168. }
  169. //*************************************************************
  170. //
  171. // InitializeGlobals()
  172. //
  173. // Purpose: Initializes all the globals variables
  174. // at DLL load time.
  175. //
  176. // Parameters: hInstance - DLL instance handle
  177. //
  178. // Return: void
  179. //
  180. // Comments:
  181. //
  182. // History: Date Author Comment
  183. // 10/13/95 ericflo Created
  184. //
  185. //*************************************************************
  186. void InitializeGlobals (HINSTANCE hInstance)
  187. {
  188. OSVERSIONINFO ver;
  189. DWORD dwIndex, dwSize, dwType;
  190. HKEY hKey, hKeyRoot;
  191. TCHAR szTemp[MAX_PATH];
  192. TCHAR szTemp2[MAX_PATH];
  193. TCHAR szTemp3[MAX_PATH];
  194. SECURITY_DESCRIPTOR sd;
  195. SECURITY_ATTRIBUTES sa;
  196. LPTSTR lpEnd;
  197. SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
  198. PACL pAcl = NULL;
  199. PSID pSidAdmin = NULL, pSidSystem = NULL;
  200. DWORD cbAcl;
  201. BOOL bDefaultSecurity = FALSE;
  202. //
  203. // Save the instance handle
  204. //
  205. g_hDllInstance = hInstance;
  206. //
  207. // Save the number of shell folders
  208. //
  209. g_dwNumShellFolders = ARRAYSIZE(c_ShellFolders);
  210. g_dwNumCommonShellFolders = ARRAYSIZE(c_CommonShellFolders);
  211. //
  212. // Query the build number
  213. //
  214. ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  215. GetVersionEx(&ver);
  216. g_dwBuildNumber = (DWORD) LOWORD(ver.dwBuildNumber);
  217. //
  218. // Initialize the product type
  219. //
  220. InitializeProductType ();
  221. //
  222. // Open the user profile setup event. This event is set to non-signalled
  223. // anytime the default user profile is being updated. This blocks
  224. // LoadUserProfile until the update is finished.
  225. //
  226. if (!g_hProfileSetup) {
  227. //
  228. // Get the system sid
  229. //
  230. if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
  231. 0, 0, 0, 0, 0, 0, 0, &pSidSystem)) {
  232. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize system sid. Error = %d"), GetLastError()));
  233. bDefaultSecurity = TRUE;
  234. goto DefaultSecurity;
  235. }
  236. //
  237. // Get the Admin sid
  238. //
  239. if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
  240. DOMAIN_ALIAS_RID_ADMINS, 0, 0,
  241. 0, 0, 0, 0, &pSidAdmin)) {
  242. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize admin sid. Error = %d"), GetLastError()));
  243. bDefaultSecurity = TRUE;
  244. goto DefaultSecurity;
  245. }
  246. cbAcl = (GetLengthSid (pSidSystem)) +
  247. (GetLengthSid (pSidAdmin)) +
  248. sizeof(ACL) +
  249. (2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
  250. pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
  251. if (!pAcl) {
  252. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to allocate memory for acl. Error = %d"), GetLastError()));
  253. bDefaultSecurity = TRUE;
  254. goto DefaultSecurity;
  255. }
  256. if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
  257. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize acl. Error = %d"), GetLastError()));
  258. bDefaultSecurity = TRUE;
  259. goto DefaultSecurity;
  260. }
  261. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSidSystem)) {
  262. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to add system ace. Error = %d"), GetLastError()));
  263. bDefaultSecurity = TRUE;
  264. goto DefaultSecurity;
  265. }
  266. if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSidAdmin)) {
  267. DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to add builtin admin ace. Error = %d"), GetLastError()));
  268. bDefaultSecurity = TRUE;
  269. goto DefaultSecurity;
  270. }
  271. //
  272. // Put together the security descriptor
  273. //
  274. InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
  275. SetSecurityDescriptorDacl (
  276. &sd,
  277. TRUE, // Dacl present
  278. pAcl, // Dacl
  279. FALSE // Not defaulted
  280. );
  281. DefaultSecurity:
  282. sa.nLength = sizeof(sa);
  283. sa.bInheritHandle = FALSE;
  284. if (bDefaultSecurity) {
  285. sa.lpSecurityDescriptor = NULL;
  286. }
  287. else {
  288. sa.lpSecurityDescriptor = &sd;
  289. }
  290. g_hProfileSetup = CreateEvent (&sa, TRUE, TRUE, USER_PROFILE_SETUP_EVENT);
  291. if (!g_hProfileSetup) {
  292. DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: Failed to create profile setup event with %d"), GetLastError()));
  293. }
  294. if (pAcl) {
  295. GlobalFree (pAcl);
  296. }
  297. if (pSidSystem) {
  298. FreeSid(pSidSystem);
  299. }
  300. if (pSidAdmin) {
  301. FreeSid(pSidAdmin);
  302. }
  303. }
  304. //
  305. // Now load the directory names that match
  306. // the special folders
  307. //
  308. for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++) {
  309. LoadString(hInstance, c_ShellFolders[dwIndex].iFolderID,
  310. c_ShellFolders[dwIndex].szFolderLocation, MAX_FOLDER_SIZE);
  311. }
  312. for (dwIndex = 0; dwIndex < g_dwNumCommonShellFolders; dwIndex++) {
  313. LoadString(hInstance, c_CommonShellFolders[dwIndex].iFolderID,
  314. c_CommonShellFolders[dwIndex].szFolderLocation, MAX_FOLDER_SIZE);
  315. }
  316. //
  317. // Special case for the Personal / My Documents folder. NT4 used a folder
  318. // called "Personal" for document storage. NT5 renamed this folder to
  319. // My Documents. In the upgrade case from NT4 to NT5, if the user already
  320. // had information in "Personal", that name was preserved (for compatibility
  321. // reasons) and the My Pictures folder is created inside of Personal.
  322. // We need to make sure and fix up the My Documents and My Pictures entries
  323. // in the global array so they have the correct directory names.
  324. //
  325. if (RegOpenCurrentUser(KEY_READ, &hKeyRoot) == ERROR_SUCCESS) {
  326. if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
  327. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  328. dwSize = sizeof(szTemp3);
  329. szTemp3[0] = TEXT('\0');
  330. if (RegQueryValueEx (hKey, TEXT("Personal"), NULL, &dwType,
  331. (LPBYTE) szTemp3, &dwSize) == ERROR_SUCCESS) {
  332. LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2));
  333. lstrcpy (szTemp, TEXT("%USERPROFILE%\\"));
  334. lstrcat (szTemp, szTemp2);
  335. if (lstrcmpi(szTemp, szTemp3) == 0) {
  336. LoadString(hInstance, IDS_SH_PERSONAL2,
  337. c_ShellFolders[5].szFolderLocation, MAX_FOLDER_SIZE);
  338. }
  339. }
  340. //
  341. // Special Case for Local Settings.
  342. // Due to localisations LocalSettings can be pointing to different places in nt4 and rc might
  343. // not be in sync with the current value. Read the LocalSettings value first and then
  344. // update everything else afterwards.
  345. //
  346. dwSize = sizeof(szTemp2);
  347. *szTemp = *szTemp2 = TEXT('\0');
  348. //
  349. // Read the value from the registry if it is available
  350. //
  351. if (RegQueryValueEx (hKey, TEXT("Local Settings"), NULL, &dwType,
  352. (LPBYTE) szTemp2, &dwSize) != ERROR_SUCCESS) {
  353. //
  354. // if the value is not present load it from the rc file
  355. //
  356. LoadString(hInstance, IDS_SH_LOCALSETTINGS, szTemp, MAX_FOLDER_SIZE);
  357. DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder from the rc is %s"), szTemp));
  358. }
  359. else {
  360. //
  361. // The registry value read from the registry is the full unexpanded path.
  362. //
  363. if (lstrlen(szTemp2) > lstrlen(TEXT("%userprofile%"))) {
  364. lstrcpy(szTemp, szTemp2+(lstrlen(TEXT("%userprofile%"))+1));
  365. DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder from the reigtry is %s"), szTemp));
  366. }
  367. else {
  368. LoadString(hInstance, IDS_SH_LOCALSETTINGS, szTemp, MAX_FOLDER_SIZE);
  369. DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder(2) from the rc is %s"), szTemp));
  370. }
  371. }
  372. lpEnd = CheckSlash(szTemp);
  373. for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++) {
  374. //
  375. // Fix up all LocalSettings related shfolders
  376. //
  377. if (lstrcmpi(c_ShellFolders[dwIndex].lpFolderName, TEXT("Local Settings")) == 0) {
  378. *lpEnd = TEXT('\0');
  379. //
  380. // Don't copy the final slash
  381. //
  382. lstrcpyn(c_ShellFolders[dwIndex].szFolderLocation, szTemp, lstrlen(szTemp));
  383. }
  384. if (c_ShellFolders[dwIndex].bLocalSettings) {
  385. LoadString(hInstance, c_ShellFolders[dwIndex].iFolderID,
  386. szTemp3, MAX_FOLDER_SIZE);
  387. //
  388. // Append localsetting value read above to the end of %userprofile%
  389. // before putting on the shell folder itself
  390. //
  391. lstrcpy(lpEnd, szTemp3);
  392. lstrcpy(c_ShellFolders[dwIndex].szFolderLocation, szTemp);
  393. DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: Shell folder %s is %s"), c_ShellFolders[dwIndex].lpFolderName,
  394. c_ShellFolders[dwIndex].szFolderLocation));
  395. }
  396. }
  397. RegCloseKey (hKey);
  398. }
  399. RegCloseKey (hKeyRoot);
  400. }
  401. //
  402. // Get string version of registry extension guid
  403. //
  404. GuidToString( &guidRegistryExt, c_szRegistryExtName );
  405. }
  406. //*************************************************************
  407. //
  408. // InitializeProductType()
  409. //
  410. // Purpose: Determines the current product type and
  411. // sets the g_ProductType global variable.
  412. //
  413. // Parameters: void
  414. //
  415. // Return: void
  416. //
  417. // Comments:
  418. //
  419. // History: Date Author Comment
  420. // 4/08/96 ericflo Created
  421. //
  422. //*************************************************************
  423. void InitializeProductType (void)
  424. {
  425. #ifdef WINNT
  426. HKEY hkey;
  427. LONG lResult;
  428. TCHAR szProductType[50];
  429. DWORD dwType, dwSize;
  430. //
  431. // Default product type is workstation.
  432. //
  433. g_ProductType = PT_WORKSTATION;
  434. //
  435. // Query the registry for the product type.
  436. //
  437. lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  438. TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
  439. 0,
  440. KEY_READ,
  441. &hkey);
  442. if (lResult != ERROR_SUCCESS) {
  443. DebugMsg((DM_WARNING, TEXT("InitializeProductType: Failed to open registry (%d)"), lResult));
  444. goto Exit;
  445. }
  446. dwSize = 50;
  447. szProductType[0] = TEXT('\0');
  448. lResult = RegQueryValueEx (hkey,
  449. TEXT("ProductType"),
  450. NULL,
  451. &dwType,
  452. (LPBYTE) szProductType,
  453. &dwSize);
  454. RegCloseKey (hkey);
  455. if (lResult != ERROR_SUCCESS) {
  456. DebugMsg((DM_WARNING, TEXT("InitializeProductType: Failed to query product type (%d)"), lResult));
  457. goto Exit;
  458. }
  459. //
  460. // Map the product type string to the enumeration value.
  461. //
  462. if (!lstrcmpi (szProductType, TEXT("WinNT"))) {
  463. g_ProductType = PT_WORKSTATION;
  464. } else if (!lstrcmpi (szProductType, TEXT("ServerNT"))) {
  465. g_ProductType = PT_SERVER;
  466. } else if (!lstrcmpi (szProductType, TEXT("LanmanNT"))) {
  467. g_ProductType = PT_DC;
  468. } else {
  469. DebugMsg((DM_WARNING, TEXT("InitializeProductType: Unknown product type! <%s>"), szProductType));
  470. }
  471. Exit:
  472. DebugMsg((DM_VERBOSE, TEXT("InitializeProductType: Product Type: %d"), g_ProductType));
  473. #else // WINNT
  474. //
  475. // Windows only has 1 product type
  476. //
  477. g_ProductType = PT_WINDOWS;
  478. #endif
  479. }