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.

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