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.

616 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT4.0
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: MdmShrUp.C
  7. //
  8. // Contents: OEM DLL for Modem sharing upgrade from NT4 to NT5 (Server/Client)
  9. //
  10. // Notes:
  11. //
  12. // Author: erany 18-May-98
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <tchar.h>
  18. #include <setupapi.h> // For HINF definition
  19. #include <oemupgex.h>
  20. #define CLIENT_HIVE_FILE L"\\C_MdmShr"
  21. #define SERVER_HIVE_FILE L"\\S_MdmShr"
  22. #define CLIENT_NT5_SYSTEM_NAME L"MS_SERRDR"
  23. //----------------------------------------------------------------------------
  24. // Prototypes:
  25. //----------------------------------------------------------------------------
  26. // Reads NT4 registry and stores in a file
  27. LONG RegistryToFile (HKEY hKeyParams, PCWSTR szConfigFile);
  28. // Reads a file and stores in NT5 registry
  29. LONG FileToRegistry (HKEY hKeyParams, PCWSTR szConfigFile);
  30. // Sets privilege in an access token
  31. LONG SetSpecificPrivilegeInAccessToken (PCWSTR lpwcsPrivType, BOOL bEnabled);
  32. // Display detailed error message in a message box
  33. LONG DisplayErrorMsg (HWND hParent,
  34. PCWSTR szOperation,
  35. BOOL bIsClient,
  36. LONG lErrCode);
  37. // Display debug message
  38. void DebugMsg (PCWSTR lpStr);
  39. // Copy constant vendor info into a buffer
  40. void FillVendorInfo (VENDORINFO* pviVendorInfo);
  41. //----------------------------------------------------------------------------
  42. // Globals:
  43. //----------------------------------------------------------------------------
  44. // Registry hive dump file name (client)
  45. WCHAR g_szClientConfigFile[MAX_PATH];
  46. // Registry hive dump file name (server)
  47. WCHAR g_szServerConfigFile[MAX_PATH];
  48. // OEM Working directory
  49. WCHAR g_szOEMDir[MAX_PATH];
  50. // Vendor information constants
  51. WCHAR g_szConstCompanyName[] = L"Microsoft";
  52. WCHAR g_szConstSupportNumber[] = L"<Place microsoft support phone number here>";
  53. WCHAR g_szConstSupportUrl[] = L"<Place microsoft support URL here>";
  54. WCHAR g_szConstInstructionsToUser[] = L"<Place instructions to user here>";
  55. //----------------------------------------------------------------------------
  56. // DLL exports:
  57. //----------------------------------------------------------------------------
  58. //+---------------------------------------------------------------------------
  59. //
  60. // Function: DllMain
  61. //
  62. // Purpose: DLL entry and exit point
  63. //
  64. // Arguments:
  65. // hInst [in] Handle of process instance
  66. // ul_reason_for_call [in] Reason for function call
  67. // lpReserved [out] reserved
  68. //
  69. // Returns: TRUE in case of success.
  70. //
  71. // Author: erany 5-May-98
  72. //
  73. // Notes:
  74. // Does nothing. Always returns TRUE.
  75. //
  76. BOOL WINAPI DllMain (HANDLE hInst,
  77. ULONG ul_reason_for_call,
  78. LPVOID lpReserved)
  79. {
  80. return TRUE;
  81. }
  82. //----------------------------------------------------------------------------
  83. // DLL exports - Windows NT 4 stage:
  84. //----------------------------------------------------------------------------
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Function: PreUpgradeInitialize
  88. //
  89. // Purpose: Intialize OEM DLL
  90. //
  91. // Arguments:
  92. // szWorkingDir [in] name of temporary directory to be used
  93. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo structure
  94. // szProductId [out] Description of component being upgraded - NOT IN USE
  95. // pviVendorInfo [out] information about OEM
  96. // pvReserved [out] reserved
  97. //
  98. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  99. //
  100. // Author: erany 5-May-98
  101. //
  102. // Notes:
  103. // This function is called before any other function in this dll.
  104. // The main purpose of calling this function is to obtain
  105. // identification information and to allow the DLL to initialize
  106. // its internal data
  107. //
  108. EXTERN_C LONG __stdcall
  109. PreUpgradeInitialize(IN PCWSTR szWorkingDir,
  110. IN NetUpgradeInfo* pNetUpgradeInfo,
  111. OUT VENDORINFO* pviVendorInfo,
  112. OUT DWORD* pdwFlags,
  113. OUT NetUpgradeData* pNetUpgradeData)
  114. {
  115. FillVendorInfo (pviVendorInfo);
  116. *pdwFlags = 0; // No special flags
  117. // Create registry hive file name for the client:
  118. wcscpy (g_szOEMDir, szWorkingDir); // Save config path
  119. wcscpy (g_szClientConfigFile, szWorkingDir); // Save registry dump full path
  120. wcscat (g_szClientConfigFile, CLIENT_HIVE_FILE);
  121. // Create registry hive file name for the server:
  122. wcscpy (g_szServerConfigFile, szWorkingDir); // Save registry dump full path
  123. wcscat (g_szServerConfigFile, SERVER_HIVE_FILE);
  124. #ifdef _DEBUG // Test code:
  125. {
  126. WCHAR dbgMsg[2048];
  127. _stprintf (dbgMsg,
  128. L"PreUpgradeInitialize called.\nszClientConfigFile=%s\nszServerConfigFile=%s",
  129. g_szClientConfigFile, g_szServerConfigFile);
  130. DebugMsg (dbgMsg);
  131. }
  132. #endif // End of test code
  133. return ERROR_SUCCESS;
  134. }
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Function: DoPreUpgradeProcessing
  138. //
  139. // Purpose: Intialize OEM DLL
  140. //
  141. // Arguments:
  142. // hParentWindow [in] window handle for showing UI
  143. // hkeyParams [in] handle to parameters key in registry
  144. // szPreNT5InfId [in] pre-NT5 InfID
  145. // szPreNT5Instance [in] pre-NT5 instance name
  146. // szNT5InfId [in] NT5 InfId
  147. // szSectionName [in] section name to be used for writing info
  148. // dwFlags [out] flags
  149. // pvReserve [in] reserved
  150. //
  151. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  152. //
  153. // Author: erany 5-May-98
  154. //
  155. // Notes:
  156. // This function is called once per component to be upgraded.
  157. //
  158. EXTERN_C LONG __stdcall
  159. DoPreUpgradeProcessing(IN HWND hParentWindow,
  160. IN HKEY hkeyParams,
  161. IN PCWSTR szPreNT5InfId,
  162. IN PCWSTR szPreNT5Instance,
  163. IN PCWSTR szNT5InfId,
  164. IN PCWSTR szSectionName,
  165. OUT VENDORINFO* pviVendorInfo,
  166. OUT DWORD* pdwFlags,
  167. IN LPVOID pvReserved)
  168. {
  169. LONG lRes;
  170. //WCHAR szLine[MAX_PATH];
  171. BOOL bIsClient = FALSE; // Is this a client upgrade ?
  172. *pdwFlags = NUA_LOAD_POST_UPGRADE; // Ask to be activated in post stage (GUI NT5)
  173. FillVendorInfo (pviVendorInfo);
  174. if (!_wcsicmp(szNT5InfId, CLIENT_NT5_SYSTEM_NAME))
  175. bIsClient=TRUE; // Client is being upgraded now
  176. #ifdef _DEBUG // Test code:
  177. {
  178. WCHAR dbgMsg[2048];
  179. WCHAR key[1024];
  180. RegEnumKey (hkeyParams,0,key,MAX_PATH);
  181. _stprintf (dbgMsg,
  182. L"DoPreUpgradeProcessing called: 1st key=%s\n"
  183. L"PreNT5InfId=%s\n"
  184. L"PreNT5Instance=%s\n"
  185. L"NT5InfId=%s\n"
  186. L"SectionName=%s",key, szPreNT5InfId, szPreNT5Instance, szNT5InfId, szSectionName);
  187. DebugMsg (dbgMsg);
  188. }
  189. #endif // End of test code
  190. // Dump registry hive to a file
  191. lRes = RegistryToFile (hkeyParams,
  192. bIsClient ? g_szClientConfigFile : g_szServerConfigFile);
  193. if (lRes != ERROR_SUCCESS) // Error dumping our registry section to a file
  194. return DisplayErrorMsg (hParentWindow,
  195. L"attempting to save registry section to a file",
  196. bIsClient,
  197. lRes);
  198. return ERROR_SUCCESS;
  199. }
  200. //----------------------------------------------------------------------------
  201. // DLL exports - Windows NT 5 stage:
  202. //----------------------------------------------------------------------------
  203. //+---------------------------------------------------------------------------
  204. //
  205. // Function: PostUpgradeInitialize
  206. //
  207. // Purpose: Intialize OEM DLL during GUI mode setup
  208. //
  209. // Arguments:
  210. // szWorkingDir [in] name of temporary directory to be used
  211. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo structure
  212. // szProductId [out] Description of component being upgraded - NOT IN USE
  213. // pviVendorInfo [out] information about OEM
  214. // pvReserved [out] reserved
  215. //
  216. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  217. //
  218. // Author: erany 5-May-98
  219. //
  220. // Notes:
  221. // This function is called in GUI mode setup before
  222. // any other function in this dll .
  223. // The main purpose of calling this function is to obtain
  224. // identification information and to allow the DLL to initialize
  225. // its internal data
  226. //
  227. EXTERN_C LONG __stdcall
  228. PostUpgradeInitialize(IN PCWSTR szWorkingDir,
  229. IN NetUpgradeInfo* pNetUpgradeInfo,
  230. //OUT PCWSTR* szProductId,
  231. OUT VENDORINFO* pviVendorInfo,
  232. OUT LPVOID pvReserved)
  233. {
  234. FillVendorInfo (pviVendorInfo);
  235. // Create registry hive file name for the client:
  236. wcscpy (g_szOEMDir, szWorkingDir); // Save config path
  237. wcscpy (g_szClientConfigFile, szWorkingDir); // Save registry dump full path
  238. wcscat (g_szClientConfigFile, CLIENT_HIVE_FILE);
  239. // Create registry hive file name for the server:
  240. wcscpy (g_szServerConfigFile, szWorkingDir); // Save registry dump full path
  241. wcscat (g_szServerConfigFile, SERVER_HIVE_FILE);
  242. #ifdef _DEBUG // Test code:
  243. {
  244. WCHAR dbgMsg[MAX_PATH*2];
  245. _stprintf (dbgMsg,
  246. L"PostUpgradeInitialize called.\nszClientConfigFile=%s\nszServerConfigFile=%s",
  247. g_szClientConfigFile, g_szServerConfigFile);
  248. DebugMsg (dbgMsg);
  249. }
  250. #endif // End of test code
  251. return ERROR_SUCCESS;
  252. }
  253. //+---------------------------------------------------------------------------
  254. //
  255. // Function: DoPostUpgradeProcessing
  256. //
  257. // Purpose: Intialize OEM DLL
  258. //
  259. // Arguments:
  260. // hParentWindow [in] window handle for showing UI
  261. // hkeyParams [in] handle to parameters key in registry
  262. // szPreNT5InfId [in] pre-NT5 InfID
  263. // szPreNT5Instance [in] pre-NT5 instance name
  264. // szNT5InfId [in] NT5 InfId
  265. // hinfAnswerFile [in] handle to answer-file
  266. // szSectionName [in] name of section having component parameters
  267. // pvReserve [in] reserved
  268. //
  269. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  270. //
  271. // Author: erany 5-May-98
  272. //
  273. // Notes:
  274. // This function is called once per component upgraded.
  275. //
  276. EXTERN_C LONG __stdcall
  277. DoPostUpgradeProcessing(IN HWND hParentWindow,
  278. IN HKEY hkeyParams,
  279. IN PCWSTR szPreNT5Instance,
  280. IN PCWSTR szNT5InfId,
  281. IN HINF hinfAnswerFile,
  282. IN PCWSTR szSectionName,
  283. OUT VENDORINFO* pviVendorInfo,
  284. IN LPVOID pvReserved)
  285. {
  286. LONG lRes;
  287. BOOL bIsClient = FALSE; // Is this a client upgrade ?
  288. if (!_wcsicmp(szNT5InfId, CLIENT_NT5_SYSTEM_NAME))
  289. bIsClient=TRUE; // Client is being upgraded now
  290. FillVendorInfo (pviVendorInfo);
  291. #ifdef _DEBUG // Test code:
  292. {
  293. WCHAR dbgMsg[MAX_PATH*4];
  294. WCHAR key[MAX_PATH];
  295. RegEnumKey (hkeyParams,0,key,MAX_PATH);
  296. _stprintf (dbgMsg,
  297. L"DoPostUpgradeProcessing called: 1st key=%s\n"
  298. L"PreNT5Instance=%s\n"
  299. L"NT5InfId=%s\n"
  300. L"SectionName=%s",key, szPreNT5Instance, szNT5InfId, szSectionName);
  301. DebugMsg (dbgMsg);
  302. }
  303. #endif // End of test code
  304. // read back registry hive from the dump file
  305. lRes = FileToRegistry (hkeyParams,
  306. bIsClient ? g_szClientConfigFile : g_szServerConfigFile);
  307. if (lRes != ERROR_SUCCESS) // Error dumping our registry section to a file
  308. return DisplayErrorMsg (hParentWindow,
  309. L"attempting to read registry section from a file",
  310. bIsClient,
  311. lRes);
  312. return ERROR_SUCCESS;
  313. }
  314. //+---------------------------------------------------------------------------
  315. //
  316. // Function: RegistryToFile
  317. //
  318. // Purpose: Reads NT4 registry and stores in a file
  319. //
  320. // Arguments:
  321. // hKeyParames [in] handle to parameters key in registry
  322. // szConfigFile [in] Name of configuration file
  323. //
  324. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  325. //
  326. // Author: erany 10-March-98
  327. //
  328. // Notes:
  329. // This function is called once per component upgraded.
  330. // It recursively calls itself (with an open file handle)
  331. // for every registry key it meets.
  332. //
  333. LONG RegistryToFile (HKEY hKeyParams, PCWSTR szConfigFile)
  334. {
  335. LONG lRes;
  336. if (!DeleteFile (szConfigFile) && GetLastError() != ERROR_FILE_NOT_FOUND)
  337. {
  338. //
  339. // The hive file is there but I can't delete it
  340. //
  341. return GetLastError();
  342. }
  343. lRes = SetSpecificPrivilegeInAccessToken (SE_BACKUP_NAME, TRUE);
  344. if (lRes != ERROR_SUCCESS)
  345. {
  346. return lRes;
  347. }
  348. lRes = RegSaveKey (hKeyParams, szConfigFile, NULL);
  349. SetSpecificPrivilegeInAccessToken (SE_BACKUP_NAME, FALSE);
  350. return lRes;
  351. }
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Function: FileToRegistry
  355. //
  356. // Purpose: Reads a file and stores in NT5 registry
  357. //
  358. // Arguments:
  359. // hKeyParames [in] handle to parameters key in registry
  360. // szConfigFile [in] Name of configuration file
  361. //
  362. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  363. //
  364. // Author: erany 10-March-98
  365. //
  366. // Notes:
  367. // This function is called once per component upgraded (in NT5 GUI mode).
  368. // It recursively calls itself (with an open file handle)
  369. // for every registry key it meets.
  370. //
  371. LONG FileToRegistry (HKEY hKeyParams, PCWSTR szConfigFile)
  372. {
  373. LONG lRes;
  374. lRes = SetSpecificPrivilegeInAccessToken (SE_RESTORE_NAME, TRUE);
  375. if (lRes != ERROR_SUCCESS)
  376. {
  377. return lRes;
  378. }
  379. lRes = RegRestoreKey (hKeyParams, szConfigFile, 0);
  380. SetSpecificPrivilegeInAccessToken (SE_RESTORE_NAME, FALSE);
  381. return lRes;
  382. }
  383. //+---------------------------------------------------------------------------
  384. //
  385. // Function: SetSpecificPrivilegeInAccessToken
  386. //
  387. // Purpose: Sets a privilege in an access token
  388. //
  389. // Arguments:
  390. // lpwcsPrivType [in] Type of privilege
  391. // bEnabled [in] Enable / Disable flag
  392. //
  393. // Returns: ERROR_SUCCESS in case of success, win32 error otherwise
  394. //
  395. // Author: erany 10-March-98
  396. //
  397. // Notes:
  398. // Copied from an example by boazf
  399. //
  400. LONG SetSpecificPrivilegeInAccessToken (PCWSTR lpwcsPrivType, BOOL bEnabled)
  401. {
  402. LUID luidPrivilegeLUID;
  403. TOKEN_PRIVILEGES tpTokenPrivilege;
  404. HANDLE hAccessToken;
  405. BOOL bRet;
  406. //
  407. // 1st, Try to get a handle to the current thread.
  408. // If not successful, get a handle to the current process token.
  409. //
  410. if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, TRUE, &hAccessToken) &&
  411. !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hAccessToken))
  412. return GetLastError ();
  413. //
  414. // Get the LUID of the privilege.
  415. //
  416. if (!LookupPrivilegeValue(NULL,
  417. lpwcsPrivType,
  418. &luidPrivilegeLUID))
  419. {
  420. CloseHandle(hAccessToken);
  421. return GetLastError ();
  422. }
  423. //
  424. // Enable/Disable the privilege.
  425. //
  426. tpTokenPrivilege.PrivilegeCount = 1;
  427. tpTokenPrivilege.Privileges[0].Luid = luidPrivilegeLUID;
  428. tpTokenPrivilege.Privileges[0].Attributes = bEnabled ?SE_PRIVILEGE_ENABLED : 0;
  429. bRet = AdjustTokenPrivileges (hAccessToken,
  430. FALSE, // Do not disable all
  431. &tpTokenPrivilege,
  432. sizeof(TOKEN_PRIVILEGES),
  433. NULL, // Ignore previous info
  434. NULL); // Ignore previous info
  435. //
  436. // Free the process token.
  437. //
  438. CloseHandle(hAccessToken);
  439. if (!bRet)
  440. return GetLastError();
  441. return ERROR_SUCCESS;
  442. }
  443. //+---------------------------------------------------------------------------
  444. //
  445. // Function: DisplayErrorMsg
  446. //
  447. // Purpose: Displays a detailed error mesaage in a message box
  448. //
  449. // Arguments:
  450. // hParent [in] Window hanlde of parent window
  451. // szOperation [in] Description of operation that caused error
  452. // bIsClient [in] Did it happend while upgrading modem sharing client?
  453. // lErrCode [in] Win32 error code
  454. //
  455. // Returns: lErrCode unchanged
  456. //
  457. // Author: erany 10-March-98
  458. //
  459. // Notes:
  460. // Returns the input error code unchanged.
  461. //
  462. LONG DisplayErrorMsg (HWND hParent,
  463. PCWSTR szOperation,
  464. BOOL bIsClient,
  465. LONG lErrCode)
  466. {
  467. WCHAR szMsg[256],
  468. szHdr[256];
  469. PWSTR lpszError=NULL;
  470. BOOL bGotErrorDescription = TRUE;
  471. //
  472. // Create message box title
  473. //
  474. _stprintf (szHdr,L"Modem sharing %s NT5 upgrade",
  475. bIsClient ? L"client" : L"server");
  476. // Create descriptive error text
  477. if (0 == FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  478. FORMAT_MESSAGE_FROM_SYSTEM,
  479. NULL,
  480. lErrCode,
  481. 0,
  482. lpszError,
  483. 0,
  484. NULL))
  485. {
  486. //
  487. // Failure to format the message
  488. //
  489. bGotErrorDescription = FALSE;
  490. }
  491. if (bGotErrorDescription)
  492. {
  493. //
  494. // We successfully created a descriptive error string from the error code
  495. //
  496. _stprintf (szMsg, L"Error while %s.\n%s.", szOperation, lpszError);
  497. }
  498. else
  499. {
  500. //
  501. // We failed to created a descriptive error string from the error code
  502. //
  503. _stprintf (szMsg, L"Error while %s.\nError code: %ld.", szOperation, lErrCode);
  504. }
  505. MessageBox (hParent, szMsg, szHdr, MB_OK | MB_ICONSTOP);
  506. if (bGotErrorDescription)
  507. {
  508. LocalFree (lpszError);
  509. }
  510. return lErrCode;
  511. }
  512. //+---------------------------------------------------------------------------
  513. //
  514. // Function: FillVendorInfo
  515. //
  516. // Purpose: Fills global constant strings into the vendor info buffer.
  517. //
  518. // Arguments:
  519. // pviVendorInfo [out] Points to vendor info buffer
  520. //
  521. // Returns: None.
  522. //
  523. // Author: erany 10-March-98
  524. //
  525. // Notes:
  526. // Consts are global, they effect all calls.
  527. //
  528. void FillVendorInfo (VENDORINFO* pviVendorInfo)
  529. {
  530. wcscpy (pviVendorInfo->szCompanyName, g_szConstCompanyName);
  531. wcscpy (pviVendorInfo->szSupportNumber, g_szConstSupportNumber);
  532. wcscpy (pviVendorInfo->szSupportUrl, g_szConstSupportUrl);
  533. wcscpy (pviVendorInfo->szInstructionsToUser, g_szConstInstructionsToUser);
  534. }
  535. //+---------------------------------------------------------------------------
  536. //
  537. // Function: DebugMsg
  538. //
  539. // Purpose: Displays a debug message to the debugger
  540. //
  541. // Arguments:
  542. // lpStr [in] String to output
  543. //
  544. // Returns: None.
  545. //
  546. // Author: erany 14-July-98
  547. //
  548. //
  549. void DebugMsg (PCWSTR lpStr)
  550. {
  551. static PCWSTR szDbgHeader =
  552. L"-------------------- Modem sharing client / server upgrade DLL --------------------\n";
  553. OutputDebugString (szDbgHeader);
  554. OutputDebugString (lpStr);
  555. OutputDebugString (L"\n");
  556. OutputDebugString (szDbgHeader);
  557. OutputDebugString (L"\n");
  558. }