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.

1346 lines
36 KiB

  1. /* Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. **
  3. ** pbuser.c
  4. ** User preference storage routines
  5. ** Listed alphabetically
  6. **
  7. ** 10/31/95 Steve Cobb
  8. */
  9. #include <windows.h> // Win32 root
  10. #include <debug.h> // Trace/Assert library
  11. #include <nouiutil.h> // Heap macros
  12. #include <pbuser.h> // Our public header
  13. #include <rasdlg.h> // RAS common dialog header for RASMD_*
  14. /* Default user preference settings.
  15. */
  16. static const PBUSER g_pbuserDefaults =
  17. {
  18. FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE,
  19. 0, 15, 1200, FALSE, TRUE, FALSE,
  20. CBM_Maybe, NULL, NULL,
  21. PBM_System, NULL, NULL, NULL,
  22. NULL, FALSE,
  23. NULL, NULL, NULL,
  24. 0x7FFFFFFF, 0x7FFFFFFF, NULL,
  25. FALSE, FALSE
  26. };
  27. /*----------------------------------------------------------------------------
  28. ** Local prototypes (alphabetically)
  29. **----------------------------------------------------------------------------
  30. */
  31. VOID
  32. GetCallbackList(
  33. IN HKEY hkey,
  34. OUT DTLLIST** ppListResult );
  35. VOID
  36. GetLocationList(
  37. IN HKEY hkey,
  38. OUT DTLLIST** ppListResult );
  39. VOID
  40. MoveLogonPreferences(
  41. void );
  42. VOID
  43. MoveUserPreferences(
  44. void );
  45. DWORD
  46. ReadUserPreferences(
  47. IN HKEY hkey,
  48. OUT PBUSER* pUser );
  49. DWORD
  50. SetCallbackList(
  51. IN HKEY hkey,
  52. IN DTLLIST* pList );
  53. DWORD
  54. SetDefaultUserPreferences(
  55. OUT PBUSER* pUser,
  56. IN DWORD dwMode );
  57. DWORD
  58. SetLocationList(
  59. IN HKEY hkey,
  60. IN DTLLIST* pList );
  61. DWORD
  62. WriteUserPreferences(
  63. IN HKEY hkey,
  64. IN PBUSER* pUser );
  65. /*----------------------------------------------------------------------------
  66. ** Phonebook preference routines (alphabetically)
  67. **----------------------------------------------------------------------------
  68. */
  69. DTLNODE*
  70. CreateLocationNode(
  71. IN DWORD dwLocationId,
  72. IN DWORD iPrefix,
  73. IN DWORD iSuffix )
  74. /* Returns a LOCATIONINFO node associated with TAPI location
  75. ** 'dwLocationId', prefix index 'iPrefix' and suffix index 'iSuffix'.
  76. */
  77. {
  78. DTLNODE* pNode;
  79. LOCATIONINFO* pInfo;
  80. pNode = DtlCreateSizedNode( sizeof(LOCATIONINFO), 0L );
  81. if (!pNode)
  82. return NULL;
  83. pInfo = (LOCATIONINFO* )DtlGetData( pNode );
  84. pInfo->dwLocationId = dwLocationId;
  85. pInfo->iPrefix = iPrefix;
  86. pInfo->iSuffix = iSuffix;
  87. return pNode;
  88. }
  89. DTLNODE*
  90. CreateCallbackNode(
  91. IN TCHAR* pszPortName,
  92. IN TCHAR* pszDeviceName,
  93. IN TCHAR* pszNumber,
  94. IN DWORD dwDeviceType )
  95. /* Returns a CALLBACKINFO node containing a copy of 'pszPortName',
  96. ** 'pszDeviceName' and 'pszNumber' and 'dwDeviceType' or NULL on error.
  97. ** It is caller's responsibility to DestroyCallbackNode the returned node.
  98. */
  99. {
  100. DTLNODE* pNode;
  101. CALLBACKINFO* pInfo;
  102. pNode = DtlCreateSizedNode( sizeof(CALLBACKINFO), 0L );
  103. if (!pNode)
  104. return NULL;
  105. pInfo = (CALLBACKINFO* )DtlGetData( pNode );
  106. pInfo->pszPortName = StrDup( pszPortName );
  107. pInfo->pszDeviceName = StrDup( pszDeviceName );
  108. pInfo->pszNumber = StrDup( pszNumber );
  109. pInfo->dwDeviceType = dwDeviceType;
  110. if (!pInfo->pszPortName || !pInfo->pszDeviceName || !pInfo->pszNumber)
  111. {
  112. Free0( pInfo->pszPortName );
  113. Free0( pInfo->pszDeviceName );
  114. Free0( pInfo->pszNumber );
  115. DtlDestroyNode( pNode );
  116. return NULL;
  117. }
  118. return pNode;
  119. }
  120. VOID
  121. DestroyLocationNode(
  122. IN DTLNODE* pNode )
  123. /* Release memory allociated with location node 'pNode'.
  124. */
  125. {
  126. DtlDestroyNode( pNode );
  127. }
  128. VOID
  129. DestroyCallbackNode(
  130. IN DTLNODE* pNode )
  131. /* Release memory allociated with callback node 'pNode'.
  132. */
  133. {
  134. CALLBACKINFO* pInfo;
  135. ASSERT(pNode);
  136. pInfo = (CALLBACKINFO* )DtlGetData( pNode );
  137. ASSERT(pInfo);
  138. Free0( pInfo->pszPortName );
  139. Free0( pInfo->pszDeviceName );
  140. Free0( pInfo->pszNumber );
  141. DtlDestroyNode( pNode );
  142. }
  143. VOID
  144. DestroyUserPreferences(
  145. IN PBUSER* pUser )
  146. /* Releases memory allocated by GetUserPreferences and zeros the
  147. ** structure.
  148. */
  149. {
  150. if (pUser->fInitialized)
  151. {
  152. DtlDestroyList( pUser->pdtllistCallback, DestroyCallbackNode );
  153. DtlDestroyList( pUser->pdtllistPhonebooks, DestroyPszNode );
  154. DtlDestroyList( pUser->pdtllistAreaCodes, DestroyPszNode );
  155. DtlDestroyList( pUser->pdtllistPrefixes, DestroyPszNode );
  156. DtlDestroyList( pUser->pdtllistSuffixes, DestroyPszNode );
  157. DtlDestroyList( pUser->pdtllistLocations, DestroyLocationNode );
  158. Free0( pUser->pszPersonalFile );
  159. Free0( pUser->pszAlternatePath );
  160. Free0( pUser->pszLastCallbackByCaller );
  161. Free0( pUser->pszDefaultEntry );
  162. }
  163. ZeroMemory( pUser, sizeof(*pUser) );
  164. }
  165. DTLNODE*
  166. DuplicateLocationNode(
  167. IN DTLNODE* pNode )
  168. /* Duplicates LOCATIONINFO node 'pNode'. See DtlDuplicateList.
  169. **
  170. ** Returns the address of the allocated node or NULL if out of memory. It
  171. ** is caller's responsibility to free the returned node.
  172. */
  173. {
  174. LOCATIONINFO* pInfo = (LOCATIONINFO* )DtlGetData( pNode );
  175. return CreateLocationNode(
  176. pInfo->dwLocationId, pInfo->iPrefix, pInfo->iSuffix );
  177. }
  178. DWORD
  179. DwGetUserPreferences(
  180. OUT PBUSER* pUser,
  181. IN DWORD dwMode )
  182. /* Load caller's 'pUser' with user phonebook preferences from the
  183. ** registry. 'DwMode' indicates the preferences to get, either the normal
  184. ** interactive user, the pre-logon, or router preferences.
  185. **
  186. ** Returns 0 if successful or an error code. If successful, caller should
  187. ** eventually call DestroyUserPreferences to release the returned heap
  188. ** buffers.
  189. */
  190. {
  191. DWORD dwErr;
  192. TRACE1("GetUserPreferences(m=%d)",dwMode);
  193. /* Move the user preferences, if it's not already been done.
  194. */
  195. if (dwMode == UPM_Normal)
  196. MoveUserPreferences();
  197. else if (dwMode == UPM_Logon)
  198. MoveLogonPreferences();
  199. dwErr = SetDefaultUserPreferences( pUser, dwMode );
  200. if (dwErr == 0)
  201. {
  202. HKEY hkey;
  203. DWORD dwErr2;
  204. if (dwMode == UPM_Normal)
  205. {
  206. dwErr2 = RegOpenKeyEx(
  207. HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuRas,
  208. 0, KEY_READ, &hkey );
  209. }
  210. else if (dwMode == UPM_Logon)
  211. {
  212. dwErr2 = RegOpenKeyEx(
  213. HKEY_USERS, (LPCTSTR )REGKEY_HkuRasLogon,
  214. 0, KEY_READ, &hkey );
  215. }
  216. else
  217. {
  218. ASSERT(dwMode==UPM_Router);
  219. dwErr2 = RegOpenKeyEx(
  220. HKEY_LOCAL_MACHINE, (LPCTSTR )REGKEY_HklmRouter,
  221. 0, KEY_READ, &hkey );
  222. }
  223. if (dwErr2 == 0)
  224. {
  225. if (ReadUserPreferences( hkey, pUser ) != 0)
  226. dwErr = SetDefaultUserPreferences( pUser, dwMode );
  227. RegCloseKey( hkey );
  228. }
  229. else
  230. {
  231. TRACE1("RegOpenKeyEx=%d",dwErr2);
  232. }
  233. }
  234. TRACE1("GetUserPreferences=%d",dwErr);
  235. return dwErr;
  236. }
  237. DWORD
  238. GetUserPreferences(HANDLE hConnection,
  239. PBUSER *pUser,
  240. DWORD dwMode)
  241. {
  242. RAS_RPC *pRasRpcConnection = (RAS_RPC *) hConnection;
  243. DWORD dwError = ERROR_SUCCESS;
  244. if( NULL == pRasRpcConnection
  245. || pRasRpcConnection->fLocal)
  246. {
  247. dwError = DwGetUserPreferences(pUser, dwMode);
  248. }
  249. else
  250. {
  251. dwError = RemoteGetUserPreferences(hConnection,
  252. pUser,
  253. dwMode);
  254. }
  255. return dwError;
  256. }
  257. DWORD
  258. DwSetUserPreferences(
  259. IN PBUSER* pUser,
  260. IN DWORD dwMode )
  261. /* Set current user phonebook preferences in the registry from caller's
  262. ** settings in 'pUser', if necessary. 'DwMode' indicates the preferences
  263. ** to get, either the normal interactive user, the pre-logon, or router
  264. ** preferences.
  265. **
  266. ** Returns 0 if successful, or an error code. Caller's 'pUser' is marked
  267. ** clean if successful.
  268. */
  269. {
  270. DWORD dwErr;
  271. DWORD dwDisposition;
  272. HKEY hkey;
  273. TRACE1("SetUserPreferences(m=%d)",dwMode);
  274. if (!pUser->fDirty)
  275. return 0;
  276. /* Create the preference key, or if it exists just open it.
  277. */
  278. if (dwMode == UPM_Normal)
  279. {
  280. dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
  281. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  282. &hkey, &dwDisposition );
  283. }
  284. else if (dwMode == UPM_Logon)
  285. {
  286. dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
  287. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  288. &hkey, &dwDisposition );
  289. }
  290. else
  291. {
  292. ASSERT(dwMode==UPM_Router);
  293. dwErr = RegCreateKeyEx( HKEY_LOCAL_MACHINE, REGKEY_HklmRouter,
  294. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  295. &hkey, &dwDisposition );
  296. }
  297. if (dwErr == 0)
  298. {
  299. dwErr = WriteUserPreferences( hkey, pUser );
  300. RegCloseKey( hkey );
  301. }
  302. TRACE1("SetUserPreferences=%d",dwErr);
  303. return dwErr;
  304. }
  305. DWORD
  306. SetUserPreferences(HANDLE hConnection,
  307. PBUSER *pUser,
  308. DWORD dwMode)
  309. {
  310. DWORD dwError = ERROR_SUCCESS;
  311. RAS_RPC *pRasRpcConnection = (RAS_RPC *) hConnection;
  312. if( NULL == pRasRpcConnection
  313. || pRasRpcConnection->fLocal)
  314. {
  315. dwError = DwSetUserPreferences(pUser, dwMode);
  316. }
  317. else
  318. {
  319. dwError = RemoteSetUserPreferences(hConnection,
  320. pUser,
  321. dwMode);
  322. }
  323. return dwError;
  324. }
  325. // Reads the operator assisted dial user parameter directly from
  326. // the registry.
  327. DWORD SetUserManualDialEnabling (
  328. IN OUT BOOL bEnable,
  329. IN DWORD dwMode )
  330. {
  331. DWORD dwErr;
  332. DWORD dwDisposition;
  333. HKEY hkey;
  334. TRACE2("SetUserManualDialEnabling (en=%d) (m=%d)",bEnable, dwMode);
  335. /* Create the preference key, or if it exists just open it.
  336. */
  337. if (dwMode == UPM_Normal)
  338. {
  339. dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
  340. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  341. &hkey, &dwDisposition );
  342. }
  343. else if (dwMode == UPM_Logon)
  344. {
  345. dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
  346. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  347. &hkey, &dwDisposition );
  348. }
  349. else
  350. return ERROR_INVALID_PARAMETER;
  351. if (dwErr != 0)
  352. return dwErr;
  353. dwErr = SetRegDword( hkey, REGVAL_fOperatorDial,
  354. !!bEnable );
  355. RegCloseKey( hkey );
  356. return dwErr;
  357. }
  358. // Sets the operator assisted dialing parameter directly in the
  359. // registry.
  360. DWORD GetUserManualDialEnabling (
  361. IN PBOOL pbEnabled,
  362. IN DWORD dwMode )
  363. {
  364. DWORD dwErr;
  365. DWORD dwDisposition;
  366. HKEY hkey;
  367. TRACE1("GetUserManualDialEnabling (m=%d)", dwMode);
  368. if (!pbEnabled)
  369. return ERROR_INVALID_PARAMETER;
  370. // Set defaults
  371. *pbEnabled = g_pbuserDefaults.fOperatorDial;
  372. /* Create the preference key, or if it exists just open it.
  373. */
  374. if (dwMode == UPM_Normal)
  375. {
  376. dwErr = RegCreateKeyEx( HKEY_CURRENT_USER, REGKEY_HkcuRas,
  377. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  378. &hkey, &dwDisposition );
  379. }
  380. else if (dwMode == UPM_Logon)
  381. {
  382. dwErr = RegCreateKeyEx( HKEY_USERS, REGKEY_HkuRasLogon,
  383. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  384. &hkey, &dwDisposition );
  385. }
  386. else
  387. return ERROR_INVALID_PARAMETER;
  388. if (dwErr != 0)
  389. return dwErr;
  390. GetRegDword( hkey, REGVAL_fOperatorDial,
  391. pbEnabled );
  392. RegCloseKey( hkey );
  393. return dwErr;
  394. }
  395. /*----------------------------------------------------------------------------
  396. ** Utilities (alphabetically)
  397. **----------------------------------------------------------------------------
  398. */
  399. VOID
  400. GetCallbackList(
  401. IN HKEY hkey,
  402. OUT DTLLIST** ppListResult )
  403. /* Replaces '*ppListResult' with a list containing a node for each device
  404. ** name under registry value "REGVAL_szCallback" of registry key 'hkey'.
  405. ** If no values exist *ppListResult' is replaced with an empty list.
  406. **
  407. ** It is caller's responsibility to destroy the returned list if non-NULL.
  408. */
  409. {
  410. DWORD dwErr;
  411. TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
  412. TCHAR* pszDevice;
  413. TCHAR* pszPort;
  414. TCHAR* pszNumber;
  415. DWORD dwDeviceType;
  416. DWORD cb;
  417. INT i;
  418. DTLLIST* pList;
  419. DTLNODE* pNode;
  420. HKEY hkeyCb;
  421. HKEY hkeyDP;
  422. pList = DtlCreateList( 0 );
  423. if (!pList)
  424. return;
  425. dwErr = RegOpenKeyEx( hkey, REGKEY_Callback, 0, KEY_READ, &hkeyCb );
  426. if (dwErr == 0)
  427. {
  428. for (i = 0; TRUE; ++i)
  429. {
  430. cb = sizeof(szDP)/sizeof(TCHAR);
  431. dwErr = RegEnumKeyEx(
  432. hkeyCb, i, szDP, &cb, NULL, NULL, NULL, NULL );
  433. if (dwErr == ERROR_NO_MORE_ITEMS)
  434. break;
  435. if (dwErr != 0)
  436. continue;
  437. /* Ignore keys not of the form "device (port)".
  438. */
  439. if (!DeviceAndPortFromPsz( szDP, &pszDevice, &pszPort ))
  440. continue;
  441. dwErr = RegOpenKeyEx( hkeyCb, szDP, 0, KEY_READ, &hkeyDP );
  442. if (dwErr == 0)
  443. {
  444. GetRegDword( hkeyDP, REGVAL_dwDeviceType, &dwDeviceType );
  445. dwErr = GetRegSz( hkeyDP, REGVAL_szNumber, &pszNumber );
  446. if (dwErr == 0)
  447. {
  448. pNode = CreateCallbackNode(
  449. pszPort, pszDevice, pszNumber, dwDeviceType );
  450. if (pNode)
  451. DtlAddNodeLast( pList, pNode );
  452. Free( pszNumber );
  453. }
  454. RegCloseKey( hkeyDP );
  455. }
  456. Free( pszDevice );
  457. Free( pszPort );
  458. }
  459. RegCloseKey( hkeyCb );
  460. }
  461. DtlDestroyList( *ppListResult, DestroyCallbackNode );
  462. *ppListResult = pList;
  463. }
  464. VOID
  465. GetLocationList(
  466. IN HKEY hkey,
  467. OUT DTLLIST** ppListResult )
  468. /* Replaces '*ppListResult' with a list containing a node for each
  469. ** location under registry value "REGVAL_szLocation" of registry key
  470. ** 'hkey'. If no values exist *ppListResult' is replaced with an empty
  471. ** list.
  472. **
  473. ** It is caller's responsibility to destroy the returned list if non-NULL.
  474. */
  475. {
  476. DWORD dwErr;
  477. TCHAR szId[ MAXLTOTLEN + 1 ];
  478. DWORD cb;
  479. INT i;
  480. DTLLIST* pList;
  481. DTLNODE* pNode;
  482. HKEY hkeyL;
  483. HKEY hkeyId;
  484. pList = DtlCreateList( 0 );
  485. if (!pList)
  486. return;
  487. dwErr = RegOpenKeyEx( hkey, REGKEY_Location, 0, KEY_READ, &hkeyL );
  488. if (dwErr == 0)
  489. {
  490. for (i = 0; TRUE; ++i)
  491. {
  492. cb = MAXLTOTLEN + 1;
  493. dwErr = RegEnumKeyEx( hkeyL, i, szId, &cb, NULL, NULL, NULL, NULL );
  494. if (dwErr == ERROR_NO_MORE_ITEMS)
  495. break;
  496. if (dwErr != 0)
  497. continue;
  498. dwErr = RegOpenKeyEx( hkeyL, szId, 0, KEY_READ, &hkeyId );
  499. if (dwErr == 0)
  500. {
  501. DWORD dwId;
  502. DWORD iPrefix;
  503. DWORD iSuffix;
  504. dwId = (DWORD )TToL( szId );
  505. iPrefix = 0;
  506. GetRegDword( hkeyId, REGVAL_dwPrefix, &iPrefix );
  507. iSuffix = 0;
  508. GetRegDword( hkeyId, REGVAL_dwSuffix, &iSuffix );
  509. pNode = CreateLocationNode( dwId, iPrefix, iSuffix );
  510. if (!pNode)
  511. continue;
  512. DtlAddNodeLast( pList, pNode );
  513. RegCloseKey( hkeyId );
  514. }
  515. }
  516. RegCloseKey( hkeyL );
  517. }
  518. DtlDestroyList( *ppListResult, DestroyLocationNode );
  519. *ppListResult = pList;
  520. }
  521. VOID
  522. MoveLogonPreferences(
  523. void )
  524. /* Move logon preferences from the NT 4.0 location to a new unique
  525. ** position, if necessary. This manuever is added because in NT 4.0 user
  526. ** preference calls from LocalSystem service use the old logon location at
  527. ** HKU\.DEFAULT due to fallbacks in the registry APIs causing logon and
  528. ** LocalSystem settings to overwrite each other.
  529. */
  530. {
  531. DWORD dwErr;
  532. HKEY hkeyOld;
  533. HKEY hkeyNew;
  534. PBUSER user;
  535. dwErr = RegOpenKeyEx(
  536. HKEY_USERS, (LPCTSTR )REGKEY_HkuOldRasLogon,
  537. 0, KEY_READ, &hkeyOld );
  538. if (dwErr != 0)
  539. return;
  540. dwErr = RegOpenKeyEx(
  541. HKEY_USERS, (LPCTSTR )REGKEY_HkuRasLogon,
  542. 0, KEY_READ, &hkeyNew );
  543. if (dwErr == 0)
  544. RegCloseKey( hkeyNew );
  545. else
  546. {
  547. /* Old tree exists and new tree doesn't. Move a copy of the old tree
  548. ** to the new tree.
  549. */
  550. dwErr = SetDefaultUserPreferences( &user, UPM_Logon );
  551. if (dwErr == 0)
  552. {
  553. dwErr = ReadUserPreferences( hkeyOld, &user );
  554. if (dwErr == 0)
  555. dwErr = SetUserPreferences( NULL, &user, UPM_Logon );
  556. }
  557. DestroyUserPreferences( &user );
  558. TRACE1("MoveLogonPreferences=%d",dwErr);
  559. }
  560. RegCloseKey( hkeyOld );
  561. }
  562. VOID
  563. MoveUserPreferences(
  564. void )
  565. /* Move user preferences from their old net-tools registry location to the
  566. ** new location nearer the other RAS keys.
  567. */
  568. {
  569. DWORD dwErr;
  570. HKEY hkeyOld;
  571. HKEY hkeyNew;
  572. /* See if the old current-user key exists.
  573. */
  574. dwErr = RegOpenKeyEx(
  575. HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuOldRas, 0,
  576. KEY_ALL_ACCESS, &hkeyOld );
  577. if (dwErr == 0)
  578. {
  579. PBUSER user;
  580. /* Read the preferences at the old key.
  581. */
  582. TRACE("Getting old prefs");
  583. dwErr = SetDefaultUserPreferences( &user, UPM_Normal );
  584. if (dwErr == 0)
  585. {
  586. dwErr = ReadUserPreferences( hkeyOld, &user );
  587. if (dwErr == 0)
  588. {
  589. /* Write the preferences at the new key.
  590. */
  591. user.fDirty = TRUE;
  592. dwErr = SetUserPreferences( NULL, &user, FALSE );
  593. if (dwErr == 0)
  594. {
  595. /* Blow away the old tree.
  596. */
  597. dwErr = RegOpenKeyEx(
  598. HKEY_CURRENT_USER, (LPCTSTR )REGKEY_HkcuOldRasParent,
  599. 0, KEY_ALL_ACCESS, &hkeyNew );
  600. if (dwErr == 0)
  601. {
  602. TRACE("Delete old prefs");
  603. dwErr = RegDeleteTree( hkeyNew, REGKEY_HkcuOldRasRoot );
  604. RegCloseKey( hkeyNew );
  605. }
  606. }
  607. }
  608. }
  609. RegCloseKey( hkeyOld );
  610. TRACE1("MoveUserPreferences=%d",dwErr);
  611. }
  612. }
  613. DWORD
  614. ReadUserPreferences(
  615. IN HKEY hkey,
  616. OUT PBUSER* pUser )
  617. /* Fill caller's 'pUser' buffer with user preferences from RAS-Phonebook
  618. ** registry tree 'hkey'.
  619. **
  620. ** Returns 0 if successful, false otherwise.
  621. */
  622. {
  623. BOOL fOldSettings;
  624. DWORD dwErr;
  625. TRACE("ReadUserPreferences");
  626. /* Read the values.
  627. */
  628. {
  629. DWORD dwMode;
  630. /* Lack of a phonebook mode key indicates that we are updating old NT
  631. ** 3.51-style settings.
  632. */
  633. dwMode = 0xFFFFFFFF;
  634. GetRegDword( hkey, REGVAL_dwPhonebookMode, &dwMode );
  635. if (dwMode != 0xFFFFFFFF)
  636. {
  637. pUser->dwPhonebookMode = dwMode;
  638. fOldSettings = FALSE;
  639. }
  640. else
  641. fOldSettings = TRUE;
  642. }
  643. GetRegDword( hkey, REGVAL_fOperatorDial,
  644. &pUser->fOperatorDial );
  645. GetRegDword( hkey, REGVAL_fPreviewPhoneNumber,
  646. &pUser->fPreviewPhoneNumber );
  647. GetRegDword( hkey, REGVAL_fUseLocation,
  648. &pUser->fUseLocation );
  649. GetRegDword( hkey, REGVAL_fShowLights,
  650. &pUser->fShowLights );
  651. GetRegDword( hkey, REGVAL_fShowConnectStatus,
  652. &pUser->fShowConnectStatus );
  653. GetRegDword( hkey, REGVAL_fNewEntryWizard,
  654. &pUser->fNewEntryWizard );
  655. GetRegDword( hkey, REGVAL_fCloseOnDial,
  656. &pUser->fCloseOnDial );
  657. GetRegDword( hkey, REGVAL_fAllowLogonPhonebookEdits,
  658. &pUser->fAllowLogonPhonebookEdits );
  659. GetRegDword( hkey, REGVAL_fAllowLogonLocationEdits,
  660. &pUser->fAllowLogonLocationEdits );
  661. GetRegDword( hkey, REGVAL_fSkipConnectComplete,
  662. &pUser->fSkipConnectComplete );
  663. GetRegDword( hkey, REGVAL_dwRedialAttempts,
  664. &pUser->dwRedialAttempts );
  665. GetRegDword( hkey, REGVAL_dwRedialSeconds,
  666. &pUser->dwRedialSeconds );
  667. GetRegDword( hkey, REGVAL_dwIdleDisconnectSeconds,
  668. &pUser->dwIdleDisconnectSeconds );
  669. GetRegDword( hkey, REGVAL_fRedialOnLinkFailure,
  670. &pUser->fRedialOnLinkFailure );
  671. GetRegDword( hkey, REGVAL_fPopupOnTopWhenRedialing,
  672. &pUser->fPopupOnTopWhenRedialing );
  673. GetRegDword( hkey, REGVAL_fExpandAutoDialQuery,
  674. &pUser->fExpandAutoDialQuery );
  675. GetRegDword( hkey, REGVAL_dwCallbackMode,
  676. &pUser->dwCallbackMode );
  677. GetRegDword( hkey, REGVAL_fUseAreaAndCountry,
  678. &pUser->fUseAreaAndCountry );
  679. GetRegDword( hkey, REGVAL_dwXWindow,
  680. &pUser->dwXPhonebook );
  681. GetRegDword( hkey, REGVAL_dwYWindow,
  682. &pUser->dwYPhonebook );
  683. //
  684. // For NT5, we ignore the "require wizard" setting since
  685. // we always require the user to use the wizard to create
  686. // new connections
  687. //
  688. pUser->fNewEntryWizard = TRUE;
  689. do
  690. {
  691. GetCallbackList( hkey, &pUser->pdtllistCallback );
  692. dwErr = GetRegMultiSz( hkey, REGVAL_mszPhonebooks,
  693. &pUser->pdtllistPhonebooks, NT_Psz );
  694. if (dwErr != 0)
  695. break;
  696. dwErr = GetRegMultiSz( hkey, REGVAL_mszAreaCodes,
  697. &pUser->pdtllistAreaCodes, NT_Psz );
  698. if (dwErr != 0)
  699. break;
  700. /* If the prefixes key doesn't exist don't read an empty list over the
  701. ** defaults.
  702. */
  703. if (RegValueExists( hkey, REGVAL_mszPrefixes ))
  704. {
  705. dwErr = GetRegMultiSz( hkey, REGVAL_mszPrefixes,
  706. &pUser->pdtllistPrefixes, NT_Psz );
  707. if (dwErr != 0)
  708. break;
  709. }
  710. dwErr = GetRegMultiSz( hkey, REGVAL_mszSuffixes,
  711. &pUser->pdtllistSuffixes, NT_Psz );
  712. if (dwErr != 0)
  713. break;
  714. GetLocationList( hkey, &pUser->pdtllistLocations );
  715. dwErr = GetRegSz( hkey, REGVAL_szLastCallbackByCaller,
  716. &pUser->pszLastCallbackByCaller );
  717. if (dwErr != 0)
  718. break;
  719. /* Get the personal phonebook file name, if any. In NT 3.51, the full
  720. ** path was stored, but now "<nt>\system32\ras" directory is assumed.
  721. ** This gives better (not perfect) behavior with user profiles rooted
  722. ** on different drive letters.
  723. */
  724. {
  725. TCHAR* psz;
  726. dwErr = GetRegSz( hkey, REGVAL_szPersonalPhonebookPath, &psz );
  727. if (dwErr != 0)
  728. break;
  729. if (*psz == TEXT('\0'))
  730. {
  731. Free(psz);
  732. dwErr = GetRegSz( hkey, REGVAL_szPersonalPhonebookFile,
  733. &pUser->pszPersonalFile );
  734. if (dwErr != 0)
  735. break;
  736. }
  737. else
  738. {
  739. pUser->pszPersonalFile = StrDup( StripPath( psz ) );
  740. Free( psz );
  741. if (!pUser->pszPersonalFile)
  742. {
  743. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  744. break;
  745. }
  746. }
  747. }
  748. dwErr = GetRegSz( hkey, REGVAL_szAlternatePhonebookPath,
  749. &pUser->pszAlternatePath );
  750. if (dwErr != 0)
  751. break;
  752. dwErr = GetRegSz( hkey, REGVAL_szDefaultEntry,
  753. &pUser->pszDefaultEntry );
  754. if (dwErr != 0)
  755. break;
  756. if (fOldSettings)
  757. {
  758. TCHAR* psz;
  759. psz = NULL;
  760. dwErr = GetRegSz( hkey, REGVAL_szUsePersonalPhonebook, &psz );
  761. if (dwErr != 0)
  762. break;
  763. if (psz)
  764. {
  765. if (*psz == TEXT('1'))
  766. pUser->dwPhonebookMode = PBM_Personal;
  767. Free( psz );
  768. }
  769. }
  770. }
  771. while (FALSE);
  772. if (dwErr != 0)
  773. DestroyUserPreferences( pUser );
  774. TRACE1("ReadUserPreferences=%d",dwErr);
  775. return dwErr;
  776. }
  777. DWORD
  778. SetCallbackList(
  779. IN HKEY hkey,
  780. IN DTLLIST* pList )
  781. /* Sets callback tree under registry key 'hkey' to the list of callback
  782. ** nodes 'pList'.
  783. **
  784. ** Returns 0 if successful or an error code.
  785. */
  786. {
  787. DWORD dwErr;
  788. TCHAR szDP[ RAS_MaxDeviceName + 2 + MAX_PORT_NAME + 1 + 1 ];
  789. DWORD cb;
  790. DWORD i;
  791. DWORD dwDisposition;
  792. HKEY hkeyCb;
  793. HKEY hkeyDP;
  794. DTLNODE* pNode;
  795. dwErr = RegCreateKeyEx( hkey, REGKEY_Callback,
  796. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  797. &hkeyCb, &dwDisposition );
  798. if (dwErr != 0)
  799. return dwErr;
  800. /* Delete all keys and values under the callback key.
  801. */
  802. for (;;)
  803. {
  804. cb = sizeof(szDP);
  805. dwErr = RegEnumKeyEx(
  806. hkeyCb, 0, szDP, &cb, NULL, NULL, NULL, NULL );
  807. if (dwErr != 0)
  808. break;
  809. dwErr = RegDeleteKey( hkeyCb, szDP );
  810. if (dwErr != 0)
  811. break;
  812. }
  813. if (dwErr == ERROR_NO_MORE_ITEMS)
  814. dwErr = 0;
  815. if (dwErr == 0)
  816. {
  817. /* Add the new device/port sub-trees.
  818. */
  819. for (pNode = DtlGetFirstNode( pList );
  820. pNode;
  821. pNode = DtlGetNextNode( pNode ))
  822. {
  823. CALLBACKINFO* pInfo;
  824. TCHAR* psz;
  825. pInfo = (CALLBACKINFO* )DtlGetData( pNode );
  826. ASSERT(pInfo);
  827. ASSERT(pInfo->pszPortName);
  828. ASSERT(pInfo->pszDeviceName);
  829. ASSERT(pInfo->pszNumber);
  830. psz = PszFromDeviceAndPort(
  831. pInfo->pszDeviceName, pInfo->pszPortName );
  832. if (psz)
  833. {
  834. dwErr = RegCreateKeyEx( hkeyCb, psz, 0, TEXT(""),
  835. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyDP,
  836. &dwDisposition );
  837. if (dwErr != 0)
  838. break;
  839. dwErr = SetRegDword( hkeyDP, REGVAL_dwDeviceType,
  840. pInfo->dwDeviceType );
  841. if (dwErr == 0)
  842. {
  843. dwErr = SetRegSz( hkeyDP,
  844. REGVAL_szNumber, pInfo->pszNumber );
  845. }
  846. RegCloseKey( hkeyDP );
  847. }
  848. else
  849. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  850. if (dwErr != 0)
  851. break;
  852. }
  853. }
  854. RegCloseKey( hkeyCb );
  855. return dwErr;
  856. }
  857. DWORD
  858. SetDefaultUserPreferences(
  859. OUT PBUSER* pUser,
  860. IN DWORD dwMode )
  861. /* Fill caller's 'pUser' buffer with default user preferences. 'DwMode'
  862. ** indicates the type of user preferences.
  863. **
  864. ** Returns 0 if successful, false otherwise.
  865. */
  866. {
  867. DTLNODE* pNode;
  868. /* Set defaults.
  869. */
  870. CopyMemory( pUser, &g_pbuserDefaults, sizeof(*pUser) );
  871. pUser->pdtllistCallback = DtlCreateList( 0L );
  872. pUser->pdtllistPhonebooks = DtlCreateList( 0L );
  873. pUser->pdtllistAreaCodes = DtlCreateList( 0L );
  874. pUser->pdtllistPrefixes = DtlCreateList( 0L );
  875. pUser->pdtllistSuffixes = DtlCreateList( 0L );
  876. pUser->pdtllistLocations = DtlCreateList( 0L );
  877. if (!pUser->pdtllistCallback
  878. || !pUser->pdtllistPhonebooks
  879. || !pUser->pdtllistAreaCodes
  880. || !pUser->pdtllistPrefixes
  881. || !pUser->pdtllistSuffixes
  882. || !pUser->pdtllistLocations)
  883. {
  884. /* Can't even get empty lists, so we're forced to return an error.
  885. */
  886. DestroyUserPreferences( pUser );
  887. return ERROR_NOT_ENOUGH_MEMORY;
  888. }
  889. /* Add the default prefixes.
  890. */
  891. pNode = CreatePszNode( TEXT("0,") );
  892. if (pNode)
  893. DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
  894. pNode = CreatePszNode( TEXT("9,") );
  895. if (pNode)
  896. DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
  897. pNode = CreatePszNode( TEXT("8,") );
  898. if (pNode)
  899. DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
  900. pNode = CreatePszNode( TEXT("70#") );
  901. if (pNode)
  902. DtlAddNodeLast( pUser->pdtllistPrefixes, pNode );
  903. if (dwMode == UPM_Logon)
  904. {
  905. ASSERT(pUser->dwPhonebookMode!=PBM_Personal);
  906. pUser->fShowLights = FALSE;
  907. pUser->fSkipConnectComplete = TRUE;
  908. }
  909. if (dwMode == UPM_Router)
  910. {
  911. pUser->dwCallbackMode = CBM_No;
  912. }
  913. pUser->fInitialized = TRUE;
  914. return 0;
  915. }
  916. DWORD
  917. SetLocationList(
  918. IN HKEY hkey,
  919. IN DTLLIST* pList )
  920. /* Sets by-location tree under registry key 'hkey' to the list of
  921. ** by-location nodes 'pList'.
  922. **
  923. ** Returns 0 if successful or an error code.
  924. */
  925. {
  926. DWORD dwErr;
  927. TCHAR szId[ MAXLTOTLEN + 1 ];
  928. DWORD cb;
  929. DWORD i;
  930. DWORD dwDisposition;
  931. HKEY hkeyL;
  932. HKEY hkeyId;
  933. DTLNODE* pNode;
  934. dwErr = RegCreateKeyEx( hkey, REGKEY_Location,
  935. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  936. &hkeyL, &dwDisposition );
  937. if (dwErr != 0)
  938. return dwErr;
  939. /* Delete all keys and values under the location key.
  940. */
  941. for (;;)
  942. {
  943. cb = MAXLTOTLEN + 1;
  944. dwErr = RegEnumKeyEx( hkeyL, 0, szId, &cb, NULL, NULL, NULL, NULL );
  945. if (dwErr != 0)
  946. break;
  947. dwErr = RegDeleteKey( hkeyL, szId );
  948. if (dwErr != 0)
  949. break;
  950. }
  951. if (dwErr == ERROR_NO_MORE_ITEMS)
  952. dwErr = 0;
  953. if (dwErr == 0)
  954. {
  955. /* Add the new ID sub-trees.
  956. */
  957. for (pNode = DtlGetFirstNode( pList );
  958. pNode;
  959. pNode = DtlGetNextNode( pNode ))
  960. {
  961. LOCATIONINFO* pInfo;
  962. pInfo = (LOCATIONINFO* )DtlGetData( pNode );
  963. ASSERT(pInfo);
  964. LToT( pInfo->dwLocationId, szId, 10 );
  965. dwErr = RegCreateKeyEx( hkeyL, szId, 0, TEXT(""),
  966. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyId,
  967. &dwDisposition );
  968. if (dwErr != 0)
  969. break;
  970. dwErr = SetRegDword( hkeyId, REGVAL_dwPrefix, pInfo->iPrefix );
  971. if (dwErr == 0)
  972. dwErr = SetRegDword( hkeyId, REGVAL_dwSuffix, pInfo->iSuffix );
  973. RegCloseKey( hkeyId );
  974. if (dwErr != 0)
  975. break;
  976. }
  977. }
  978. RegCloseKey( hkeyL );
  979. return dwErr;
  980. }
  981. DWORD
  982. WriteUserPreferences(
  983. IN HKEY hkey,
  984. IN PBUSER* pUser )
  985. /* Write user preferences 'pUser' at RAS-Phonebook registry key 'hkey'.
  986. **
  987. ** Returns 0 if successful or an error code.
  988. */
  989. {
  990. DWORD dwErr;
  991. TRACE("WriteUserPreferences");
  992. do
  993. {
  994. dwErr = SetRegDword( hkey, REGVAL_fOperatorDial,
  995. pUser->fOperatorDial );
  996. if (dwErr != 0)
  997. break;
  998. dwErr = SetRegDword( hkey, REGVAL_fPreviewPhoneNumber,
  999. pUser->fPreviewPhoneNumber );
  1000. if (dwErr != 0)
  1001. break;
  1002. dwErr = SetRegDword( hkey, REGVAL_fUseLocation,
  1003. pUser->fUseLocation );
  1004. if (dwErr != 0)
  1005. break;
  1006. dwErr = SetRegDword( hkey, REGVAL_fShowLights,
  1007. pUser->fShowLights );
  1008. if (dwErr != 0)
  1009. break;
  1010. dwErr = SetRegDword( hkey, REGVAL_fShowConnectStatus,
  1011. pUser->fShowConnectStatus );
  1012. if (dwErr != 0)
  1013. break;
  1014. dwErr = SetRegDword( hkey, REGVAL_fNewEntryWizard,
  1015. pUser->fNewEntryWizard );
  1016. if (dwErr != 0)
  1017. break;
  1018. dwErr = SetRegDword( hkey, REGVAL_fCloseOnDial,
  1019. pUser->fCloseOnDial );
  1020. if (dwErr != 0)
  1021. break;
  1022. dwErr = SetRegDword( hkey, REGVAL_fAllowLogonPhonebookEdits,
  1023. pUser->fAllowLogonPhonebookEdits );
  1024. if (dwErr != 0)
  1025. break;
  1026. dwErr = SetRegDword( hkey, REGVAL_fAllowLogonLocationEdits,
  1027. pUser->fAllowLogonLocationEdits );
  1028. if (dwErr != 0)
  1029. break;
  1030. dwErr = SetRegDword( hkey, REGVAL_fSkipConnectComplete,
  1031. pUser->fSkipConnectComplete );
  1032. if (dwErr != 0)
  1033. break;
  1034. dwErr = SetRegDword( hkey, REGVAL_dwRedialAttempts,
  1035. pUser->dwRedialAttempts );
  1036. if (dwErr != 0)
  1037. break;
  1038. dwErr = SetRegDword( hkey, REGVAL_dwRedialSeconds,
  1039. pUser->dwRedialSeconds );
  1040. if (dwErr != 0)
  1041. break;
  1042. dwErr = SetRegDword( hkey, REGVAL_dwIdleDisconnectSeconds,
  1043. pUser->dwIdleDisconnectSeconds );
  1044. if (dwErr != 0)
  1045. break;
  1046. dwErr = SetRegDword( hkey, REGVAL_fRedialOnLinkFailure,
  1047. pUser->fRedialOnLinkFailure );
  1048. if (dwErr != 0)
  1049. break;
  1050. dwErr = SetRegDword( hkey, REGVAL_fPopupOnTopWhenRedialing,
  1051. pUser->fPopupOnTopWhenRedialing );
  1052. if (dwErr != 0)
  1053. break;
  1054. dwErr = SetRegDword( hkey, REGVAL_fExpandAutoDialQuery,
  1055. pUser->fExpandAutoDialQuery );
  1056. if (dwErr != 0)
  1057. break;
  1058. dwErr = SetRegDword( hkey, REGVAL_dwCallbackMode,
  1059. pUser->dwCallbackMode );
  1060. if (dwErr != 0)
  1061. break;
  1062. dwErr = SetRegDword( hkey, REGVAL_dwPhonebookMode,
  1063. pUser->dwPhonebookMode );
  1064. if (dwErr != 0)
  1065. break;
  1066. dwErr = SetRegDword( hkey, REGVAL_fUseAreaAndCountry,
  1067. pUser->fUseAreaAndCountry );
  1068. if (dwErr != 0)
  1069. break;
  1070. dwErr = SetRegDword( hkey, REGVAL_dwXWindow,
  1071. pUser->dwXPhonebook );
  1072. if (dwErr != 0)
  1073. break;
  1074. dwErr = SetRegDword( hkey, REGVAL_dwYWindow,
  1075. pUser->dwYPhonebook );
  1076. dwErr = SetCallbackList( hkey, pUser->pdtllistCallback );
  1077. if (dwErr != 0)
  1078. break;
  1079. dwErr = SetRegMultiSz( hkey, REGVAL_mszPhonebooks,
  1080. pUser->pdtllistPhonebooks, NT_Psz );
  1081. if (dwErr != 0)
  1082. break;
  1083. dwErr = SetRegMultiSz( hkey, REGVAL_mszAreaCodes,
  1084. pUser->pdtllistAreaCodes, NT_Psz );
  1085. if (dwErr != 0)
  1086. break;
  1087. dwErr = SetRegMultiSz( hkey, REGVAL_mszPrefixes,
  1088. pUser->pdtllistPrefixes, NT_Psz );
  1089. if (dwErr != 0)
  1090. break;
  1091. dwErr = SetRegMultiSz( hkey, REGVAL_mszSuffixes,
  1092. pUser->pdtllistSuffixes, NT_Psz );
  1093. if (dwErr != 0)
  1094. break;
  1095. dwErr = SetLocationList( hkey, pUser->pdtllistLocations );
  1096. if (dwErr != 0)
  1097. break;
  1098. dwErr = SetRegSz( hkey, REGVAL_szLastCallbackByCaller,
  1099. pUser->pszLastCallbackByCaller );
  1100. if (dwErr != 0)
  1101. break;
  1102. dwErr = SetRegSz( hkey, REGVAL_szPersonalPhonebookFile,
  1103. pUser->pszPersonalFile );
  1104. if (dwErr != 0)
  1105. break;
  1106. dwErr = SetRegSz( hkey, REGVAL_szAlternatePhonebookPath,
  1107. pUser->pszAlternatePath );
  1108. if (dwErr != 0)
  1109. break;
  1110. dwErr = SetRegSz( hkey, REGVAL_szDefaultEntry,
  1111. pUser->pszDefaultEntry );
  1112. if (dwErr != 0)
  1113. break;
  1114. RegDeleteValue( hkey, REGVAL_szPersonalPhonebookPath );
  1115. }
  1116. while (FALSE);
  1117. if (dwErr == 0)
  1118. pUser->fDirty = FALSE;
  1119. TRACE1("WriteUserPreferences=%d",dwErr);
  1120. return dwErr;
  1121. }