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.

1258 lines
39 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. ras.c
  5. Abstract:
  6. ras.c runs as a part of w95upg.dll in winnt32.exe during Win9x migrations.
  7. Saves connectoid information for later retrieval during Guimode setup.
  8. Author:
  9. Marc R. Whitten (marcw) 23-Nov-1997
  10. Revision History:
  11. Marc R. Whitten marcw 23-Jul-1998 - Major cleanup.
  12. Jeff Sigman 09-Apr-2001 - Whistler cleanup.
  13. Whistler bugs:
  14. 34270 Win9x: Upgrade: Require Data Encryption setting for VPN
  15. connections is not migrated
  16. 125693 UpgLab9x: DUN Connectoids don't migrate selected modem properly
  17. from Win9x
  18. 208318 Win9x Upg: Username and Password for DUN connectoid not migrated
  19. from Win9x to Whistler
  20. --*/
  21. #include "pch.h"
  22. #include "sysmigp.h"
  23. //
  24. // Macros
  25. //
  26. #define PAESMMCFG(pAE) ((PSMMCFG)(((PBYTE)pAE)+(pAE->uOffSMMCfg)))
  27. #define PAESMM(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffSMM)))
  28. #define PAEDI(pAE) ((PDEVICEINFO)(((PBYTE)pAE)+(pAE->uOffDI )))
  29. #define PAEAREA(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffArea)))
  30. #define PAEPHONE(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffPhone)))
  31. #define DECRYPTENTRY(x, y, z) EnDecryptEntry(x, (LPBYTE)y, z)
  32. typedef LPVOID HPWL;
  33. typedef HPWL* LPHPWL;
  34. typedef struct {
  35. DWORD Size;
  36. DWORD Unknown1;
  37. DWORD ModemUiOptions; // num seconds in high byte.
  38. DWORD Unknown3; // 0 = Not Set.
  39. DWORD Unknown4;
  40. DWORD Unknown5;
  41. DWORD ConnectionSpeed;
  42. DWORD UnknownFlowControlData; //Somehow related to flow control.
  43. DWORD Unknown8;
  44. DWORD Unknown9;
  45. DWORD Unknown10;
  46. DWORD Unknown11;
  47. DWORD Unknown12;
  48. DWORD Unknown13;
  49. DWORD Unknown14;
  50. DWORD Unknown15;
  51. DWORD Unknown16;
  52. DWORD Unknown17;
  53. DWORD Unknown18;
  54. DWORD dwCallSetupFailTimer; // Num seconds to wait before cancel if not
  55. // connected. (0xFF equals off.)
  56. DWORD dwInactivityTimeout; // 0 = Not Set.
  57. DWORD Unknown21;
  58. DWORD SpeakerVolume; // 0|1
  59. DWORD ConfigOptions;
  60. DWORD Unknown24;
  61. DWORD Unknown25;
  62. DWORD Unknown26;
  63. } MODEMDEVINFO, *PMODEMDEVINFO;
  64. DEFINE_GUID(GUID_DEVCLASS_MODEM,
  65. 0x4d36e96dL, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 );
  66. //
  67. // Globals
  68. //
  69. POOLHANDLE g_RasPool;
  70. BOOL g_RasInstalled = FALSE;
  71. BOOL g_MultilinkEnabled;
  72. HINSTANCE g_RasApi32 = NULL;
  73. DWORD (* g_RnaGetDefaultAutodialConnection) (
  74. LPBYTE lpBuf,
  75. DWORD cb,
  76. LPDWORD lpdwOptions
  77. );
  78. //
  79. // Routines and structures for dealing with the Addresses\<entry> blob..
  80. //
  81. // AddrEntry serves as a header for the entire block of data in the <entry>
  82. // blob. entries in it are offsets to the strings which follow it..in many
  83. // cases (i.e. all of the *Off* members...)
  84. //
  85. typedef struct _AddrEntry {
  86. DWORD dwVersion;
  87. DWORD dwCountryCode;
  88. UINT uOffArea;
  89. UINT uOffPhone;
  90. DWORD dwCountryID;
  91. UINT uOffSMMCfg;
  92. UINT uOffSMM;
  93. UINT uOffDI;
  94. } ADDRENTRY, *PADDRENTRY;
  95. typedef struct _SubConnEntry {
  96. DWORD dwSize;
  97. DWORD dwFlags;
  98. char szDeviceType[RAS_MaxDeviceType+1];
  99. char szDeviceName[RAS_MaxDeviceName+1];
  100. char szLocal[RAS_MaxPhoneNumber+1];
  101. } SUBCONNENTRY, *PSUBCONNENTRY;
  102. typedef struct _IPData {
  103. DWORD dwSize;
  104. DWORD fdwTCPIP;
  105. DWORD dwIPAddr;
  106. DWORD dwDNSAddr;
  107. DWORD dwDNSAddrAlt;
  108. DWORD dwWINSAddr;
  109. DWORD dwWINSAddrAlt;
  110. } IPDATA, *PIPDATA;
  111. typedef struct _DEVICEINFO {
  112. DWORD dwVersion;
  113. UINT uSize;
  114. char szDeviceName[RAS_MaxDeviceName+1];
  115. char szDeviceType[RAS_MaxDeviceType+1];
  116. } DEVICEINFO, *PDEVICEINFO;
  117. typedef struct _SMMCFG {
  118. DWORD dwSize;
  119. DWORD fdwOptions;
  120. DWORD fdwProtocols;
  121. } SMMCFG, *PSMMCFG;
  122. static BYTE NEAR PASCAL GenerateEncryptKey (LPSTR szKey)
  123. {
  124. BYTE bKey;
  125. LPBYTE lpKey;
  126. for (bKey = 0, lpKey = (LPBYTE)szKey; *lpKey != 0; lpKey++)
  127. {
  128. bKey += *lpKey;
  129. };
  130. return bKey;
  131. }
  132. DWORD NEAR PASCAL
  133. EnDecryptEntry (
  134. LPSTR szEntry,
  135. LPBYTE lpEnt,
  136. DWORD cb
  137. )
  138. {
  139. BYTE bKey;
  140. //
  141. // Generate the encryption key from the entry name
  142. //
  143. bKey = GenerateEncryptKey(szEntry);
  144. //
  145. // Encrypt the address entry one byte at a time
  146. //
  147. for (;cb > 0; cb--, lpEnt++)
  148. {
  149. *lpEnt ^= bKey;
  150. };
  151. return ERROR_SUCCESS;
  152. }
  153. //
  154. // Find out if current connection is the default connection for current user
  155. //
  156. // Whistler 417479 RAS upgrade code does not migrate the default
  157. // internet connection setting from WinME to XP
  158. //
  159. BOOL
  160. IsDefInternetCon(
  161. IN PCTSTR szEntry
  162. )
  163. {
  164. BOOL bRet = FALSE;
  165. if (g_RnaGetDefaultAutodialConnection && szEntry)
  166. {
  167. DWORD dwAutodialOptions;
  168. UCHAR szDefEntry[MAX_PATH + 1];
  169. //
  170. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,Domain,
  171. // Passwrds to not be migrated for DUN
  172. //
  173. if (!g_RnaGetDefaultAutodialConnection(szDefEntry, MAX_PATH,
  174. &dwAutodialOptions) && StringIMatch (szEntry, szDefEntry))
  175. {
  176. bRet = TRUE;
  177. }
  178. }
  179. return bRet;
  180. }
  181. HKEY
  182. FindCurrentKey (
  183. IN HKEY hkKey,
  184. IN PCTSTR pszString,
  185. IN PCTSTR pszPath
  186. )
  187. {
  188. HKEY hkResult = NULL;
  189. HKEY hkTemp = hkKey;
  190. TCHAR szPath[MAX_PATH + 1];
  191. PTSTR pszTemp = NULL;
  192. REGKEY_ENUM e;
  193. do
  194. {
  195. pszTemp = GetRegValueString (hkTemp, S_FRIENDLYNAME);
  196. if (pszTemp && StringIMatch (pszString, pszTemp))
  197. {
  198. hkResult = hkTemp;
  199. hkTemp = NULL;
  200. break;
  201. }
  202. if (!EnumFirstRegKey (&e, hkTemp)) {break;}
  203. do
  204. {
  205. if (pszTemp)
  206. {
  207. MemFree (g_hHeap, 0, pszTemp);
  208. pszTemp = NULL;
  209. }
  210. if (hkResult)
  211. {
  212. CloseRegKey(hkResult);
  213. hkResult = NULL;
  214. }
  215. sprintf(szPath, "%s\\%s", pszPath, e.SubKeyName );
  216. hkResult = OpenRegKeyStr (szPath);
  217. if (!hkResult) {break;}
  218. pszTemp = GetRegValueString (hkResult, S_FRIENDLYNAME);
  219. if (pszTemp && StringIMatch (pszString, pszTemp))
  220. {
  221. // Success
  222. break;
  223. }
  224. else
  225. {
  226. CloseRegKey(hkResult);
  227. hkResult = NULL;
  228. }
  229. } while (EnumNextRegKey (&e));
  230. } while (FALSE);
  231. //
  232. // Clean up
  233. //
  234. if (pszTemp)
  235. {
  236. MemFree (g_hHeap, 0, pszTemp);
  237. }
  238. if (hkTemp)
  239. {
  240. CloseRegKey(hkTemp);
  241. }
  242. return hkResult;
  243. }
  244. PTSTR
  245. GetInfoFromFriendlyName (
  246. IN PCTSTR pszFriendlyName,
  247. IN BOOL bType
  248. )
  249. {
  250. HKEY hkEnum = NULL;
  251. DWORD i = 0;
  252. TCHAR szData[MAX_PATH + 1];
  253. TCHAR szPath[MAX_PATH + 1];
  254. PTSTR pszTemp = NULL;
  255. PTSTR pszReturn = NULL;
  256. LPGUID pguidModem = (LPGUID)&GUID_DEVCLASS_MODEM;
  257. HDEVINFO hdi;
  258. SP_DEVINFO_DATA devInfoData = {sizeof (devInfoData), 0};
  259. hdi = SetupDiGetClassDevs (pguidModem, NULL, NULL, DIGCF_PRESENT);
  260. if (INVALID_HANDLE_VALUE == hdi)
  261. {
  262. return NULL;
  263. }
  264. while (SetupDiEnumDeviceInfo (hdi, i++, &devInfoData))
  265. {
  266. if (!SetupDiGetDeviceRegistryProperty (
  267. hdi, &devInfoData, SPDRP_FRIENDLYNAME,
  268. NULL, (PBYTE)szData, MAX_PATH, NULL) ||
  269. lstrcmp (szData, pszFriendlyName) )
  270. {
  271. continue;
  272. }
  273. if (!SetupDiGetDeviceRegistryProperty (
  274. hdi, &devInfoData, SPDRP_HARDWAREID,
  275. NULL, (PBYTE)szData, MAX_PATH, NULL) )
  276. {
  277. break;
  278. }
  279. sprintf(szPath, "%s\\%s", S_ENUM, szData );
  280. hkEnum = OpenRegKeyStr (szPath);
  281. if (!hkEnum) {break;}
  282. hkEnum = FindCurrentKey (hkEnum, pszFriendlyName, szPath);
  283. if (!hkEnum) {break;}
  284. if (bType)
  285. {
  286. pszTemp = GetRegValueString (hkEnum, S_PARENTDEVNODE);
  287. if (pszTemp)
  288. {
  289. pszReturn = PoolMemDuplicateString (g_RasPool, pszTemp);
  290. break;
  291. }
  292. pszReturn = PoolMemDuplicateString (g_RasPool, szData);
  293. break;
  294. }
  295. else
  296. {
  297. pszTemp = GetRegValueString (hkEnum, S_ATTACHEDTO);
  298. if (pszTemp)
  299. {
  300. pszReturn = PoolMemDuplicateString (g_RasPool, pszTemp);
  301. break;
  302. }
  303. pszTemp = GetRegValueString (hkEnum, S_DRIVER);
  304. if (pszTemp)
  305. {
  306. HKEY key = NULL;
  307. PTSTR pszAttach = NULL;
  308. sprintf(szPath, "%s\\%s", S_SERVICECLASS, pszTemp);
  309. key = OpenRegKeyStr (szPath);
  310. if (!key) {break;}
  311. pszAttach = GetRegValueString (key, S_ATTACHEDTO);
  312. if (!pszAttach)
  313. {
  314. CloseRegKey(key);
  315. break;
  316. }
  317. pszReturn = PoolMemDuplicateString (g_RasPool, pszAttach);
  318. MemFree (g_hHeap, 0, pszAttach);
  319. CloseRegKey(key);
  320. }
  321. break;
  322. }
  323. }
  324. //
  325. // Clean up
  326. //
  327. if (bType && pszReturn)
  328. {
  329. BOOL bFisrt = FALSE;
  330. PTSTR p;
  331. for (p = pszReturn; '\0' != *p; p++ )
  332. {
  333. if (*p != '\\') {continue;}
  334. if (!bFisrt)
  335. {
  336. bFisrt = TRUE;
  337. }
  338. else
  339. {
  340. //
  341. // Remove rest of PnpId string, not needed
  342. //
  343. *p = '\0';
  344. break;
  345. }
  346. }
  347. }
  348. if (pszTemp)
  349. {
  350. MemFree (g_hHeap, 0, pszTemp);
  351. }
  352. if (hkEnum)
  353. {
  354. CloseRegKey(hkEnum);
  355. }
  356. if (INVALID_HANDLE_VALUE != hdi)
  357. {
  358. SetupDiDestroyDeviceInfoList (hdi);
  359. }
  360. return pszReturn;
  361. }
  362. PTSTR
  363. GetComPort (
  364. IN PCTSTR DriverDesc
  365. )
  366. {
  367. PTSTR rPort = NULL;
  368. rPort = GetInfoFromFriendlyName(DriverDesc, FALSE);
  369. if (!rPort)
  370. {
  371. rPort = S_EMPTY;
  372. DEBUGMSG ((DBG_WARNING, "Could not find com port for device %s."));
  373. }
  374. return rPort;
  375. }
  376. VOID
  377. pInitLibs (
  378. VOID
  379. )
  380. {
  381. do {
  382. //
  383. // Load in rasapi32.dll, not fatal if we fail
  384. //
  385. // Whistler 417479 RAS upgrade code does not migrate the default
  386. // internet connection setting from WinME to XP
  387. //
  388. g_RasApi32 = LoadSystemLibrary(S_RASAPI32LIB);
  389. if (!g_RasApi32) {
  390. g_RnaGetDefaultAutodialConnection = NULL;
  391. DEBUGMSG((S_DBG_RAS,"Migrate Ras: could not load library %s. Default Internet Connection will not be migrated.",
  392. S_RASAPI32LIB));
  393. }
  394. //
  395. // RASAPI32 was loaded..now, get the relevant apis, not fatal if we fail
  396. //
  397. else
  398. {
  399. (FARPROC) g_RnaGetDefaultAutodialConnection = GetProcAddress(
  400. g_RasApi32,
  401. S_RNAGETDEFAUTODIALCON
  402. );
  403. if (!g_RnaGetDefaultAutodialConnection) {
  404. DEBUGMSG((S_DBG_RAS,"Migrate Ras: could not load Procedure %s. Default Internet Connection will not be migrated.",
  405. S_RNAGETDEFAUTODIALCON));
  406. }
  407. }
  408. } while ( FALSE );
  409. return;
  410. }
  411. VOID
  412. pCleanUpLibs (
  413. VOID
  414. )
  415. {
  416. //
  417. // Whistler 417479 RAS upgrade code does not migrate the default
  418. // internet connection setting from WinME to XP
  419. //
  420. if (g_RasApi32) {
  421. FreeLibrary(g_RasApi32);
  422. }
  423. }
  424. VOID
  425. pSaveConnectionDataToMemDb (
  426. IN PCTSTR User,
  427. IN PCTSTR Entry,
  428. IN PCTSTR ValueName,
  429. IN DWORD ValueType,
  430. IN PBYTE Value
  431. )
  432. {
  433. DWORD offset;
  434. TCHAR key[MEMDB_MAX];
  435. MemDbBuildKey (key, MEMDB_CATEGORY_RAS_INFO, User, Entry, ValueName);
  436. switch (ValueType) {
  437. case REG_SZ:
  438. case REG_MULTI_SZ:
  439. case REG_EXPAND_SZ:
  440. DEBUGMSG ((S_DBG_RAS, "String Data - %s = %s", ValueName,
  441. (PCTSTR) Value));
  442. if (!MemDbSetValueEx (MEMDB_CATEGORY_RAS_DATA, (PCTSTR) Value,
  443. NULL, NULL, 0, &offset)) {
  444. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  445. }
  446. if (!MemDbSetValueAndFlags (key, offset, (WORD) REG_SZ, 0)) {
  447. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  448. }
  449. break;
  450. case REG_DWORD:
  451. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", ValueName,
  452. (DWORD) Value));
  453. if (!MemDbSetValueAndFlags (key, (DWORD)Value, (WORD)ValueType,0)){
  454. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  455. }
  456. break;
  457. case REG_BINARY:
  458. DEBUGMSG ((S_DBG_RAS, "Binary data for %s.", ValueName));
  459. if (StringIMatch (S_IPINFO, ValueName)) {
  460. //
  461. // Save IP address information.
  462. //
  463. pSaveConnectionDataToMemDb (User, Entry, S_IP_FTCPIP,
  464. REG_DWORD, (PBYTE) ((PIPDATA) Value)->fdwTCPIP);
  465. pSaveConnectionDataToMemDb (User, Entry, S_IP_IPADDR,
  466. REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwIPAddr);
  467. pSaveConnectionDataToMemDb (User, Entry, S_IP_DNSADDR,
  468. REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwDNSAddr);
  469. pSaveConnectionDataToMemDb (User, Entry, S_IP_DNSADDR2,
  470. REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwDNSAddrAlt);
  471. pSaveConnectionDataToMemDb (User, Entry, S_IP_WINSADDR,
  472. REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwWINSAddr);
  473. pSaveConnectionDataToMemDb (User, Entry, S_IP_WINSADDR2,
  474. REG_DWORD, (PBYTE) ((PIPDATA) Value)->dwWINSAddrAlt);
  475. } else if (StringIMatch (S_TERMINAL, ValueName)) {
  476. //
  477. // save information on the showcmd state. This will tell us how
  478. // to set the ui display.
  479. //
  480. pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
  481. (PBYTE) ((PWINDOWPLACEMENT) Value)->showCmd);
  482. } else if (StringIMatch (S_MODE, ValueName)) {
  483. //
  484. // This value tells what to do with scripting.
  485. //
  486. pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
  487. (PBYTE) *((PDWORD) Value));
  488. } else if (StringIMatch (S_MULTILINK, ValueName)) {
  489. //
  490. // Save wether or not multilink is enabled.
  491. //
  492. pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
  493. (PBYTE) *((PDWORD) Value));
  494. //
  495. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
  496. // Domain, Passwrds to not be migrated for DUN
  497. //
  498. } else if (StringIMatch (S_PBE_REDIALATTEMPTS, ValueName)) {
  499. //
  500. // Save the number of redial attempts
  501. //
  502. pSaveConnectionDataToMemDb (User, Entry, S_REDIAL_TRY, REG_DWORD,
  503. (PBYTE) *((PDWORD) Value));
  504. //
  505. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
  506. // Domain, Passwrds to not be migrated for DUN
  507. //
  508. } else if (StringIMatch (S_REDIAL_WAIT, ValueName)) {
  509. //
  510. // Save the number of seconds to wait for redial
  511. //
  512. pSaveConnectionDataToMemDb (User, Entry, ValueName, REG_DWORD,
  513. (PBYTE) *((PDWORD) Value));
  514. } ELSE_DEBUGMSG ((DBG_WARNING, "Don't know how to handle binary data %s. It will be ignored.",
  515. ValueName));
  516. break;
  517. default:
  518. DEBUGMSG ((DBG_WHOOPS, "Unknown type of registry data found in RAS settings. %s",
  519. ValueName));
  520. break;
  521. }
  522. }
  523. BOOL
  524. pGetRasEntrySettings (
  525. IN PUSERENUM EnumPtr,
  526. IN HKEY Key,
  527. IN PCTSTR EntryName
  528. )
  529. {
  530. REGVALUE_ENUM e;
  531. PBYTE curData = NULL;
  532. BOOL rSuccess = TRUE;
  533. DEBUGMSG ((S_DBG_RAS, "---Processing %s's entry settings: %s---",
  534. EnumPtr->FixedUserName, EntryName));
  535. if (EnumFirstRegValue (&e, Key)) {
  536. do {
  537. //
  538. // Get the data for this entry.
  539. //
  540. curData = GetRegValueData (Key, e.ValueName);
  541. if (curData) {
  542. //
  543. // Whistler bug: 417745 INTL:Win9x Upg: DBCS chars cause User,
  544. // Domain, Passwrds to not be migrated for DUN
  545. //
  546. if (StringIMatch (S_MULTILINK, e.ValueName) &&
  547. !g_MultilinkEnabled) {
  548. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  549. EntryName, e.ValueName, REG_DWORD, 0);
  550. }
  551. else {
  552. pSaveConnectionDataToMemDb (
  553. EnumPtr->FixedUserName, EntryName, e.ValueName, e.Type,
  554. e.Type == REG_DWORD ? (PBYTE) (*((PDWORD)curData)) :
  555. curData);
  556. }
  557. MemFree (g_hHeap, 0, curData);
  558. }
  559. } while (EnumNextRegValue (&e));
  560. }
  561. return rSuccess;
  562. }
  563. BOOL
  564. pGetRasEntryAddressInfo (
  565. IN PUSERENUM EnumPtr,
  566. IN HKEY Key,
  567. IN PCTSTR EntryName
  568. )
  569. {
  570. BOOL rSuccess = TRUE;
  571. HKEY subEntriesKey = NULL;
  572. UINT count = 0, type = 0, sequencer = 0;
  573. PBYTE data = NULL;
  574. PTSTR subEntriesKeyStr = NULL;
  575. TCHAR buffer[MAX_TCHAR_PATH];
  576. PCTSTR group;
  577. PSMMCFG smmCfg = NULL;
  578. PADDRENTRY entry = NULL;
  579. PDEVICEINFO devInfo = NULL;
  580. REGVALUE_ENUM e, eSubEntries;
  581. PSUBCONNENTRY subEntry = NULL;
  582. PMODEMDEVINFO modemInfo;
  583. //
  584. // First we have to get the real entry name. It must match exactly even
  585. // case. Unfortunately, it isn't neccessarily a given that the case between
  586. // HKR\RemoteAccess\Profiles\<Foo> and HKR\RemoteAccess\Addresses\[Foo] is
  587. // the same. The registry apis will of course work fine because they work
  588. // case insensitively. However, I will be unable to decrypt the value if I
  589. // use the wrong name.
  590. //
  591. if (EnumFirstRegValue (&e, Key)) {
  592. do {
  593. if (StringIMatch (e.ValueName, EntryName)) {
  594. //
  595. // Found the correct entry. Use it.
  596. //
  597. data = GetRegValueBinary (Key, e.ValueName);
  598. if (data) {
  599. DEBUGMSG ((S_DBG_RAS, "-----Processing entry: %s-----",
  600. e.ValueName));
  601. //
  602. // Whistler 417479 RAS upgrade code does not migrate the default
  603. // internet connection setting from WinME to XP
  604. //
  605. pSaveConnectionDataToMemDb (
  606. EnumPtr->FixedUserName, EntryName, S_DEFINTERNETCON,
  607. REG_DWORD, (PBYTE) IsDefInternetCon(EntryName));
  608. entry = (PADDRENTRY) data;
  609. DECRYPTENTRY(e.ValueName, entry, e.DataSize);
  610. smmCfg = PAESMMCFG(entry);
  611. devInfo = PAEDI(entry);
  612. pSaveConnectionDataToMemDb (
  613. EnumPtr->FixedUserName, EntryName, S_PHONE_NUMBER,
  614. REG_SZ, (PBYTE) PAEPHONE(entry));
  615. pSaveConnectionDataToMemDb (
  616. EnumPtr->FixedUserName, EntryName, S_AREA_CODE, REG_SZ,
  617. (PBYTE) PAEAREA(entry));
  618. pSaveConnectionDataToMemDb (
  619. EnumPtr->FixedUserName, EntryName, S_SMM, REG_SZ,
  620. (PBYTE) PAESMM(entry));
  621. pSaveConnectionDataToMemDb (
  622. EnumPtr->FixedUserName, EntryName, S_COUNTRY_CODE,
  623. REG_DWORD, (PBYTE) entry->dwCountryCode);
  624. pSaveConnectionDataToMemDb (
  625. EnumPtr->FixedUserName, EntryName, S_COUNTRY_ID,
  626. REG_DWORD, (PBYTE) entry->dwCountryID);
  627. pSaveConnectionDataToMemDb (
  628. EnumPtr->FixedUserName, EntryName, S_DEVICE_NAME,
  629. REG_SZ, (PBYTE) devInfo->szDeviceName);
  630. pSaveConnectionDataToMemDb (
  631. EnumPtr->FixedUserName, EntryName, S_DEVICE_TYPE,
  632. REG_SZ, (PBYTE) devInfo->szDeviceType);
  633. pSaveConnectionDataToMemDb (
  634. EnumPtr->FixedUserName, EntryName, S_PROTOCOLS,
  635. REG_DWORD, (PBYTE) smmCfg->fdwProtocols);
  636. pSaveConnectionDataToMemDb (
  637. EnumPtr->FixedUserName, EntryName, S_SMM_OPTIONS,
  638. REG_DWORD, (PBYTE) smmCfg->fdwOptions);
  639. //
  640. // Save device information away.
  641. //
  642. if (StringIMatch (devInfo->szDeviceType, S_MODEM)) {
  643. PTSTR pszPnpId = NULL;
  644. pszPnpId = GetInfoFromFriendlyName(
  645. devInfo->szDeviceName, TRUE);
  646. if (pszPnpId)
  647. {
  648. pSaveConnectionDataToMemDb (
  649. EnumPtr->FixedUserName, EntryName,
  650. S_DEVICE_ID, REG_SZ, (PBYTE) pszPnpId);
  651. }
  652. modemInfo = (PMODEMDEVINFO) (devInfo->szDeviceType +
  653. RAS_MaxDeviceType + 3);
  654. if (modemInfo->Size >= sizeof (MODEMDEVINFO)) {
  655. DEBUGMSG_IF ((modemInfo->Size >
  656. sizeof (MODEMDEVINFO), S_DBG_RAS,
  657. "Structure size larger than our known size."));
  658. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  659. EntryName, S_MODEM_UI_OPTIONS, REG_DWORD,
  660. (PBYTE) modemInfo->ModemUiOptions);
  661. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  662. EntryName, S_MODEM_SPEED, REG_DWORD,
  663. (PBYTE) modemInfo->ConnectionSpeed);
  664. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  665. EntryName, S_MODEM_SPEAKER_VOLUME, REG_DWORD,
  666. (PBYTE) modemInfo->SpeakerVolume);
  667. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  668. EntryName, S_MODEM_IDLE_DISCONNECT_SECONDS,
  669. REG_DWORD,
  670. (PBYTE) modemInfo->dwInactivityTimeout);
  671. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  672. EntryName, S_MODEM_CANCEL_SECONDS, REG_DWORD,
  673. (PBYTE) modemInfo->dwCallSetupFailTimer);
  674. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  675. EntryName, S_MODEM_CFG_OPTIONS, REG_DWORD,
  676. (PBYTE) modemInfo->ConfigOptions);
  677. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  678. EntryName, S_MODEM_COM_PORT, REG_SZ,
  679. (PBYTE) GetComPort (devInfo->szDeviceName));
  680. }
  681. ELSE_DEBUGMSG ((DBG_WHOOPS, "No modem configuration data saved. Size smaller than known structure. Investigate."));
  682. }
  683. //
  684. // If SMM is not SLIP, CSLIP or PPP, we need to add a
  685. // message to the upgrade report.
  686. //
  687. if (!StringIMatch (PAESMM(entry), S_SLIP)&&
  688. !StringIMatch (PAESMM(entry), S_PPP) &&
  689. !StringIMatch (PAESMM(entry), S_CSLIP)) {
  690. //
  691. // Add message for this connection entry.
  692. //
  693. group = BuildMessageGroup (
  694. MSG_LOSTSETTINGS_ROOT,
  695. MSG_CONNECTION_BADPROTOCOL_SUBGROUP,
  696. EntryName
  697. );
  698. if (group) {
  699. MsgMgr_ObjectMsg_Add (
  700. EntryName,
  701. group,
  702. S_EMPTY
  703. );
  704. FreeText (group);
  705. }
  706. }
  707. }
  708. //
  709. // Check to see if there are any sub-entries for this
  710. // connection (MULTILINK settings..)
  711. //
  712. // Luckily, we don't have to do the same enumeration of these
  713. // entries as we had to above to get around the case
  714. // sensitivity bug. the 9x code uses the address key name above
  715. // for encryption/decryption.
  716. //
  717. sequencer = 1;
  718. g_MultilinkEnabled = FALSE;
  719. if (data && !StringIMatch (PAESMM(entry), S_PPP))
  720. {
  721. DEBUGMSG ((S_DBG_RAS, "Not using PPP, disabling Multi-Link"));
  722. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName,
  723. EntryName, S_DEVICECOUNT, REG_DWORD,
  724. (PBYTE) sequencer);
  725. MemFree (g_hHeap, 0, data);
  726. data = NULL;
  727. break;
  728. }
  729. subEntriesKeyStr = JoinPaths (S_SUBENTRIES, e.ValueName);
  730. if (subEntriesKeyStr)
  731. {
  732. subEntriesKey = OpenRegKey (Key, subEntriesKeyStr);
  733. FreePathString (subEntriesKeyStr);
  734. }
  735. if (subEntriesKey) {
  736. DEBUGMSG ((S_DBG_RAS, "Multi-Link Subentries found for entry %s. Processing.",
  737. e.ValueName));
  738. g_MultilinkEnabled = TRUE;
  739. if (EnumFirstRegValue (&eSubEntries, subEntriesKey)) {
  740. do {
  741. data = GetRegValueBinary (subEntriesKey,
  742. eSubEntries.ValueName);
  743. if (data) {
  744. PTSTR pszPnpId = NULL;
  745. subEntry = (PSUBCONNENTRY) data;
  746. DECRYPTENTRY (e.ValueName, subEntry,
  747. eSubEntries.DataSize);
  748. wsprintf (buffer, "ml%d%s",sequencer,
  749. S_DEVICE_TYPE);
  750. pSaveConnectionDataToMemDb (
  751. EnumPtr->FixedUserName, EntryName, buffer,
  752. REG_SZ, (PBYTE) subEntry->szDeviceType);
  753. wsprintf (buffer, "ml%d%s",sequencer,
  754. S_DEVICE_NAME);
  755. pSaveConnectionDataToMemDb (
  756. EnumPtr->FixedUserName, EntryName, buffer,
  757. REG_SZ, (PBYTE) subEntry->szDeviceName);
  758. pszPnpId = GetInfoFromFriendlyName(
  759. subEntry->szDeviceName, TRUE);
  760. if (pszPnpId)
  761. {
  762. wsprintf (buffer, "ml%d%s",sequencer,
  763. S_DEVICE_ID);
  764. pSaveConnectionDataToMemDb (
  765. EnumPtr->FixedUserName, EntryName,
  766. buffer, REG_SZ, (PBYTE) pszPnpId);
  767. }
  768. wsprintf (buffer, "ml%d%s",sequencer,
  769. S_PHONE_NUMBER);
  770. pSaveConnectionDataToMemDb (
  771. EnumPtr->FixedUserName, EntryName, buffer,
  772. REG_SZ, (PBYTE) subEntry->szLocal);
  773. wsprintf (buffer, "ml%d%s",sequencer,
  774. S_MODEM_COM_PORT);
  775. pSaveConnectionDataToMemDb (
  776. EnumPtr->FixedUserName, EntryName, buffer,
  777. REG_SZ, (PBYTE)
  778. GetComPort (subEntry->szDeviceName));
  779. MemFree (g_hHeap, 0, data);
  780. data = NULL;
  781. }
  782. sequencer++;
  783. } while (EnumNextRegValue (&eSubEntries));
  784. }
  785. CloseRegKey (subEntriesKey);
  786. }
  787. //
  788. // Save away the number of devices associated with this
  789. // connection
  790. //
  791. pSaveConnectionDataToMemDb (EnumPtr->FixedUserName, EntryName,
  792. S_DEVICECOUNT, REG_DWORD, (PBYTE) sequencer);
  793. //
  794. // We're done. Break out of the enumeration.
  795. //
  796. break;
  797. }
  798. } while (EnumNextRegValue (&e));
  799. }
  800. return rSuccess;
  801. }
  802. BOOL
  803. pGetPerConnectionSettings (
  804. IN PUSERENUM EnumPtr
  805. )
  806. {
  807. HKEY profileKey;
  808. HKEY entryKey = NULL;
  809. HKEY addressKey = NULL;
  810. BOOL rSuccess = TRUE;
  811. REGVALUE_ENUM e;
  812. DEBUGMSG((S_DBG_RAS, "Gathering per-connection RAS Setting Information"));
  813. //
  814. // Open needed registry keys.
  815. //
  816. profileKey = OpenRegKey (EnumPtr->UserRegKey, S_PROFILE_KEY);
  817. addressKey = OpenRegKey (EnumPtr->UserRegKey, S_ADDRESSES_KEY);
  818. if (addressKey) {
  819. //
  820. // Enumerate each entry for this user.
  821. //
  822. if (EnumFirstRegValue (&e, addressKey)) {
  823. do {
  824. //
  825. // Get base connection info -- stored as binary blob under
  826. // address key. All connections will have this info -- It
  827. // contains such things as the phone number, area code, dialing
  828. // rules, etc.. It does not matter wether the connection has
  829. // been used or not.
  830. //
  831. rSuccess &= pGetRasEntryAddressInfo (EnumPtr,
  832. addressKey, e.ValueName );
  833. if (profileKey) {
  834. //
  835. // Under the profile key are negotiated options for the
  836. // connection. This key will only exist if the entry has
  837. // actually been connected to by the user.
  838. //
  839. entryKey = OpenRegKey (profileKey, e.ValueName);
  840. if (entryKey) {
  841. rSuccess &= pGetRasEntrySettings ( EnumPtr, entryKey,
  842. e.ValueName );
  843. CloseRegKey (entryKey);
  844. }
  845. }
  846. } while (EnumNextRegValue (&e));
  847. }
  848. }
  849. ELSE_DEBUGMSG ((DBG_WARNING, "pGetPerConnectionSettings: Unable to access needed registry info for user %s.",
  850. EnumPtr->FixedUserName));
  851. //
  852. // Clean up resources.
  853. //
  854. if (addressKey) {
  855. CloseRegKey (addressKey);
  856. }
  857. if (profileKey) {
  858. CloseRegKey (profileKey);
  859. }
  860. return rSuccess;
  861. }
  862. BOOL
  863. pGetPerUserSettings (
  864. IN PUSERENUM EnumPtr
  865. )
  866. {
  867. HKEY settingsKey;
  868. PDWORD data;
  869. BOOL rSuccess = TRUE;
  870. DEBUGMSG ((S_DBG_RAS, "Gathering per-user RAS data for %s.",
  871. EnumPtr->UserName));
  872. settingsKey = OpenRegKey (EnumPtr->UserRegKey, S_REMOTE_ACCESS_KEY);
  873. if (settingsKey) {
  874. //
  875. // Get UI settings.
  876. //
  877. data = (PDWORD) GetRegValueBinary (settingsKey, S_DIALUI);
  878. //
  879. // Save Dial User Interface info into memdb for this user.
  880. //
  881. if (data) {
  882. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_DIALUI, *data));
  883. rSuccess &= MemDbSetValueEx (
  884. MEMDB_CATEGORY_RAS_INFO,
  885. MEMDB_FIELD_USER_SETTINGS,
  886. EnumPtr->FixedUserName,
  887. S_DIALUI,
  888. *data,
  889. NULL
  890. );
  891. MemFree (g_hHeap, 0, data);
  892. }
  893. ELSE_DEBUGMSG ((S_DBG_RAS, "No user UI settings found for %s.",
  894. EnumPtr->UserName));
  895. //
  896. // Get Redial information.
  897. //
  898. data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_REDIAL);
  899. if (data) {
  900. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_ENABLE_REDIAL,
  901. *data));
  902. rSuccess &= MemDbSetValueEx (
  903. MEMDB_CATEGORY_RAS_INFO,
  904. MEMDB_FIELD_USER_SETTINGS,
  905. EnumPtr->FixedUserName,
  906. S_ENABLE_REDIAL,
  907. *data,
  908. NULL
  909. );
  910. MemFree (g_hHeap, 0, data);
  911. }
  912. ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
  913. EnumPtr->UserName));
  914. data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_TRY);
  915. if (data) {
  916. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_REDIAL_TRY,
  917. *data));
  918. rSuccess &= MemDbSetValueEx (
  919. MEMDB_CATEGORY_RAS_INFO,
  920. MEMDB_FIELD_USER_SETTINGS,
  921. EnumPtr->FixedUserName,
  922. S_REDIAL_TRY,
  923. *data,
  924. NULL
  925. );
  926. MemFree (g_hHeap, 0, data);
  927. }
  928. ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
  929. EnumPtr->UserName));
  930. data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_WAIT);
  931. if (data) {
  932. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_REDIAL_WAIT,
  933. HIWORD(*data) * 60 + LOWORD(*data)));
  934. MemDbSetValueEx (
  935. MEMDB_CATEGORY_RAS_INFO,
  936. MEMDB_FIELD_USER_SETTINGS,
  937. EnumPtr->FixedUserName,
  938. S_REDIAL_WAIT,
  939. HIWORD(*data) * 60 + LOWORD(*data),
  940. NULL
  941. );
  942. MemFree (g_hHeap, 0, data);
  943. }
  944. ELSE_DEBUGMSG ((S_DBG_RAS, "No user redial information found for %s.",
  945. EnumPtr->UserName));
  946. //
  947. // Get implicit connection information. (Controls wether connection ui
  948. // should be displayed or not)
  949. //
  950. data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_IMPLICIT);
  951. if (data) {
  952. DEBUGMSG ((S_DBG_RAS, "DWORD Data - %s = %u", S_ENABLE_IMPLICIT,
  953. *data));
  954. MemDbSetValueEx (
  955. MEMDB_CATEGORY_RAS_INFO,
  956. MEMDB_FIELD_USER_SETTINGS,
  957. EnumPtr->FixedUserName,
  958. S_ENABLE_IMPLICIT,
  959. *data,
  960. NULL
  961. );
  962. MemFree(g_hHeap,0,data);
  963. }
  964. ELSE_DEBUGMSG ((S_DBG_RAS, "No user implicit connection information found for %s.",
  965. EnumPtr->UserName));
  966. CloseRegKey(settingsKey);
  967. }
  968. return rSuccess;
  969. }
  970. DWORD
  971. ProcessRasSettings (
  972. IN DWORD Request,
  973. IN PUSERENUM EnumPtr
  974. )
  975. {
  976. DWORD rc = ERROR_SUCCESS;
  977. switch (Request) {
  978. case REQUEST_QUERYTICKS:
  979. return TICKS_RAS_PREPARE_REPORT;
  980. case REQUEST_BEGINUSERPROCESSING:
  981. //
  982. // We are about to be called for each user. Do necessary
  983. // initialization.
  984. //
  985. // Initialize our pool and get information from libraries.
  986. //
  987. g_RasPool = PoolMemInitNamedPool (TEXT("RAS - Win9x Side"));
  988. MYASSERT( g_RasPool);
  989. pInitLibs();
  990. g_RasInstalled = IsRasInstalled();
  991. return ERROR_SUCCESS;
  992. case REQUEST_RUN:
  993. //
  994. // Gather RAS information for this user.
  995. //
  996. if (g_RasInstalled && EnumPtr -> AccountType & NAMED_USER) {
  997. __try {
  998. pGetPerUserSettings (EnumPtr);
  999. pGetPerConnectionSettings (EnumPtr);
  1000. }
  1001. __except (TRUE) {
  1002. DEBUGMSG ((DBG_WHOOPS, "Caught an exception while processing ras settings."));
  1003. }
  1004. }
  1005. return ERROR_SUCCESS;
  1006. case REQUEST_ENDUSERPROCESSING:
  1007. //
  1008. // Clean up our resources.
  1009. //
  1010. pCleanUpLibs();
  1011. PoolMemDestroyPool(g_RasPool);
  1012. return ERROR_SUCCESS;
  1013. default:
  1014. DEBUGMSG ((DBG_ERROR, "Bad parameter in Ras_PrepareReport"));
  1015. }
  1016. return 0;
  1017. }
  1018. BOOL
  1019. IsRasInstalled (
  1020. void
  1021. )
  1022. {
  1023. HKEY testKey = NULL;
  1024. BOOL rf = FALSE;
  1025. testKey = OpenRegKeyStr(S_SERVICEREMOTEACCESS);
  1026. if (testKey) {
  1027. //
  1028. // Open key succeeded. Assume RAS is installed.
  1029. //
  1030. rf = TRUE;
  1031. CloseRegKey(testKey);
  1032. }
  1033. return rf;
  1034. }
  1035. BOOL
  1036. WINAPI
  1037. Ras_Entry (
  1038. IN HINSTANCE hinstDLL,
  1039. IN DWORD dwReason,
  1040. IN LPVOID lpv
  1041. )
  1042. {
  1043. BOOL rSuccess = TRUE;
  1044. switch (dwReason)
  1045. {
  1046. case DLL_PROCESS_ATTACH:
  1047. break;
  1048. case DLL_PROCESS_DETACH:
  1049. //
  1050. // Clean up resources that we used.
  1051. //
  1052. break;
  1053. }
  1054. return rSuccess;
  1055. }