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.

4212 lines
122 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rasmig.c
  5. Abstract:
  6. <abstract>
  7. Author:
  8. Calin Negreanu (calinn) 08 Mar 2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "logmsg.h"
  17. #include <ras.h>
  18. #include <raserror.h>
  19. #define DBG_RASMIG "RasMig"
  20. #define SIZEOF_STRUCT(structname, uptomember) ((int)((LPBYTE)(&((structname*)0)->uptomember) - ((LPBYTE)((structname*)0))))
  21. //
  22. // Strings
  23. //
  24. #define S_RAS_POOL_NAME "RasConnection"
  25. #define S_RAS_NAME TEXT("RasConnection")
  26. #define S_PBKFILE_ATTRIBUTE TEXT("PbkFile")
  27. #ifdef UNICODE
  28. #define S_RASAPI_RASSETCREDENTIALS "RasSetCredentialsW"
  29. #define S_RASAPI_RASDELETEENTRY "RasDeleteEntryW"
  30. #else
  31. #define S_RASAPI_RASSETCREDENTIALS "RasSetCredentialsA"
  32. #define S_RASAPI_RASDELETEENTRY "RasDeleteEntryA"
  33. #endif
  34. //
  35. // Constants
  36. //
  37. // None
  38. //
  39. // Macros
  40. //
  41. // None
  42. //
  43. // Types
  44. //
  45. // RAS api functions
  46. typedef DWORD(WINAPI RASGETCREDENTIALSA)(
  47. IN LPCSTR lpszPhonebook,
  48. IN LPCSTR lpszEntry,
  49. OUT LPRASCREDENTIALSA lpRasCredentials
  50. );
  51. typedef RASGETCREDENTIALSA *PRASGETCREDENTIALSA;
  52. typedef DWORD(WINAPI RASSETCREDENTIALS)(
  53. IN LPCTSTR lpszPhonebook,
  54. IN LPCTSTR lpszEntry,
  55. IN LPRASCREDENTIALS lpRasCredentials,
  56. IN BOOL fClearCredentials
  57. );
  58. typedef RASSETCREDENTIALS *PRASSETCREDENTIALS;
  59. typedef DWORD(WINAPI RASDELETEENTRY)(
  60. IN LPCTSTR lpszPhonebook,
  61. IN LPCTSTR lpszEntry
  62. );
  63. typedef RASDELETEENTRY *PRASDELETEENTRY;
  64. typedef struct {
  65. PCTSTR Pattern;
  66. HASHTABLE_ENUM HashData;
  67. } RAS_ENUM, *PRAS_ENUM;
  68. //
  69. // Globals
  70. //
  71. PMHANDLE g_RasPool = NULL;
  72. HASHTABLE g_RasTable;
  73. MIG_OBJECTTYPEID g_RasTypeId = 0;
  74. static MIG_OBJECTTYPEID g_FileTypeId = 0;
  75. MIG_ATTRIBUTEID g_PbkFileAttribute = 0;
  76. BOOL g_AllowPbkRestore = FALSE;
  77. GROWBUFFER g_RasConversionBuff = INIT_GROWBUFFER;
  78. MIG_OBJECTSTRINGHANDLE g_Win9xPbkFile = NULL;
  79. BOOL g_SrcOSNT4 = FALSE;
  80. BOOL g_FirstRasPair = FALSE;
  81. BOOL g_DelayRasOp = FALSE;
  82. // RAS api functions
  83. PRASGETCREDENTIALSA g_RasGetCredentialsA = NULL;
  84. PRASSETCREDENTIALS g_RasSetCredentials = NULL;
  85. PRASDELETEENTRY g_RasDeleteEntry = NULL;
  86. //
  87. // Macro expansion list
  88. //
  89. // None
  90. //
  91. // Private function prototypes
  92. //
  93. // None
  94. //
  95. // Macro expansion definition
  96. //
  97. // None
  98. //
  99. // Private prototypes
  100. //
  101. SGMENUMERATIONCALLBACK SgmRasConnectionsCallback;
  102. VCMENUMERATIONCALLBACK VcmRasConnectionsCallback;
  103. TYPE_ENUMFIRSTPHYSICALOBJECT EnumFirstRasConnection;
  104. TYPE_ENUMNEXTPHYSICALOBJECT EnumNextRasConnection;
  105. TYPE_ABORTENUMPHYSICALOBJECT AbortEnumRasConnection;
  106. TYPE_CONVERTOBJECTTOMULTISZ ConvertRasConnectionToMultiSz;
  107. TYPE_CONVERTMULTISZTOOBJECT ConvertMultiSzToRasConnection;
  108. TYPE_GETNATIVEOBJECTNAME GetNativeRasConnectionName;
  109. TYPE_ACQUIREPHYSICALOBJECT AcquireRasConnection;
  110. TYPE_RELEASEPHYSICALOBJECT ReleaseRasConnection;
  111. TYPE_DOESPHYSICALOBJECTEXIST DoesRasConnectionExist;
  112. TYPE_REMOVEPHYSICALOBJECT RemoveRasConnection;
  113. TYPE_CREATEPHYSICALOBJECT CreateRasConnection;
  114. TYPE_CONVERTOBJECTCONTENTTOUNICODE ConvertRasConnectionContentToUnicode;
  115. TYPE_CONVERTOBJECTCONTENTTOANSI ConvertRasConnectionContentToAnsi;
  116. TYPE_FREECONVERTEDOBJECTCONTENT FreeConvertedRasConnectionContent;
  117. MIG_OBJECTENUMCALLBACK PbkFilesCallback;
  118. MIG_RESTORECALLBACK PbkRestoreCallback;
  119. OPMFILTERCALLBACK FilterRasAutoFilter;
  120. PCTSTR
  121. pCreate9xPbkFile (
  122. VOID
  123. );
  124. //
  125. // Code
  126. //
  127. BOOL
  128. RasMigInitialize (
  129. VOID
  130. )
  131. {
  132. g_RasTable = HtAllocWithData (sizeof (PCTSTR));
  133. if (!g_RasTable) {
  134. return FALSE;
  135. }
  136. g_RasPool = PmCreateNamedPool (S_RAS_POOL_NAME);
  137. if (!g_RasPool) {
  138. return FALSE;
  139. }
  140. return TRUE;
  141. }
  142. VOID
  143. RasMigTerminate (
  144. VOID
  145. )
  146. {
  147. HASHTABLE_ENUM e;
  148. PCTSTR nativeName;
  149. PCTSTR rasData = NULL;
  150. if (g_Win9xPbkFile) {
  151. nativeName = IsmGetNativeObjectName (
  152. g_FileTypeId,
  153. g_Win9xPbkFile
  154. );
  155. if (nativeName) {
  156. DeleteFile (nativeName);
  157. IsmReleaseMemory (nativeName);
  158. }
  159. IsmDestroyObjectHandle (g_Win9xPbkFile);
  160. g_Win9xPbkFile = NULL;
  161. }
  162. GbFree (&g_RasConversionBuff);
  163. if (g_RasTable) {
  164. if (EnumFirstHashTableString (&e, g_RasTable)) {
  165. do {
  166. rasData = *(PCTSTR *)(e.ExtraData);
  167. PmReleaseMemory (g_RasPool, rasData);
  168. } while (EnumNextHashTableString (&e));
  169. }
  170. HtFree (g_RasTable);
  171. g_RasTable = NULL;
  172. }
  173. if (g_RasPool) {
  174. PmDestroyPool (g_RasPool);
  175. g_RasPool = NULL;
  176. }
  177. }
  178. BOOL
  179. pLoadRasEntries (
  180. BOOL LeftSide
  181. )
  182. {
  183. HMODULE rasDll = NULL;
  184. BOOL result = FALSE;
  185. __try {
  186. rasDll = LoadLibrary (TEXT("RASAPI32.DLL"));
  187. }
  188. __except (EXCEPTION_EXECUTE_HANDLER) {
  189. rasDll = NULL;
  190. }
  191. if (rasDll) {
  192. if (LeftSide) {
  193. g_RasGetCredentialsA = (PRASGETCREDENTIALSA) GetProcAddress (rasDll, "RasGetCredentialsA");
  194. } else {
  195. g_RasSetCredentials = (PRASSETCREDENTIALS) GetProcAddress (rasDll, S_RASAPI_RASSETCREDENTIALS);
  196. g_RasDeleteEntry = (PRASDELETEENTRY) GetProcAddress (rasDll, S_RASAPI_RASDELETEENTRY);
  197. }
  198. } else {
  199. DEBUGMSG ((DBG_RASMIG, "RAS is not installed on this computer."));
  200. }
  201. return result;
  202. }
  203. BOOL
  204. pAddWin9xPbkObject (
  205. VOID
  206. )
  207. {
  208. g_Win9xPbkFile = pCreate9xPbkFile ();
  209. return (g_Win9xPbkFile != NULL);
  210. }
  211. BOOL
  212. WINAPI
  213. RasMigEtmInitialize (
  214. IN MIG_PLATFORMTYPEID Platform,
  215. IN PMIG_LOGCALLBACK LogCallback,
  216. IN PVOID Reserved
  217. )
  218. {
  219. MIG_OSVERSIONINFO versionInfo;
  220. TYPE_REGISTER rasConnTypeData;
  221. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  222. g_FileTypeId = MIG_FILE_TYPE;
  223. ZeroMemory (&rasConnTypeData, sizeof (TYPE_REGISTER));
  224. rasConnTypeData.Priority = PRIORITY_RASCONNECTION;
  225. if (Platform == PLATFORM_SOURCE) {
  226. rasConnTypeData.EnumFirstPhysicalObject = EnumFirstRasConnection;
  227. rasConnTypeData.EnumNextPhysicalObject = EnumNextRasConnection;
  228. rasConnTypeData.AbortEnumPhysicalObject = AbortEnumRasConnection;
  229. rasConnTypeData.ConvertObjectToMultiSz = ConvertRasConnectionToMultiSz;
  230. rasConnTypeData.ConvertMultiSzToObject = ConvertMultiSzToRasConnection;
  231. rasConnTypeData.GetNativeObjectName = GetNativeRasConnectionName;
  232. rasConnTypeData.AcquirePhysicalObject = AcquireRasConnection;
  233. rasConnTypeData.ReleasePhysicalObject = ReleaseRasConnection;
  234. rasConnTypeData.ConvertObjectContentToUnicode = ConvertRasConnectionContentToUnicode;
  235. rasConnTypeData.ConvertObjectContentToAnsi = ConvertRasConnectionContentToAnsi;
  236. rasConnTypeData.FreeConvertedObjectContent = FreeConvertedRasConnectionContent;
  237. g_RasTypeId = IsmRegisterObjectType (
  238. S_RAS_NAME,
  239. TRUE,
  240. FALSE,
  241. &rasConnTypeData
  242. );
  243. pLoadRasEntries (TRUE);
  244. if (IsmGetOsVersionInfo (Platform, &versionInfo)) {
  245. if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
  246. // now it's time to convert registry into a PBK file
  247. pAddWin9xPbkObject ();
  248. }
  249. if ((versionInfo.OsType == OSTYPE_WINDOWSNT) &&
  250. (versionInfo.OsMajorVersion == OSMAJOR_WINNT4)
  251. ) {
  252. g_SrcOSNT4 = TRUE;
  253. }
  254. }
  255. } else {
  256. rasConnTypeData.ConvertObjectToMultiSz = ConvertRasConnectionToMultiSz;
  257. rasConnTypeData.ConvertMultiSzToObject = ConvertMultiSzToRasConnection;
  258. rasConnTypeData.GetNativeObjectName = GetNativeRasConnectionName;
  259. rasConnTypeData.DoesPhysicalObjectExist = DoesRasConnectionExist;
  260. rasConnTypeData.RemovePhysicalObject = RemoveRasConnection;
  261. rasConnTypeData.CreatePhysicalObject = CreateRasConnection;
  262. rasConnTypeData.ConvertObjectContentToUnicode = ConvertRasConnectionContentToUnicode;
  263. rasConnTypeData.ConvertObjectContentToAnsi = ConvertRasConnectionContentToAnsi;
  264. rasConnTypeData.FreeConvertedObjectContent = FreeConvertedRasConnectionContent;
  265. g_RasTypeId = IsmRegisterObjectType (
  266. S_RAS_NAME,
  267. TRUE,
  268. FALSE,
  269. &rasConnTypeData
  270. );
  271. pLoadRasEntries (FALSE);
  272. if (IsmGetOsVersionInfo (Platform, &versionInfo)) {
  273. if ((versionInfo.OsType == OSTYPE_WINDOWSNT) &&
  274. (versionInfo.OsMajorVersion == OSMAJOR_WINNT4)
  275. ) {
  276. g_SrcOSNT4 = TRUE;
  277. }
  278. }
  279. }
  280. MYASSERT (g_RasTypeId);
  281. return TRUE;
  282. }
  283. PCTSTR
  284. pGetNextRasConnection (
  285. IN HANDLE PbkHandle
  286. )
  287. {
  288. CHAR input = 0;
  289. ULONGLONG beginPos = 0;
  290. ULONGLONG endPos = 0;
  291. ULONGLONG lastPos = 0;
  292. PSTR resultTmp = NULL;
  293. PTSTR result = NULL;
  294. #ifdef UNICODE
  295. WORD oldCodePage;
  296. DWORD sizeW = 0;
  297. PWSTR resultW = NULL;
  298. #endif
  299. while (TRUE) {
  300. if (!BfReadFile (PbkHandle, (PBYTE)(&input), sizeof (CHAR))) {
  301. break;
  302. }
  303. if (input == '[') {
  304. if (!beginPos) {
  305. BfGetFilePointer (PbkHandle, &beginPos);
  306. }
  307. }
  308. if (input == ']') {
  309. if (beginPos) {
  310. if (!endPos) {
  311. BfGetFilePointer (PbkHandle, &endPos);
  312. endPos --;
  313. } else {
  314. beginPos = 0;
  315. endPos = 0;
  316. }
  317. }
  318. }
  319. if (input == '\n') {
  320. if (beginPos && endPos && (endPos > beginPos)) {
  321. BfGetFilePointer (PbkHandle, &lastPos);
  322. BfSetFilePointer (PbkHandle, beginPos);
  323. resultTmp = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
  324. if (!BfReadFile (PbkHandle, (PBYTE) resultTmp, (UINT) (endPos - beginPos) + 1)) {
  325. PmReleaseMemory (g_RasPool, resultTmp);
  326. resultTmp = NULL;
  327. } else {
  328. resultTmp [(UINT) (endPos - beginPos)] = 0;
  329. }
  330. BfSetFilePointer (PbkHandle, lastPos);
  331. break;
  332. }
  333. beginPos = 0;
  334. endPos = 0;
  335. }
  336. }
  337. #ifdef UNICODE
  338. if (resultTmp) {
  339. if (!g_SrcOSNT4) {
  340. // make sure that the conversion is using UTF8
  341. oldCodePage = SetConversionCodePage (CP_UTF8);
  342. }
  343. sizeW = SizeOfStringA(resultTmp);
  344. resultW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
  345. if (resultW) {
  346. KnownSizeAtoW (resultW, resultTmp);
  347. }
  348. if (!g_SrcOSNT4) {
  349. SetConversionCodePage (oldCodePage);
  350. }
  351. if (resultW) {
  352. result = PmDuplicateStringW (g_RasPool, resultW);
  353. PmReleaseMemory (g_RasPool, resultW);
  354. resultW = NULL;
  355. }
  356. }
  357. #else
  358. result = resultTmp;
  359. #endif
  360. return result;
  361. }
  362. BOOL
  363. pGetNextRasPair (
  364. IN HANDLE PbkHandle,
  365. OUT PCTSTR *ValueName,
  366. OUT PCTSTR *Value
  367. )
  368. {
  369. BOOL error = FALSE;
  370. CHAR input = 0;
  371. ULONGLONG beginPos = 0;
  372. ULONGLONG endPos = 0;
  373. ULONGLONG lastPos = 0;
  374. BOOL begin = TRUE;
  375. BOOL inValue = FALSE;
  376. PSTR valueName = NULL;
  377. PSTR value = NULL;
  378. #ifdef UNICODE
  379. WORD oldCodePage;
  380. DWORD sizeW = 0;
  381. PWSTR valueNameW = NULL;
  382. PWSTR valueW = NULL;
  383. #endif
  384. BfGetFilePointer (PbkHandle, &beginPos);
  385. while (TRUE) {
  386. if (!BfReadFile (PbkHandle, (PBYTE)(&input), sizeof (CHAR))) {
  387. error = TRUE;
  388. break;
  389. }
  390. if ((input == '[') && begin) {
  391. BfSetFilePointer (PbkHandle, beginPos);
  392. error = TRUE;
  393. break;
  394. }
  395. if ((input == ' ') && begin) {
  396. continue;
  397. }
  398. begin = FALSE;
  399. if (input == '=') {
  400. if (!inValue) {
  401. BfGetFilePointer (PbkHandle, &endPos);
  402. endPos --;
  403. if (endPos > beginPos) {
  404. BfGetFilePointer (PbkHandle, &lastPos);
  405. BfSetFilePointer (PbkHandle, beginPos);
  406. valueName = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
  407. if (!BfReadFile (PbkHandle, (PBYTE) valueName, (UINT) (endPos - beginPos) + 1)) {
  408. error = TRUE;
  409. break;
  410. } else {
  411. valueName [(UINT) (endPos - beginPos)] = 0;
  412. }
  413. BfSetFilePointer (PbkHandle, lastPos);
  414. }
  415. BfGetFilePointer (PbkHandle, &beginPos);
  416. inValue = TRUE;
  417. }
  418. continue;
  419. }
  420. if (input == '\r') {
  421. BfGetFilePointer (PbkHandle, &endPos);
  422. endPos --;
  423. continue;
  424. }
  425. if (input == '\n') {
  426. if (endPos > beginPos) {
  427. BfGetFilePointer (PbkHandle, &lastPos);
  428. BfSetFilePointer (PbkHandle, beginPos);
  429. if (inValue) {
  430. value = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
  431. if (!BfReadFile (PbkHandle, (PBYTE) value, (UINT) (endPos - beginPos) + 1)) {
  432. error = TRUE;
  433. break;
  434. } else {
  435. value [(UINT) (endPos - beginPos)] = 0;
  436. }
  437. } else {
  438. valueName = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
  439. if (!BfReadFile (PbkHandle, (PBYTE) valueName, (UINT) (endPos - beginPos) + 1)) {
  440. error = TRUE;
  441. break;
  442. } else {
  443. valueName [(UINT) (endPos - beginPos)] = 0;
  444. }
  445. }
  446. BfSetFilePointer (PbkHandle, lastPos);
  447. }
  448. break;
  449. }
  450. }
  451. if (error) {
  452. if (valueName) {
  453. PmReleaseMemory (g_RasPool, valueName);
  454. valueName = NULL;
  455. }
  456. if (value) {
  457. PmReleaseMemory (g_RasPool, value);
  458. value = NULL;
  459. }
  460. }
  461. // if this is NT4 and this is the first time we are called,
  462. // we look to see if the first pair is the "Encoding=1" one.
  463. // If not, we are going to return it anyway and leave the
  464. // current read pair for the next time.
  465. if (g_SrcOSNT4 &&
  466. valueName &&
  467. g_FirstRasPair &&
  468. !StringIMatchA (valueName, "Encoding")
  469. ) {
  470. g_FirstRasPair = FALSE;
  471. // set the pointer to where we initially found it
  472. BfSetFilePointer (PbkHandle, beginPos);
  473. // free the valueName and value if needed
  474. PmReleaseMemory (g_RasPool, valueName);
  475. if (value) {
  476. PmReleaseMemory (g_RasPool, value);
  477. }
  478. valueName = PmDuplicateStringA (g_RasPool, "Encoding");
  479. value = PmDuplicateStringA (g_RasPool, "1");
  480. }
  481. #ifdef UNICODE
  482. if (ValueName) {
  483. if (valueName) {
  484. if (!g_SrcOSNT4) {
  485. // make sure that the conversion is using UTF8
  486. oldCodePage = SetConversionCodePage (CP_UTF8);
  487. }
  488. sizeW = SizeOfStringA (valueName);
  489. valueNameW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
  490. if (valueNameW) {
  491. KnownSizeAtoW (valueNameW, valueName);
  492. }
  493. if (!g_SrcOSNT4) {
  494. SetConversionCodePage (oldCodePage);
  495. }
  496. if (valueNameW) {
  497. *ValueName = PmDuplicateStringW (g_RasPool, valueNameW);
  498. PmReleaseMemory (g_RasPool, valueNameW);
  499. }
  500. } else {
  501. *ValueName = NULL;
  502. }
  503. }
  504. if (Value) {
  505. if (value) {
  506. if (!g_SrcOSNT4) {
  507. // make sure that the conversion is using UTF8
  508. oldCodePage = SetConversionCodePage (CP_UTF8);
  509. }
  510. sizeW = SizeOfStringA(value);
  511. valueW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
  512. if (valueW) {
  513. KnownSizeAtoW (valueW, value);
  514. }
  515. if (!g_SrcOSNT4) {
  516. SetConversionCodePage (oldCodePage);
  517. }
  518. if (valueW) {
  519. *Value = PmDuplicateStringW (g_RasPool, valueW);
  520. PmReleaseMemory (g_RasPool, valueW);
  521. }
  522. } else {
  523. *Value = NULL;
  524. }
  525. }
  526. #else
  527. if (ValueName) {
  528. *ValueName = valueName;
  529. }
  530. if (Value) {
  531. *Value = value;
  532. }
  533. #endif
  534. return !error;
  535. }
  536. PCTSTR
  537. pGetRasLineValue (
  538. IN PCTSTR RasLines,
  539. IN PCTSTR ValueName
  540. )
  541. {
  542. MULTISZ_ENUM multiSzEnum;
  543. BOOL first = TRUE;
  544. BOOL found = FALSE;
  545. if (EnumFirstMultiSz (&multiSzEnum, RasLines)) {
  546. do {
  547. if (found) {
  548. return multiSzEnum.CurrentString;
  549. }
  550. if (first && StringIMatch (multiSzEnum.CurrentString, ValueName)) {
  551. found = TRUE;
  552. }
  553. first = !first;
  554. } while (EnumNextMultiSz (&multiSzEnum));
  555. }
  556. return NULL;
  557. }
  558. BOOL
  559. pLoadRasConnections (
  560. IN PCTSTR PbkFileName,
  561. IN HASHTABLE RasTable
  562. )
  563. {
  564. HANDLE pbkFileHandle;
  565. PCTSTR entryName;
  566. PCTSTR valueName;
  567. PCTSTR value;
  568. GROWBUFFER rasLines = INIT_GROWBUFFER;
  569. PTSTR rasLinesStr;
  570. MIG_OBJECTSTRINGHANDLE rasConnectionName;
  571. RASCREDENTIALSA rasCredentials;
  572. TCHAR valueStr [sizeof (DWORD) * 2 + 3];
  573. DWORD err;
  574. MIG_OSVERSIONINFO versionInfo;
  575. BOOL versionOk = FALSE;
  576. BOOL inMedia = FALSE;
  577. BOOL result = FALSE;
  578. #ifdef UNICODE
  579. PCSTR tempStr1 = NULL;
  580. PCSTR tempStr2 = NULL;
  581. PCWSTR tempStr3 = NULL;
  582. #endif
  583. if (!RasTable) {
  584. return FALSE;
  585. }
  586. pbkFileHandle = BfOpenReadFile (PbkFileName);
  587. if (pbkFileHandle) {
  588. while (TRUE) {
  589. // get the next RAS connection
  590. entryName = pGetNextRasConnection (pbkFileHandle);
  591. if (!entryName) {
  592. break;
  593. }
  594. rasLines.End = 0;
  595. GbMultiSzAppend (&rasLines, TEXT("ConnectionName"));
  596. GbMultiSzAppend (&rasLines, entryName);
  597. versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
  598. // we use credentials API only on NT, on win9x the conversion code will automatically insert the fields
  599. if (!versionOk || (versionInfo.OsType != OSTYPE_WINDOWS9X)) {
  600. err = ERROR_INVALID_DATA;
  601. if (g_RasGetCredentialsA) {
  602. ZeroMemory (&rasCredentials, sizeof (RASCREDENTIALSA));
  603. rasCredentials.dwSize = sizeof (RASCREDENTIALSA);
  604. rasCredentials.dwMask = RASCM_UserName | RASCM_Domain | RASCM_Password;
  605. #ifdef UNICODE
  606. tempStr1 = ConvertWtoA (PbkFileName);
  607. tempStr2 = ConvertWtoA (entryName);
  608. err = g_RasGetCredentialsA (tempStr1, tempStr2, &rasCredentials);
  609. FreeConvertedStr (tempStr1);
  610. FreeConvertedStr (tempStr2);
  611. #else
  612. err = g_RasGetCredentialsA (PbkFileName, entryName, &rasCredentials);
  613. #endif
  614. if (!err) {
  615. wsprintf (valueStr, TEXT("0x%08X"), rasCredentials.dwMask);
  616. GbMultiSzAppend (&rasLines, TEXT("CredMask"));
  617. GbMultiSzAppend (&rasLines, valueStr);
  618. GbMultiSzAppend (&rasLines, TEXT("CredName"));
  619. #ifndef UNICODE
  620. GbMultiSzAppend (&rasLines, (*rasCredentials.szUserName)?rasCredentials.szUserName:TEXT("<empty>"));
  621. #else
  622. tempStr3 = ConvertAtoW (rasCredentials.szUserName);
  623. GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
  624. FreeConvertedStr (tempStr3);
  625. #endif
  626. GbMultiSzAppend (&rasLines, TEXT("CredDomain"));
  627. #ifndef UNICODE
  628. GbMultiSzAppend (&rasLines, (*rasCredentials.szDomain)?rasCredentials.szDomain:TEXT("<empty>"));
  629. #else
  630. tempStr3 = ConvertAtoW (rasCredentials.szDomain);
  631. GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
  632. FreeConvertedStr (tempStr3);
  633. #endif
  634. GbMultiSzAppend (&rasLines, TEXT("CredPassword"));
  635. #ifndef UNICODE
  636. GbMultiSzAppend (&rasLines, (*rasCredentials.szPassword)?rasCredentials.szPassword:TEXT("<empty>"));
  637. #else
  638. tempStr3 = ConvertAtoW (rasCredentials.szPassword);
  639. GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
  640. FreeConvertedStr (tempStr3);
  641. #endif
  642. }
  643. }
  644. if (err) {
  645. GbMultiSzAppend (&rasLines, TEXT("CredMask"));
  646. GbMultiSzAppend (&rasLines, TEXT("<empty>"));
  647. GbMultiSzAppend (&rasLines, TEXT("CredName"));
  648. GbMultiSzAppend (&rasLines, TEXT("<empty>"));
  649. GbMultiSzAppend (&rasLines, TEXT("CredDomain"));
  650. GbMultiSzAppend (&rasLines, TEXT("<empty>"));
  651. GbMultiSzAppend (&rasLines, TEXT("CredPassword"));
  652. GbMultiSzAppend (&rasLines, TEXT("<empty>"));
  653. }
  654. }
  655. inMedia = FALSE;
  656. g_FirstRasPair = TRUE;
  657. while (TRUE) {
  658. // get the next RAS connection line
  659. if (!pGetNextRasPair (pbkFileHandle, &valueName, &value)) {
  660. break;
  661. }
  662. if (valueName &&
  663. StringMatch (valueName, TEXT("MEDIA")) &&
  664. value &&
  665. StringIMatch (value, TEXT("serial"))
  666. ) {
  667. inMedia = TRUE;
  668. }
  669. if (inMedia &&
  670. valueName &&
  671. StringMatch (valueName, TEXT("DEVICE"))
  672. ) {
  673. inMedia = FALSE;
  674. }
  675. if (inMedia &&
  676. valueName &&
  677. StringIMatch (valueName, TEXT("Port"))
  678. ) {
  679. if (value) {
  680. PmReleaseMemory (g_RasPool, value);
  681. value = NULL;
  682. }
  683. }
  684. if (inMedia &&
  685. valueName &&
  686. StringMatch (valueName, TEXT("Device"))
  687. ) {
  688. if (value) {
  689. PmReleaseMemory (g_RasPool, value);
  690. value = NULL;
  691. }
  692. }
  693. GbMultiSzAppend (&rasLines, valueName?valueName:TEXT("<empty>"));
  694. GbMultiSzAppend (&rasLines, value?value:TEXT("<empty>"));
  695. if (valueName) {
  696. PmReleaseMemory (g_RasPool, valueName);
  697. valueName = NULL;
  698. }
  699. if (value) {
  700. PmReleaseMemory (g_RasPool, value);
  701. value = NULL;
  702. }
  703. }
  704. GbMultiSzAppend (&rasLines, TEXT(""));
  705. if (rasLines.End) {
  706. // now add the RAS connection
  707. rasLinesStr = PmGetMemory (g_RasPool, rasLines.End);
  708. CopyMemory (rasLinesStr, rasLines.Buf, rasLines.End);
  709. rasConnectionName = IsmCreateObjectHandle (PbkFileName, entryName);
  710. MYASSERT (rasConnectionName);
  711. if (rasConnectionName) {
  712. result = TRUE;
  713. HtAddStringEx (RasTable, rasConnectionName, &rasLinesStr, FALSE);
  714. }
  715. IsmDestroyObjectHandle (rasConnectionName);
  716. }
  717. PmReleaseMemory (g_RasPool, entryName);
  718. }
  719. CloseHandle (pbkFileHandle);
  720. }
  721. return result;
  722. }
  723. UINT
  724. PbkFilesCallback (
  725. IN PCMIG_OBJECTENUMDATA Data,
  726. IN ULONG_PTR CallerArg
  727. )
  728. {
  729. if (Data->IsLeaf) {
  730. // do this only if somebody actually persisted the object
  731. if (IsmIsPersistentObject (Data->ObjectTypeId, Data->ObjectName) ||
  732. IsmIsApplyObject (Data->ObjectTypeId, Data->ObjectName)
  733. ) {
  734. // record all connections from this PBK file
  735. if (pLoadRasConnections (Data->NativeObjectName, g_RasTable)) {
  736. // this is really a PBK file and at least one valid
  737. // connection was found
  738. // set the PbkFile attribute so we won't restore this one as a file (if it survives)
  739. IsmSetAttributeOnObject (Data->ObjectTypeId, Data->ObjectName, g_PbkFileAttribute);
  740. }
  741. }
  742. }
  743. return CALLBACK_ENUM_CONTINUE;
  744. }
  745. VOID
  746. WINAPI
  747. RasMigEtmNewUserCreated (
  748. IN PCTSTR UserName,
  749. IN PCTSTR DomainName,
  750. IN PCTSTR UserProfileRoot,
  751. IN PSID UserSid
  752. )
  753. {
  754. // a new user was created, the RAS operations on object that
  755. // belong exclusively to that user need to be delayed
  756. g_DelayRasOp = TRUE;
  757. }
  758. BOOL
  759. WINAPI
  760. RasMigSgmInitialize (
  761. IN PMIG_LOGCALLBACK LogCallback,
  762. IN PVOID Reserved
  763. )
  764. {
  765. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  766. return TRUE;
  767. }
  768. BOOL
  769. WINAPI
  770. RasMigSgmParse (
  771. IN PVOID Reserved
  772. )
  773. {
  774. return TRUE;
  775. }
  776. UINT
  777. SgmRasConnectionsCallback (
  778. IN PCMIG_OBJECTENUMDATA Data,
  779. IN ULONG_PTR CallerArg
  780. )
  781. {
  782. PCTSTR node, nodePtr, leaf;
  783. PTSTR leafPtr;
  784. PCTSTR rasLines;
  785. PCTSTR rasValue;
  786. MIG_OBJECTSTRINGHANDLE objectName;
  787. MIG_CONTENT objectContent;
  788. PCTSTR nativeName;
  789. MIG_OSVERSIONINFO versionInfo;
  790. BOOL versionOk = FALSE;
  791. if (IsmGetRealPlatform () == PLATFORM_DESTINATION) {
  792. // let's reset the PbkFileAttribute on the source of this connection
  793. // because the attribute was lost during the transport
  794. if (IsmCreateObjectStringsFromHandle (Data->ObjectName, &node, &leaf)) {
  795. if (node) {
  796. leafPtr = _tcsrchr (node, TEXT('\\'));
  797. if (leafPtr) {
  798. *leafPtr = 0;
  799. leafPtr ++;
  800. objectName = IsmCreateObjectHandle (node, leafPtr);
  801. if (objectName) {
  802. IsmSetAttributeOnObject (g_FileTypeId, objectName, g_PbkFileAttribute);
  803. IsmDestroyObjectHandle (objectName);
  804. }
  805. }
  806. }
  807. IsmDestroyObjectString (node);
  808. IsmDestroyObjectString (leaf);
  809. }
  810. }
  811. // let's see if we can actually migrate this RAS connection
  812. if (IsmAcquireObject (Data->ObjectTypeId, Data->ObjectName, &objectContent)) {
  813. versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
  814. rasLines = (PCTSTR) objectContent.MemoryContent.ContentBytes;
  815. rasValue = pGetRasLineValue (rasLines, TEXT("BaseProtocol"));
  816. if (rasValue && (StringIMatch (rasValue, TEXT("1")) || StringIMatch (rasValue, TEXT("2")))) {
  817. IsmAbandonObjectOnCollision (Data->ObjectTypeId, Data->ObjectName);
  818. IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
  819. // now it's a good time to force the migration of the script file
  820. // if this connection has one
  821. rasValue = NULL;
  822. if (versionOk) {
  823. if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
  824. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
  825. rasValue = pGetRasLineValue (rasLines, TEXT("Type"));
  826. }
  827. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
  828. rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
  829. }
  830. }
  831. if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
  832. rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
  833. }
  834. }
  835. if (rasValue && *rasValue) {
  836. node = DuplicatePathString (rasValue, 0);
  837. if (_tcsnextc (node) == TEXT('[')) {
  838. nodePtr = _tcsinc (node);
  839. } else {
  840. nodePtr = node;
  841. }
  842. leafPtr = _tcsrchr (nodePtr, TEXT('\\'));
  843. if (leafPtr) {
  844. *leafPtr = 0;
  845. leafPtr ++;
  846. objectName = IsmCreateObjectHandle (nodePtr, leafPtr);
  847. if (objectName) {
  848. IsmMakeApplyObject (g_FileTypeId, objectName);
  849. IsmDestroyObjectHandle (objectName);
  850. }
  851. }
  852. FreePathString (node);
  853. }
  854. } else {
  855. // this is an unsupported framing protocol
  856. // we will log a message and abandon this connection
  857. nativeName = IsmGetNativeObjectName (Data->ObjectTypeId, Data->ObjectName);
  858. LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, nativeName));
  859. IsmReleaseMemory (nativeName);
  860. }
  861. IsmReleaseObject (&objectContent);
  862. }
  863. return CALLBACK_ENUM_CONTINUE;
  864. }
  865. BOOL
  866. WINAPI
  867. RasMigSgmQueueEnumeration (
  868. IN PVOID Reserved
  869. )
  870. {
  871. ENCODEDSTRHANDLE pattern;
  872. g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
  873. MYASSERT (g_PbkFileAttribute);
  874. if (IsmGetRealPlatform () == PLATFORM_SOURCE) {
  875. // hook all PBK files enumeration, we will not migrate the files but the connections within
  876. pattern = IsmCreateSimpleObjectPattern (NULL, FALSE, TEXT("*.PBK"), TRUE);
  877. IsmHookEnumeration (
  878. g_FileTypeId,
  879. pattern,
  880. PbkFilesCallback,
  881. (ULONG_PTR) 0,
  882. TEXT("PbkFiles")
  883. );
  884. IsmDestroyObjectHandle (pattern);
  885. }
  886. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
  887. IsmQueueEnumeration (
  888. g_RasTypeId,
  889. pattern,
  890. SgmRasConnectionsCallback,
  891. (ULONG_PTR) 0,
  892. S_RAS_NAME
  893. );
  894. IsmDestroyObjectHandle (pattern);
  895. return TRUE;
  896. }
  897. BOOL
  898. WINAPI
  899. RasMigVcmInitialize (
  900. IN PMIG_LOGCALLBACK LogCallback,
  901. IN PVOID Reserved
  902. )
  903. {
  904. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  905. return TRUE;
  906. }
  907. BOOL
  908. WINAPI
  909. RasMigVcmParse (
  910. IN PVOID Reserved
  911. )
  912. {
  913. return RasMigSgmParse (Reserved);
  914. }
  915. UINT
  916. VcmRasConnectionsCallback (
  917. IN PCMIG_OBJECTENUMDATA Data,
  918. IN ULONG_PTR CallerArg
  919. )
  920. {
  921. PCTSTR node, nodePtr;
  922. PTSTR leafPtr;
  923. PCTSTR rasLines;
  924. PCTSTR rasValue;
  925. MIG_OBJECTSTRINGHANDLE objectName;
  926. MIG_CONTENT objectContent;
  927. PCTSTR nativeName;
  928. MIG_OSVERSIONINFO versionInfo;
  929. BOOL versionOk = FALSE;
  930. // let's see if we can actually migrate this RAS connection
  931. if (IsmAcquireObject (Data->ObjectTypeId, Data->ObjectName, &objectContent)) {
  932. versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
  933. rasLines = (PCTSTR) objectContent.MemoryContent.ContentBytes;
  934. rasValue = pGetRasLineValue (rasLines, TEXT("BaseProtocol"));
  935. if (rasValue && (StringIMatch (rasValue, TEXT("1")) || StringIMatch (rasValue, TEXT("2")))) {
  936. IsmMakePersistentObject (Data->ObjectTypeId, Data->ObjectName);
  937. // now it's a good time to force the migration of the script file
  938. // if this connection has one
  939. rasValue = NULL;
  940. if (versionOk) {
  941. if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
  942. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
  943. rasValue = pGetRasLineValue (rasLines, TEXT("Type"));
  944. }
  945. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
  946. rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
  947. }
  948. }
  949. if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
  950. rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
  951. }
  952. }
  953. if (rasValue && *rasValue) {
  954. node = DuplicatePathString (rasValue, 0);
  955. if (_tcsnextc (node) == TEXT('[')) {
  956. nodePtr = _tcsinc (node);
  957. } else {
  958. nodePtr = node;
  959. }
  960. leafPtr = _tcsrchr (nodePtr, TEXT('\\'));
  961. if (leafPtr) {
  962. *leafPtr = 0;
  963. leafPtr ++;
  964. objectName = IsmCreateObjectHandle (nodePtr, leafPtr);
  965. if (objectName) {
  966. IsmMakePersistentObject (g_FileTypeId, objectName);
  967. IsmDestroyObjectHandle (objectName);
  968. }
  969. }
  970. FreePathString (node);
  971. }
  972. } else {
  973. // this is an unsupported framing protocol
  974. // we will log a message and abandon this connection
  975. nativeName = IsmGetNativeObjectName (Data->ObjectTypeId, Data->ObjectName);
  976. LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, nativeName));
  977. IsmReleaseMemory (nativeName);
  978. }
  979. IsmReleaseObject (&objectContent);
  980. }
  981. return CALLBACK_ENUM_CONTINUE;
  982. }
  983. BOOL
  984. WINAPI
  985. RasMigVcmQueueEnumeration (
  986. IN PVOID Reserved
  987. )
  988. {
  989. ENCODEDSTRHANDLE pattern;
  990. g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
  991. MYASSERT (g_PbkFileAttribute);
  992. // hook all PBK files enumeration, we will not migrate the files but the connections within
  993. pattern = IsmCreateSimpleObjectPattern (NULL, FALSE, TEXT("*.PBK"), TRUE);
  994. IsmHookEnumeration (
  995. g_FileTypeId,
  996. pattern,
  997. PbkFilesCallback,
  998. (ULONG_PTR) 0,
  999. TEXT("PbkFiles")
  1000. );
  1001. IsmDestroyObjectHandle (pattern);
  1002. pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
  1003. IsmQueueEnumeration (
  1004. g_RasTypeId,
  1005. pattern,
  1006. VcmRasConnectionsCallback,
  1007. (ULONG_PTR) 0,
  1008. S_RAS_NAME
  1009. );
  1010. IsmDestroyObjectHandle (pattern);
  1011. return TRUE;
  1012. }
  1013. BOOL
  1014. PbkRestoreCallback (
  1015. IN MIG_OBJECTTYPEID ObjectTypeId,
  1016. IN MIG_OBJECTID ObjectId,
  1017. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1018. )
  1019. {
  1020. // if this is a PBK file we won't allow it to be restored like a file,
  1021. // we will add the proper connections ourselves.
  1022. return ((!IsmIsAttributeSetOnObjectId (ObjectId, g_PbkFileAttribute)) || g_AllowPbkRestore);
  1023. }
  1024. BOOL
  1025. WINAPI
  1026. FilterRasAutoFilter (
  1027. IN PCMIG_FILTERINPUT InputData,
  1028. OUT PMIG_FILTEROUTPUT OutputData,
  1029. IN BOOL NoRestoreObject,
  1030. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  1031. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  1032. )
  1033. {
  1034. // This function will split the RAS connection, filter the PBK file
  1035. // so we know where it ends up, and rebuild the object name.
  1036. PCTSTR srcFile = NULL;
  1037. PTSTR srcFilePtr = NULL;
  1038. PCTSTR srcConn = NULL;
  1039. MIG_OBJECTSTRINGHANDLE pbkFile = NULL;
  1040. MIG_OBJECTSTRINGHANDLE newPbkFile = NULL;
  1041. BOOL orgDeleted = FALSE;
  1042. BOOL orgReplaced = FALSE;
  1043. PCTSTR newPbkNative = NULL;
  1044. //
  1045. // Filter the object name
  1046. //
  1047. IsmCreateObjectStringsFromHandle (
  1048. InputData->CurrentObject.ObjectName,
  1049. &srcFile,
  1050. &srcConn
  1051. );
  1052. if (srcFile && srcConn) {
  1053. srcFilePtr = _tcsrchr (srcFile, TEXT('\\'));
  1054. if (srcFilePtr) {
  1055. // we know that \ is not a dbcs character so this is safe
  1056. *srcFilePtr = 0;
  1057. srcFilePtr ++;
  1058. pbkFile = IsmCreateObjectHandle (srcFile, srcFilePtr);
  1059. if (pbkFile) {
  1060. g_AllowPbkRestore = TRUE;
  1061. newPbkFile = IsmFilterObject (
  1062. g_FileTypeId | PLATFORM_SOURCE,
  1063. pbkFile,
  1064. NULL,
  1065. &orgDeleted,
  1066. &orgReplaced
  1067. );
  1068. g_AllowPbkRestore = FALSE;
  1069. if (newPbkFile) {
  1070. newPbkNative = IsmGetNativeObjectName (g_FileTypeId | PLATFORM_SOURCE, newPbkFile);
  1071. if (newPbkNative) {
  1072. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (newPbkNative, srcConn);
  1073. IsmReleaseMemory (newPbkNative);
  1074. newPbkNative = NULL;
  1075. }
  1076. IsmDestroyObjectHandle (newPbkFile);
  1077. newPbkFile = NULL;
  1078. }
  1079. IsmDestroyObjectHandle (pbkFile);
  1080. pbkFile = NULL;
  1081. }
  1082. }
  1083. }
  1084. IsmDestroyObjectString (srcFile);
  1085. IsmDestroyObjectString (srcConn);
  1086. return TRUE;
  1087. }
  1088. BOOL
  1089. WINAPI
  1090. RasMigOpmInitialize (
  1091. IN PMIG_LOGCALLBACK LogCallback,
  1092. IN PVOID Reserved
  1093. )
  1094. {
  1095. g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
  1096. MYASSERT (g_PbkFileAttribute);
  1097. IsmRegisterRestoreCallback (PbkRestoreCallback);
  1098. IsmRegisterGlobalFilterCallback (g_RasTypeId | PLATFORM_SOURCE, TEXT("AutoFilter"), FilterRasAutoFilter, TRUE, TRUE);
  1099. return TRUE;
  1100. }
  1101. BOOL
  1102. pEnumRasConnectionWorker (
  1103. OUT PMIG_TYPEOBJECTENUM EnumPtr,
  1104. IN PRAS_ENUM RasEnum
  1105. )
  1106. {
  1107. PCTSTR rasLines;
  1108. PCTSTR connName;
  1109. PCTSTR node, leaf;
  1110. if (EnumPtr->ObjectName) {
  1111. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  1112. EnumPtr->ObjectName = NULL;
  1113. }
  1114. if (EnumPtr->NativeObjectName) {
  1115. IsmDestroyObjectHandle (EnumPtr->NativeObjectName);
  1116. EnumPtr->NativeObjectName = NULL;
  1117. }
  1118. if (EnumPtr->ObjectNode) {
  1119. IsmDestroyObjectString (EnumPtr->ObjectNode);
  1120. EnumPtr->ObjectNode = NULL;
  1121. }
  1122. if (EnumPtr->ObjectLeaf) {
  1123. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  1124. EnumPtr->ObjectLeaf = NULL;
  1125. }
  1126. do {
  1127. IsmCreateObjectStringsFromHandle (RasEnum->HashData.String, &node, &leaf);
  1128. if (RasEnum->HashData.ExtraData) {
  1129. rasLines = *((PCTSTR *) RasEnum->HashData.ExtraData);
  1130. connName = pGetRasLineValue (rasLines, TEXT("ConnectionName"));
  1131. EnumPtr->ObjectName = IsmCreateObjectHandle (node, connName?connName:leaf);
  1132. EnumPtr->NativeObjectName = IsmCreateObjectHandle (node, connName?connName:leaf);
  1133. } else {
  1134. EnumPtr->ObjectName = IsmCreateObjectHandle (node, leaf);
  1135. EnumPtr->NativeObjectName = IsmCreateObjectHandle (node, leaf);
  1136. }
  1137. if (!ObsPatternMatch (RasEnum->Pattern, EnumPtr->ObjectName)) {
  1138. if (!EnumNextHashTableString (&RasEnum->HashData)) {
  1139. AbortEnumRasConnection (EnumPtr);
  1140. return FALSE;
  1141. }
  1142. continue;
  1143. }
  1144. IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
  1145. EnumPtr->Level = 1;
  1146. EnumPtr->SubLevel = 0;
  1147. EnumPtr->IsLeaf = TRUE;
  1148. EnumPtr->IsNode = FALSE;
  1149. EnumPtr->Details.DetailsSize = 0;
  1150. EnumPtr->Details.DetailsData = NULL;
  1151. return TRUE;
  1152. } while (TRUE);
  1153. }
  1154. BOOL
  1155. EnumFirstRasConnection (
  1156. IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
  1157. IN MIG_OBJECTSTRINGHANDLE Pattern,
  1158. IN UINT MaxLevel
  1159. )
  1160. {
  1161. PRAS_ENUM rasEnum = NULL;
  1162. if (!g_RasTable) {
  1163. return FALSE;
  1164. }
  1165. rasEnum = (PRAS_ENUM) PmGetMemory (g_RasPool, sizeof (RAS_ENUM));
  1166. rasEnum->Pattern = PmDuplicateString (g_RasPool, Pattern);
  1167. EnumPtr->EtmHandle = (LONG_PTR) rasEnum;
  1168. if (EnumFirstHashTableString (&rasEnum->HashData, g_RasTable)) {
  1169. return pEnumRasConnectionWorker (EnumPtr, rasEnum);
  1170. } else {
  1171. AbortEnumRasConnection (EnumPtr);
  1172. return FALSE;
  1173. }
  1174. }
  1175. BOOL
  1176. EnumNextRasConnection (
  1177. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  1178. )
  1179. {
  1180. PRAS_ENUM rasEnum = NULL;
  1181. rasEnum = (PRAS_ENUM)(EnumPtr->EtmHandle);
  1182. if (!rasEnum) {
  1183. return FALSE;
  1184. }
  1185. if (EnumNextHashTableString (&rasEnum->HashData)) {
  1186. return pEnumRasConnectionWorker (EnumPtr, rasEnum);
  1187. } else {
  1188. AbortEnumRasConnection (EnumPtr);
  1189. return FALSE;
  1190. }
  1191. }
  1192. VOID
  1193. AbortEnumRasConnection (
  1194. IN OUT PMIG_TYPEOBJECTENUM EnumPtr
  1195. )
  1196. {
  1197. PRAS_ENUM rasEnum = NULL;
  1198. if (EnumPtr->ObjectName) {
  1199. IsmDestroyObjectHandle (EnumPtr->ObjectName);
  1200. EnumPtr->ObjectName = NULL;
  1201. }
  1202. if (EnumPtr->NativeObjectName) {
  1203. IsmDestroyObjectHandle (EnumPtr->NativeObjectName);
  1204. EnumPtr->NativeObjectName = NULL;
  1205. }
  1206. if (EnumPtr->ObjectNode) {
  1207. IsmDestroyObjectString (EnumPtr->ObjectNode);
  1208. EnumPtr->ObjectNode = NULL;
  1209. }
  1210. if (EnumPtr->ObjectLeaf) {
  1211. IsmDestroyObjectString (EnumPtr->ObjectLeaf);
  1212. EnumPtr->ObjectLeaf = NULL;
  1213. }
  1214. rasEnum = (PRAS_ENUM)(EnumPtr->EtmHandle);
  1215. if (!rasEnum) {
  1216. return;
  1217. }
  1218. PmReleaseMemory (g_RasPool, rasEnum->Pattern);
  1219. PmReleaseMemory (g_RasPool, rasEnum);
  1220. ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
  1221. }
  1222. BOOL
  1223. AcquireRasConnection (
  1224. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1225. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  1226. IN MIG_CONTENTTYPE ContentType,
  1227. IN UINT MemoryContentLimit
  1228. )
  1229. {
  1230. PTSTR rasLines;
  1231. BOOL result = FALSE;
  1232. if (!ObjectContent) {
  1233. return FALSE;
  1234. }
  1235. if (ContentType == CONTENTTYPE_FILE) {
  1236. // nobody should request this as a file
  1237. MYASSERT (FALSE);
  1238. return FALSE;
  1239. }
  1240. if (HtFindStringEx (g_RasTable, ObjectName, &rasLines, FALSE)) {
  1241. ObjectContent->MemoryContent.ContentBytes = (PCBYTE) rasLines;
  1242. ObjectContent->MemoryContent.ContentSize = SizeOfMultiSz (rasLines);
  1243. result = TRUE;
  1244. }
  1245. return result;
  1246. }
  1247. BOOL
  1248. ReleaseRasConnection (
  1249. IN OUT PMIG_CONTENT ObjectContent
  1250. )
  1251. {
  1252. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  1253. return TRUE;
  1254. }
  1255. BOOL
  1256. DoesRasConnectionExist (
  1257. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1258. )
  1259. {
  1260. PCTSTR node = NULL;
  1261. PCTSTR leaf = NULL;
  1262. HASHTABLE rasTable;
  1263. BOOL result = FALSE;
  1264. if (ObjectName) {
  1265. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1266. rasTable = HtAllocWithData (sizeof (PCTSTR));
  1267. if (rasTable) {
  1268. if (pLoadRasConnections (node, rasTable)) {
  1269. result = (HtFindStringEx (rasTable, ObjectName, NULL, FALSE) != NULL);
  1270. }
  1271. HtFree (rasTable);
  1272. }
  1273. IsmDestroyObjectString (node);
  1274. IsmDestroyObjectString (leaf);
  1275. }
  1276. }
  1277. return result;
  1278. }
  1279. BOOL
  1280. RemoveRasConnection (
  1281. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1282. )
  1283. {
  1284. PCTSTR node, leaf;
  1285. DWORD err = 0;
  1286. BOOL result = FALSE;
  1287. if (g_RasDeleteEntry) {
  1288. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1289. MYASSERT (node);
  1290. MYASSERT (leaf);
  1291. if (node && leaf) {
  1292. err = g_RasDeleteEntry (node, leaf);
  1293. if (err == ERROR_SUCCESS) {
  1294. result = TRUE;
  1295. }
  1296. }
  1297. IsmDestroyObjectString (node);
  1298. IsmDestroyObjectString (leaf);
  1299. }
  1300. }
  1301. return result;
  1302. }
  1303. PCTSTR
  1304. pGetNewFileLocation (
  1305. IN PCTSTR SrcFile
  1306. )
  1307. {
  1308. PTSTR node, nodePtr, leaf;
  1309. MIG_OBJECTSTRINGHANDLE objectName;
  1310. MIG_OBJECTSTRINGHANDLE newObjectName;
  1311. BOOL deleted;
  1312. BOOL replaced;
  1313. PCTSTR result = NULL;
  1314. node = PmDuplicateString (g_RasPool, SrcFile);
  1315. if (*node) {
  1316. if (_tcsnextc (node) == TEXT('[')) {
  1317. nodePtr = _tcsinc (node);
  1318. } else {
  1319. nodePtr = node;
  1320. }
  1321. leaf = _tcsrchr (nodePtr, TEXT('\\'));
  1322. if (leaf) {
  1323. *leaf = 0;
  1324. leaf++;
  1325. objectName = IsmCreateObjectHandle (nodePtr, leaf);
  1326. PmReleaseMemory (g_RasPool, node);
  1327. newObjectName = IsmFilterObject (
  1328. g_FileTypeId | PLATFORM_SOURCE,
  1329. objectName,
  1330. NULL,
  1331. &deleted,
  1332. &replaced
  1333. );
  1334. if (!deleted || replaced) {
  1335. if (!newObjectName) {
  1336. newObjectName = objectName;
  1337. }
  1338. if (IsmCreateObjectStringsFromHandle (newObjectName, &node, &leaf)) {
  1339. result = JoinPaths (node, leaf);
  1340. }
  1341. }
  1342. if (newObjectName && (newObjectName != objectName)) {
  1343. IsmDestroyObjectHandle (newObjectName);
  1344. }
  1345. IsmDestroyObjectHandle (objectName);
  1346. } else {
  1347. PmReleaseMemory (g_RasPool, node);
  1348. }
  1349. } else {
  1350. PmReleaseMemory (g_RasPool, node);
  1351. }
  1352. return result;
  1353. }
  1354. BOOL
  1355. pTrackedCreateDirectory (
  1356. IN PCTSTR DirName
  1357. )
  1358. {
  1359. MIG_OBJECTSTRINGHANDLE objectName;
  1360. PTSTR pathCopy;
  1361. PTSTR p;
  1362. BOOL result = TRUE;
  1363. pathCopy = DuplicatePathString (DirName, 0);
  1364. //
  1365. // Advance past first directory
  1366. //
  1367. if (pathCopy[1] == TEXT(':') && pathCopy[2] == TEXT('\\')) {
  1368. //
  1369. // <drive>:\ case
  1370. //
  1371. p = _tcschr (&pathCopy[3], TEXT('\\'));
  1372. } else if (pathCopy[0] == TEXT('\\') && pathCopy[1] == TEXT('\\')) {
  1373. //
  1374. // UNC case
  1375. //
  1376. p = _tcschr (pathCopy + 2, TEXT('\\'));
  1377. if (p) {
  1378. p = _tcschr (p + 1, TEXT('\\'));
  1379. }
  1380. } else {
  1381. //
  1382. // Relative dir case
  1383. //
  1384. p = _tcschr (pathCopy, TEXT('\\'));
  1385. }
  1386. //
  1387. // Make all directories along the path
  1388. //
  1389. while (p) {
  1390. *p = 0;
  1391. if (!DoesFileExist (pathCopy)) {
  1392. // record directory creation
  1393. objectName = IsmCreateObjectHandle (pathCopy, NULL);
  1394. IsmRecordOperation (
  1395. JRNOP_CREATE,
  1396. g_FileTypeId,
  1397. objectName
  1398. );
  1399. IsmDestroyObjectHandle (objectName);
  1400. result = CreateDirectory (pathCopy, NULL);
  1401. if (!result) {
  1402. break;
  1403. }
  1404. }
  1405. *p = TEXT('\\');
  1406. p = _tcschr (p + 1, TEXT('\\'));
  1407. }
  1408. FreePathString (pathCopy);
  1409. return result;
  1410. }
  1411. BOOL
  1412. CreateRasConnection (
  1413. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1414. IN PMIG_CONTENT ObjectContent
  1415. )
  1416. {
  1417. PCTSTR rasLines;
  1418. MULTISZ_ENUM multiSzEnum;
  1419. PCTSTR pbkFileName = NULL;
  1420. PCTSTR connName = NULL;
  1421. HANDLE pbkFileHandle = NULL;
  1422. BOOL first = TRUE;
  1423. MIG_OSVERSIONINFO versionInfo;
  1424. BOOL versionOk = FALSE;
  1425. BOOL fileField = FALSE;
  1426. PCTSTR destFileName;
  1427. RASCREDENTIALS rasCredentials;
  1428. BOOL lastVNEmpty = FALSE;
  1429. BOOL result = FALSE;
  1430. WORD oldCodePage;
  1431. PCTSTR newUserProfile = NULL;
  1432. DWORD credResult;
  1433. __try {
  1434. if (ObjectContent->ContentInFile) {
  1435. __leave;
  1436. }
  1437. if (!ObjectContent->MemoryContent.ContentBytes) {
  1438. __leave;
  1439. }
  1440. if (!IsmCreateObjectStringsFromHandle (ObjectName, &pbkFileName, &connName)) {
  1441. __leave;
  1442. }
  1443. MYASSERT (pbkFileName);
  1444. if (!pbkFileName) {
  1445. __leave;
  1446. }
  1447. MYASSERT (connName);
  1448. if (!connName) {
  1449. __leave;
  1450. }
  1451. if (g_DelayRasOp) {
  1452. // we know that we created a new user (we are in cmd line mode).
  1453. // Let's try to see if this connection belongs to that user.
  1454. // If it does, we are going to delay the creation because
  1455. // we set credentials for the connection, and they need to be
  1456. // set in that user's context.
  1457. // If not, it means that this is a common connection so we are
  1458. // just going to go ahead and add it.
  1459. newUserProfile = IsmExpandEnvironmentString (PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, TEXT ("%userprofile%"), NULL);
  1460. if (newUserProfile) {
  1461. if (StringIPrefix (pbkFileName, newUserProfile)) {
  1462. // we need to delay this operation
  1463. // record delayed printer replace operation
  1464. IsmRecordDelayedOperation (
  1465. JRNOP_CREATE,
  1466. g_RasTypeId,
  1467. ObjectName,
  1468. ObjectContent
  1469. );
  1470. result = TRUE;
  1471. __leave;
  1472. }
  1473. IsmReleaseMemory (newUserProfile);
  1474. newUserProfile = NULL;
  1475. }
  1476. }
  1477. ZeroMemory (&rasCredentials, sizeof (RASCREDENTIALS));
  1478. rasCredentials.dwSize = sizeof (RASCREDENTIALS);
  1479. rasLines = (PCTSTR) ObjectContent->MemoryContent.ContentBytes;
  1480. // record RAS entry creation
  1481. IsmRecordOperation (
  1482. JRNOP_CREATE,
  1483. g_RasTypeId,
  1484. ObjectName
  1485. );
  1486. if (EnumFirstMultiSz (&multiSzEnum, rasLines)) {
  1487. // get the first 8 fields as being part of rasCredentials structure
  1488. MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("ConnectionName")));
  1489. if (!EnumNextMultiSz (&multiSzEnum)) {
  1490. __leave;
  1491. }
  1492. // we are just skipping the connection name
  1493. if (!EnumNextMultiSz (&multiSzEnum)) {
  1494. __leave;
  1495. }
  1496. MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredMask")));
  1497. if (!EnumNextMultiSz (&multiSzEnum)) {
  1498. __leave;
  1499. }
  1500. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1501. _stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &(rasCredentials.dwMask));
  1502. }
  1503. if (!EnumNextMultiSz (&multiSzEnum)) {
  1504. __leave;
  1505. }
  1506. MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredName")));
  1507. if (!EnumNextMultiSz (&multiSzEnum)) {
  1508. __leave;
  1509. }
  1510. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1511. StringCopyTcharCount (rasCredentials.szUserName, multiSzEnum.CurrentString, UNLEN + 1);
  1512. }
  1513. if (!EnumNextMultiSz (&multiSzEnum)) {
  1514. __leave;
  1515. }
  1516. MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredDomain")));
  1517. if (!EnumNextMultiSz (&multiSzEnum)) {
  1518. __leave;
  1519. }
  1520. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1521. StringCopyTcharCount (rasCredentials.szDomain, multiSzEnum.CurrentString, DNLEN + 1);
  1522. }
  1523. if (!EnumNextMultiSz (&multiSzEnum)) {
  1524. __leave;
  1525. }
  1526. MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredPassword")));
  1527. if (!EnumNextMultiSz (&multiSzEnum)) {
  1528. __leave;
  1529. }
  1530. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1531. StringCopyTcharCount (rasCredentials.szPassword, multiSzEnum.CurrentString, PWLEN + 1);
  1532. }
  1533. if (!EnumNextMultiSz (&multiSzEnum)) {
  1534. __leave;
  1535. }
  1536. pbkFileHandle = BfOpenFile (pbkFileName);
  1537. if (!pbkFileHandle) {
  1538. pTrackedCreateDirectory (pbkFileName);
  1539. pbkFileHandle = BfCreateFile (pbkFileName);
  1540. }
  1541. if (!pbkFileHandle) {
  1542. __leave;
  1543. }
  1544. BfGoToEndOfFile (pbkFileHandle, NULL);
  1545. WriteFileString (pbkFileHandle, TEXT("\r\n["));
  1546. // make sure that the conversion is using UTF8
  1547. oldCodePage = SetConversionCodePage (CP_UTF8);
  1548. WriteFileString (pbkFileHandle, connName);
  1549. SetConversionCodePage (oldCodePage);
  1550. WriteFileString (pbkFileHandle, TEXT("]\r\n"));
  1551. first = TRUE;
  1552. versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
  1553. do {
  1554. if (first) {
  1555. if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1556. lastVNEmpty = TRUE;
  1557. } else {
  1558. lastVNEmpty = FALSE;
  1559. if (versionOk) {
  1560. if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
  1561. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
  1562. fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Type"));
  1563. }
  1564. if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
  1565. fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Name"));
  1566. }
  1567. }
  1568. if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
  1569. fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Name"));
  1570. }
  1571. }
  1572. fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("CustomDialDll"));
  1573. fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("CustomRasDialDll"));
  1574. fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("PrerequisitePbk"));
  1575. WriteFileString (pbkFileHandle, multiSzEnum.CurrentString);
  1576. }
  1577. } else {
  1578. if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1579. if (!lastVNEmpty) {
  1580. WriteFileString (pbkFileHandle, TEXT("="));
  1581. }
  1582. WriteFileString (pbkFileHandle, TEXT("\r\n"));
  1583. } else {
  1584. WriteFileString (pbkFileHandle, TEXT("="));
  1585. if (fileField) {
  1586. destFileName = pGetNewFileLocation (multiSzEnum.CurrentString);
  1587. } else {
  1588. destFileName = NULL;
  1589. }
  1590. if (destFileName) {
  1591. // make sure that the conversion is using UTF8
  1592. oldCodePage = SetConversionCodePage (CP_UTF8);
  1593. WriteFileString (pbkFileHandle, destFileName);
  1594. SetConversionCodePage (oldCodePage);
  1595. FreePathString (destFileName);
  1596. destFileName = NULL;
  1597. } else {
  1598. // make sure that the conversion is using UTF8
  1599. oldCodePage = SetConversionCodePage (CP_UTF8);
  1600. WriteFileString (pbkFileHandle, multiSzEnum.CurrentString);
  1601. oldCodePage = SetConversionCodePage (oldCodePage);
  1602. }
  1603. WriteFileString (pbkFileHandle, TEXT("\r\n"));
  1604. }
  1605. fileField = FALSE;
  1606. }
  1607. first = !first;
  1608. } while (EnumNextMultiSz (&multiSzEnum));
  1609. WriteFileString (pbkFileHandle, TEXT("\r\n"));
  1610. result = TRUE;
  1611. }
  1612. if (pbkFileHandle) {
  1613. CloseHandle (pbkFileHandle);
  1614. pbkFileHandle = NULL;
  1615. }
  1616. if (result) {
  1617. if (g_RasSetCredentials && rasCredentials.dwMask) {
  1618. credResult = g_RasSetCredentials (pbkFileName, connName, &rasCredentials, FALSE);
  1619. }
  1620. }
  1621. }
  1622. __finally {
  1623. IsmDestroyObjectString (pbkFileName);
  1624. IsmDestroyObjectString (connName);
  1625. }
  1626. return result;
  1627. }
  1628. PCTSTR
  1629. ConvertRasConnectionToMultiSz (
  1630. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1631. IN PMIG_CONTENT ObjectContent
  1632. )
  1633. {
  1634. PCTSTR node, leaf;
  1635. PTSTR result = NULL;
  1636. BOOL bresult = TRUE;
  1637. PCTSTR rasLines;
  1638. MULTISZ_ENUM multiSzEnum;
  1639. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1640. MYASSERT (leaf);
  1641. g_RasConversionBuff.End = 0;
  1642. if (node) {
  1643. GbCopyQuotedString (&g_RasConversionBuff, node);
  1644. } else {
  1645. GbCopyQuotedString (&g_RasConversionBuff, TEXT(""));
  1646. }
  1647. GbCopyQuotedString (&g_RasConversionBuff, leaf);
  1648. MYASSERT (ObjectContent->Details.DetailsSize == 0);
  1649. MYASSERT (!ObjectContent->ContentInFile);
  1650. if ((!ObjectContent->ContentInFile) &&
  1651. (ObjectContent->MemoryContent.ContentSize) &&
  1652. (ObjectContent->MemoryContent.ContentBytes)
  1653. ) {
  1654. rasLines = (PCTSTR)ObjectContent->MemoryContent.ContentBytes;
  1655. if (EnumFirstMultiSz (&multiSzEnum, rasLines)) {
  1656. do {
  1657. if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1658. GbCopyQuotedString (&g_RasConversionBuff, TEXT(""));
  1659. } else {
  1660. GbCopyQuotedString (&g_RasConversionBuff, multiSzEnum.CurrentString);
  1661. }
  1662. } while (EnumNextMultiSz (&multiSzEnum));
  1663. }
  1664. } else {
  1665. bresult = FALSE;
  1666. }
  1667. if (bresult) {
  1668. GbCopyString (&g_RasConversionBuff, TEXT(""));
  1669. result = IsmGetMemory (g_RasConversionBuff.End);
  1670. CopyMemory (result, g_RasConversionBuff.Buf, g_RasConversionBuff.End);
  1671. }
  1672. g_RasConversionBuff.End = 0;
  1673. IsmDestroyObjectString (node);
  1674. IsmDestroyObjectString (leaf);
  1675. }
  1676. return result;
  1677. }
  1678. BOOL
  1679. ConvertMultiSzToRasConnection (
  1680. IN PCTSTR ObjectMultiSz,
  1681. OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
  1682. OUT PMIG_CONTENT ObjectContent OPTIONAL
  1683. )
  1684. {
  1685. MULTISZ_ENUM multiSzEnum;
  1686. PCTSTR node = NULL;
  1687. PCTSTR leaf = NULL;
  1688. UINT index;
  1689. g_RasConversionBuff.End = 0;
  1690. if (ObjectContent) {
  1691. ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
  1692. }
  1693. if (EnumFirstMultiSz (&multiSzEnum, ObjectMultiSz)) {
  1694. index = 0;
  1695. do {
  1696. if (index == 0) {
  1697. if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
  1698. node = multiSzEnum.CurrentString;
  1699. }
  1700. }
  1701. if (index == 1) {
  1702. leaf = multiSzEnum.CurrentString;
  1703. }
  1704. if (index > 1) {
  1705. if (*multiSzEnum.CurrentString) {
  1706. GbMultiSzAppend (&g_RasConversionBuff, multiSzEnum.CurrentString);
  1707. } else {
  1708. GbMultiSzAppend (&g_RasConversionBuff, TEXT("<empty>"));
  1709. }
  1710. }
  1711. index ++;
  1712. } while (EnumNextMultiSz (&multiSzEnum));
  1713. }
  1714. GbMultiSzAppend (&g_RasConversionBuff, TEXT(""));
  1715. if (!leaf) {
  1716. GbFree (&g_RasConversionBuff);
  1717. return FALSE;
  1718. }
  1719. if (ObjectContent) {
  1720. if (g_RasConversionBuff.End) {
  1721. ObjectContent->MemoryContent.ContentSize = g_RasConversionBuff.End;
  1722. ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
  1723. CopyMemory (
  1724. (PBYTE)ObjectContent->MemoryContent.ContentBytes,
  1725. g_RasConversionBuff.Buf,
  1726. ObjectContent->MemoryContent.ContentSize
  1727. );
  1728. } else {
  1729. ObjectContent->MemoryContent.ContentSize = 0;
  1730. ObjectContent->MemoryContent.ContentBytes = NULL;
  1731. }
  1732. ObjectContent->Details.DetailsSize = 0;
  1733. ObjectContent->Details.DetailsData = NULL;
  1734. }
  1735. *ObjectName = IsmCreateObjectHandle (node, leaf);
  1736. GbFree (&g_RasConversionBuff);
  1737. return TRUE;
  1738. }
  1739. PCTSTR
  1740. GetNativeRasConnectionName (
  1741. IN MIG_OBJECTSTRINGHANDLE ObjectName
  1742. )
  1743. {
  1744. PCTSTR node = NULL, leaf = NULL;
  1745. UINT size;
  1746. PTSTR result = NULL;
  1747. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  1748. if (leaf) {
  1749. size = SizeOfString (leaf);
  1750. if (size) {
  1751. result = IsmGetMemory (size);
  1752. CopyMemory (result, leaf, size);
  1753. }
  1754. }
  1755. IsmDestroyObjectString (node);
  1756. IsmDestroyObjectString (leaf);
  1757. }
  1758. return result;
  1759. }
  1760. PMIG_CONTENT
  1761. ConvertRasConnectionContentToUnicode (
  1762. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1763. IN PMIG_CONTENT ObjectContent
  1764. )
  1765. {
  1766. PMIG_CONTENT result = NULL;
  1767. if (!ObjectContent) {
  1768. return result;
  1769. }
  1770. if (ObjectContent->ContentInFile) {
  1771. return result;
  1772. }
  1773. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1774. if (result) {
  1775. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1776. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1777. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1778. ) {
  1779. // convert Ras Connection content
  1780. result->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize * 2);
  1781. if (result->MemoryContent.ContentBytes) {
  1782. DirectDbcsToUnicodeN (
  1783. (PWSTR)result->MemoryContent.ContentBytes,
  1784. (PSTR)ObjectContent->MemoryContent.ContentBytes,
  1785. ObjectContent->MemoryContent.ContentSize
  1786. );
  1787. result->MemoryContent.ContentSize = SizeOfMultiSzW ((PWSTR)result->MemoryContent.ContentBytes);
  1788. }
  1789. }
  1790. }
  1791. return result;
  1792. }
  1793. PMIG_CONTENT
  1794. ConvertRasConnectionContentToAnsi (
  1795. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1796. IN PMIG_CONTENT ObjectContent
  1797. )
  1798. {
  1799. PMIG_CONTENT result = NULL;
  1800. if (!ObjectContent) {
  1801. return result;
  1802. }
  1803. if (ObjectContent->ContentInFile) {
  1804. return result;
  1805. }
  1806. result = IsmGetMemory (sizeof (MIG_CONTENT));
  1807. if (result) {
  1808. CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
  1809. if ((ObjectContent->MemoryContent.ContentSize != 0) &&
  1810. (ObjectContent->MemoryContent.ContentBytes != NULL)
  1811. ) {
  1812. // convert Ras Connection content
  1813. result->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
  1814. if (result->MemoryContent.ContentBytes) {
  1815. DirectUnicodeToDbcsN (
  1816. (PSTR)result->MemoryContent.ContentBytes,
  1817. (PWSTR)ObjectContent->MemoryContent.ContentBytes,
  1818. ObjectContent->MemoryContent.ContentSize
  1819. );
  1820. result->MemoryContent.ContentSize = SizeOfMultiSzA ((PSTR)result->MemoryContent.ContentBytes);
  1821. }
  1822. }
  1823. }
  1824. return result;
  1825. }
  1826. BOOL
  1827. FreeConvertedRasConnectionContent (
  1828. IN PMIG_CONTENT ObjectContent
  1829. )
  1830. {
  1831. if (!ObjectContent) {
  1832. return TRUE;
  1833. }
  1834. if (ObjectContent->MemoryContent.ContentBytes) {
  1835. IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1836. }
  1837. IsmReleaseMemory (ObjectContent);
  1838. return TRUE;
  1839. }
  1840. //
  1841. // Win9x specific code. Converts registry format into a PBK file
  1842. //
  1843. //
  1844. // AddrEntry serves as a header for the entire block of data in the <entry>
  1845. // blob. entries in it are offsets to the strings which follow it..in many cases
  1846. // (i.e. all of the *Off* members...)
  1847. //
  1848. typedef struct _AddrEntry {
  1849. DWORD dwVersion;
  1850. DWORD dwCountryCode;
  1851. UINT uOffArea;
  1852. UINT uOffPhone;
  1853. DWORD dwCountryID;
  1854. UINT uOffSMMCfg;
  1855. UINT uOffSMM;
  1856. UINT uOffDI;
  1857. } ADDRENTRY, *PADDRENTRY;
  1858. typedef struct {
  1859. DWORD Size;
  1860. DWORD Unknown1;
  1861. DWORD ModemUiOptions; // num seconds in high byte.
  1862. DWORD Unknown2;
  1863. DWORD Unknown3;
  1864. DWORD Unknown4;
  1865. DWORD ConnectionSpeed;
  1866. DWORD UnknownFlowControlData; //Somehow related to flow control.
  1867. DWORD Unknown5;
  1868. DWORD Unknown6;
  1869. DWORD Unknown7;
  1870. DWORD Unknown8;
  1871. DWORD Unknown9;
  1872. DWORD Unknown10;
  1873. DWORD Unknown11;
  1874. DWORD Unknown12;
  1875. DWORD Unknown13;
  1876. DWORD Unknown14;
  1877. DWORD Unknown15;
  1878. DWORD CancelSeconds; //Num seconds to wait before cancel if not connected. (0xFF equals off.)
  1879. DWORD IdleDisconnectSeconds; // 0 = Not Set.
  1880. DWORD Unknown16;
  1881. DWORD SpeakerVolume; // 0|1
  1882. DWORD ConfigOptions;
  1883. DWORD Unknown17;
  1884. DWORD Unknown18;
  1885. DWORD Unknown19;
  1886. } MODEMDEVINFO, *PMODEMDEVINFO;
  1887. typedef struct _SubConnEntry {
  1888. DWORD dwSize;
  1889. DWORD dwFlags;
  1890. CHAR szDeviceType[RAS_MaxDeviceType+1];
  1891. CHAR szDeviceName[RAS_MaxDeviceName+1];
  1892. CHAR szLocal[RAS_MaxPhoneNumber+1];
  1893. } SUBCONNENTRY, *PSUBCONNENTRY;
  1894. typedef struct _SMMCFG {
  1895. DWORD dwSize;
  1896. DWORD fdwOptions;
  1897. DWORD fdwProtocols;
  1898. } SMMCFG, *PSMMCFG;
  1899. typedef struct _DEVICEINFO {
  1900. DWORD dwVersion;
  1901. UINT uSize;
  1902. CHAR szDeviceName[RAS_MaxDeviceName+1];
  1903. CHAR szDeviceType[RAS_MaxDeviceType+1];
  1904. } DEVICEINFO, *PDEVICEINFO;
  1905. typedef struct _IPData {
  1906. DWORD dwSize;
  1907. DWORD fdwTCPIP;
  1908. DWORD dwIPAddr;
  1909. DWORD dwDNSAddr;
  1910. DWORD dwDNSAddrAlt;
  1911. DWORD dwWINSAddr;
  1912. DWORD dwWINSAddrAlt;
  1913. } IPDATA, *PIPDATA;
  1914. typedef struct {
  1915. PCTSTR String;
  1916. UINT Value;
  1917. WORD DataType;
  1918. } MEMDB_RAS_DATA, *PMEMDB_RAS_DATA;
  1919. #define PAESMMCFG(pAE) ((PSMMCFG)(((PBYTE)pAE)+(pAE->uOffSMMCfg)))
  1920. #define PAESMM(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffSMM)))
  1921. #define PAEDI(pAE) ((PDEVICEINFO)(((PBYTE)pAE)+(pAE->uOffDI )))
  1922. #define PAEAREA(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffArea)))
  1923. #define PAEPHONE(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffPhone)))
  1924. #define DECRYPTENTRY(x, y, z) EnDecryptEntry(x, (LPBYTE)y, z)
  1925. #define S_REMOTE_ACCESS_KEY TEXT("HKCU\\RemoteAccess")
  1926. #define S_DIALUI TEXT("DialUI")
  1927. #define S_ENABLE_REDIAL TEXT("EnableRedial")
  1928. #define S_REDIAL_TRY TEXT("RedialTry")
  1929. #define S_REDIAL_WAIT TEXT("RedialWait")
  1930. #define S_ENABLE_IMPLICIT TEXT("EnableImplicit")
  1931. #define S_PHONE_NUMBER TEXT("Phone Number")
  1932. #define S_AREA_CODE TEXT("Area Code")
  1933. #define S_SMM TEXT("SMM")
  1934. #define S_COUNTRY_CODE TEXT("Country Code")
  1935. #define S_COUNTRY_ID TEXT("Country Id")
  1936. #define S_DEVICE_NAME TEXT("Device Name")
  1937. #define S_DEVICE_TYPE TEXT("Device Type")
  1938. #define S_PROTOCOLS TEXT("Protocols")
  1939. #define S_SMM_OPTIONS TEXT("SMM Options")
  1940. #define S_IPINFO TEXT("IP")
  1941. #define S_IP_FTCPIP TEXT("_IP_FTCPIP")
  1942. #define S_IP_IPADDR TEXT("IpAddress")
  1943. #define S_IP_DNSADDR TEXT("IpDnsAddress")
  1944. #define S_IP_DNSADDR2 TEXT("IpDns2Address")
  1945. #define S_IP_WINSADDR TEXT("IpWinsAddress")
  1946. #define S_IP_WINSADDR2 TEXT("IpWins2Address")
  1947. #define S_DOMAIN TEXT("Domain")
  1948. #define S_USER TEXT("User")
  1949. #define S_MODEMS TEXT("HKLM\\System\\CurrentControlSet\\Services\\Class\\Modem")
  1950. #define S_ATTACHEDTO TEXT("AttachedTo")
  1951. #define S_DRIVERDESC TEXT("DriverDesc")
  1952. #define S_TERMINAL TEXT("Terminal")
  1953. #define S_MODE TEXT("Mode")
  1954. #define S_MULTILINK TEXT("MultiLink")
  1955. #define S_MODEM TEXT("Modem")
  1956. #define S_MODEMA "Modem"
  1957. #define S_MODEM_UI_OPTIONS TEXT("__UiOptions")
  1958. #define S_MODEM_SPEED TEXT("__Speed")
  1959. #define S_MODEM_SPEAKER_VOLUME TEXT("__SpeakerVolume")
  1960. #define S_MODEM_IDLE_DISCONNECT_SECONDS TEXT("__IdleDisconnect")
  1961. #define S_MODEM_CANCEL_SECONDS TEXT("__CancelSeconds")
  1962. #define S_MODEM_CFG_OPTIONS TEXT("__CfgOptions")
  1963. #define S_MODEM_COM_PORT TEXT("ComPort")
  1964. #define S_DEVICECOUNT TEXT("__DeviceCount")
  1965. #define S_PPP TEXT("PPP")
  1966. #define S_PPPA "PPP"
  1967. #define S_SLIP TEXT("Slip")
  1968. #define S_SLIPA "Slip"
  1969. #define S_CSLIP TEXT("CSlip")
  1970. #define S_CSLIPA "CSlip"
  1971. #define S_SERVICEREMOTEACCESS TEXT("HKLM\\System\\CurrentControlSet\\Services\\RemoteAccess")
  1972. #define S_REMOTE_ACCESS_KEY TEXT("HKCU\\RemoteAccess")
  1973. #define S_PROFILE_KEY TEXT("HKCU\\RemoteAccess\\Profile")
  1974. #define S_ADDRESSES_KEY TEXT("HKCU\\RemoteAccess\\Addresses")
  1975. #define S_SUBENTRIES TEXT("SubEntries")
  1976. #define S_EMPTY TEXT("")
  1977. #define S_PPPSCRIPT TEXT("PPPSCRIPT")
  1978. #define MEMDB_CATEGORY_RAS_INFO TEXT("RAS Info")
  1979. #define MEMDB_CATEGORY_RAS_USER TEXT("RAS User")
  1980. #define MEMDB_CATEGORY_RAS_DATA TEXT("Ras Data")
  1981. #define MEMDB_FIELD_USER_SETTINGS TEXT("User Settings")
  1982. #define RASTYPE_PHONE 1
  1983. #define RASTYPE_VPN 2
  1984. #define S_VPN TEXT("VPN")
  1985. #define S_ZERO TEXT("0")
  1986. #define S_ONE TEXT("1")
  1987. #define SMMCFG_SW_COMPRESSION 0x00000001 // Software compression is on
  1988. #define SMMCFG_PW_ENCRYPTED 0x00000002 // Encrypted password only
  1989. #define SMMCFG_NW_LOGON 0x00000004 // Logon to the network
  1990. // Negotiated protocols
  1991. //
  1992. #define SMMPROT_NB 0x00000001 // NetBEUI
  1993. #define SMMPROT_IPX 0x00000002 // IPX
  1994. #define SMMPROT_IP 0x00000004 // TCP/IP
  1995. #define IPF_IP_SPECIFIED 0x00000001
  1996. #define IPF_NAME_SPECIFIED 0x00000002
  1997. #define IPF_NO_COMPRESS 0x00000004
  1998. #define IPF_NO_WAN_PRI 0x00000008
  1999. #define RAS_UI_FLAG_TERMBEFOREDIAL 0x1
  2000. #define RAS_UI_FLAG_TERMAFTERDIAL 0x2
  2001. #define RAS_UI_FLAG_OPERATORASSISTED 0x4
  2002. #define RAS_UI_FLAG_MODEMSTATUS 0x8
  2003. #define RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL 0x00000010
  2004. #define RAS_CFG_FLAG_SOFTWARE_FLOW_CONTROL 0x00000020
  2005. #define RAS_CFG_FLAG_STANDARD_EMULATION 0x00000040
  2006. #define RAS_CFG_FLAG_COMPRESS_DATA 0x00000001
  2007. #define RAS_CFG_FLAG_USE_ERROR_CONTROL 0x00000002
  2008. #define RAS_CFG_FLAG_ERROR_CONTROL_REQUIRED 0x00000004
  2009. #define RAS_CFG_FLAG_USE_CELLULAR_PROTOCOL 0x00000008
  2010. #define RAS_CFG_FLAG_NO_WAIT_FOR_DIALTONE 0x00000200
  2011. #define DIALUI_DONT_PROMPT_FOR_INFO 0x01
  2012. #define DIALUI_DONT_SHOW_ICON 0x04
  2013. //
  2014. // For each entry, the following basic information is stored.
  2015. //
  2016. #define ENTRY_SETTINGS \
  2017. FUNSETTING(CredMask) \
  2018. FUNSETTING(CredName) \
  2019. FUNSETTING(CredDomain) \
  2020. FUNSETTING(CredPassword) \
  2021. STRSETTING(Encoding,S_ONE) \
  2022. FUNSETTING(Type) \
  2023. STRSETTING(Autologon,S_ZERO) \
  2024. STRSETTING(DialParamsUID,S_EMPTY) \
  2025. STRSETTING(Guid,S_EMPTY) \
  2026. STRSETTING(UsePwForNetwork,S_EMPTY) \
  2027. STRSETTING(ServerType,S_EMPTY) \
  2028. FUNSETTING(BaseProtocol) \
  2029. FUNSETTING(VpnStrategy) \
  2030. STRSETTING(Authentication,S_EMPTY) \
  2031. FUNSETTING(ExcludedProtocols) \
  2032. STRSETTING(LcpExtensions,S_ONE) \
  2033. FUNSETTING(DataEncryption) \
  2034. STRSETTING(SkipNwcWarning,S_EMPTY) \
  2035. STRSETTING(SkipDownLevelDialog,S_EMPTY) \
  2036. FUNSETTING(SwCompression) \
  2037. FUNSETTING(ShowMonitorIconInTaskBar) \
  2038. STRSETTING(CustomAuthKey,S_EMPTY) \
  2039. STRSETTING(CustomAuthData,S_EMPTY) \
  2040. FUNSETTING(AuthRestrictions) \
  2041. STRSETTING(OverridePref,TEXT("15")) \
  2042. STRSETTING(DialMode,S_EMPTY) \
  2043. STRSETTING(DialPercent,S_EMPTY) \
  2044. STRSETTING(DialSeconds,S_EMPTY) \
  2045. STRSETTING(HangUpPercent,S_EMPTY) \
  2046. STRSETTING(HangUpSeconds,S_EMPTY) \
  2047. FUNSETTING(RedialAttempts) \
  2048. FUNSETTING(RedialSeconds) \
  2049. FUNSETTING(IdleDisconnectSeconds) \
  2050. STRSETTING(RedialOnLinkFailure,S_EMPTY) \
  2051. STRSETTING(CallBackMode,S_EMPTY) \
  2052. STRSETTING(CustomDialDll,S_EMPTY) \
  2053. STRSETTING(CustomDialFunc,S_EMPTY) \
  2054. STRSETTING(AuthenticateServer,S_EMPTY) \
  2055. STRSETTING(SecureLocalFiels,S_EMPTY) \
  2056. STRSETTING(ShareMsFilePrint,S_EMPTY) \
  2057. STRSETTING(BindMsNetClient,S_EMPTY) \
  2058. STRSETTING(SharedPhoneNumbers,S_EMPTY) \
  2059. STRSETTING(PrerequisiteEntry,S_EMPTY) \
  2060. FUNSETTING(PreviewUserPw) \
  2061. FUNSETTING(PreviewDomain) \
  2062. FUNSETTING(PreviewPhoneNumber) \
  2063. STRSETTING(ShowDialingProgress,S_ONE) \
  2064. FUNSETTING(IpPrioritizeRemote) \
  2065. FUNSETTING(IpHeaderCompression) \
  2066. FUNSETTING(IpAddress) \
  2067. FUNSETTING(IpAssign) \
  2068. FUNSETTING(IpDnsAddress) \
  2069. FUNSETTING(IpDns2Address) \
  2070. FUNSETTING(IpWINSAddress) \
  2071. FUNSETTING(IpWINS2Address) \
  2072. FUNSETTING(IpNameAssign) \
  2073. STRSETTING(IpFrameSize,S_EMPTY) \
  2074. //
  2075. // There can be multiple media sections for each entry.
  2076. //
  2077. #define MEDIA_SETTINGS \
  2078. FUNSETTING(MEDIA) \
  2079. FUNSETTING(Port) \
  2080. FUNSETTING(Device) \
  2081. FUNSETTING(ConnectBps) \
  2082. //
  2083. // There can be multiple device sections for each entry.
  2084. //
  2085. #define SWITCH_DEVICE_SETTINGS \
  2086. FUNSETTING(DEVICE) \
  2087. FUNSETTING(Name) \
  2088. FUNSETTING(Terminal) \
  2089. FUNSETTING(Script) \
  2090. #define MODEM_DEVICE_SETTINGS \
  2091. FUNSETTING(DEVICE) \
  2092. FUNSETTING(PhoneNumber) \
  2093. FUNSETTING(AreaCode) \
  2094. FUNSETTING(CountryCode) \
  2095. FUNSETTING(CountryID) \
  2096. FUNSETTING(UseDialingRules) \
  2097. STRSETTING(Comment,S_EMPTY) \
  2098. STRSETTING(LastSelectedPhone,S_EMPTY) \
  2099. STRSETTING(PromoteAlternates,S_EMPTY) \
  2100. STRSETTING(TryNextAlternateOnFail,S_EMPTY) \
  2101. FUNSETTING(HwFlowControl) \
  2102. FUNSETTING(Protocol) \
  2103. FUNSETTING(Compression) \
  2104. FUNSETTING(Speaker) \
  2105. #define PAD_DEVICE_SETTINGS \
  2106. STRSETTING(X25Pad,S_EMPTY) \
  2107. STRSETTING(X25Address,S_EMPTY) \
  2108. STRSETTING(UserData,S_EMPTY) \
  2109. STRSETTING(Facilities,S_EMPTY) \
  2110. #define ISDN_DEVICE_SETTINGS \
  2111. FUNSETTING(PhoneNumber) \
  2112. FUNSETTING(AreaCode) \
  2113. FUNSETTING(CountryCode) \
  2114. FUNSETTING(CountryID) \
  2115. FUNSETTING(UseDialingRules) \
  2116. STRSETTING(Comment,S_EMPTY) \
  2117. STRSETTING(LastSelectedPhone,S_EMPTY) \
  2118. STRSETTING(PromoteAlternates,S_EMPTY) \
  2119. STRSETTING(TryNextAlternateOnFail,S_EMPTY) \
  2120. STRSETTING(LineType,S_EMPTY) \
  2121. STRSETTING(FallBack,S_EMPTY) \
  2122. STRSETTING(EnableCompressiong,S_EMPTY) \
  2123. STRSETTING(ChannelAggregation,S_EMPTY) \
  2124. #define X25_DEVICE_SETTINGS \
  2125. STRSETTING(X25Address,S_EMPTY) \
  2126. STRSETTING(UserData,S_EMPTY) \
  2127. STRSETTING(Facilities,S_EMPTY) \
  2128. //
  2129. // Function prototypes.
  2130. //
  2131. typedef PCTSTR (DATA_FUNCTION_PROTOTYPE)(VOID);
  2132. typedef DATA_FUNCTION_PROTOTYPE * DATA_FUNCTION;
  2133. #define FUNSETTING(Data) DATA_FUNCTION_PROTOTYPE pGet##Data;
  2134. #define STRSETTING(x,y)
  2135. ENTRY_SETTINGS
  2136. MEDIA_SETTINGS
  2137. SWITCH_DEVICE_SETTINGS
  2138. MODEM_DEVICE_SETTINGS
  2139. PAD_DEVICE_SETTINGS
  2140. ISDN_DEVICE_SETTINGS
  2141. X25_DEVICE_SETTINGS
  2142. #undef FUNSETTING
  2143. #undef STRSETTING
  2144. #define FUNSETTING(x) {TEXT(#x), pGet##x, NULL},
  2145. #define STRSETTING(x,y) {TEXT(#x), NULL, y},
  2146. #define LASTSETTING {NULL,NULL,NULL}
  2147. typedef struct {
  2148. PCTSTR SettingName;
  2149. DATA_FUNCTION SettingFunction;
  2150. PCTSTR SettingValue;
  2151. } RAS_SETTING, * PRAS_SETTING;
  2152. RAS_SETTING g_EntrySettings[] = {ENTRY_SETTINGS LASTSETTING};
  2153. RAS_SETTING g_MediaSettings[] = {MEDIA_SETTINGS LASTSETTING};
  2154. RAS_SETTING g_SwitchDeviceSettings[] = {SWITCH_DEVICE_SETTINGS LASTSETTING};
  2155. RAS_SETTING g_ModemDeviceSettings[] = {MODEM_DEVICE_SETTINGS LASTSETTING};
  2156. RAS_SETTING g_PadDeviceSettings[] = {PAD_DEVICE_SETTINGS LASTSETTING};
  2157. RAS_SETTING g_IsdnDeviceSettings[] = {ISDN_DEVICE_SETTINGS LASTSETTING};
  2158. RAS_SETTING g_X25DeviceSettings[] = {X25_DEVICE_SETTINGS LASTSETTING};
  2159. BOOL g_InSwitchSection = FALSE;
  2160. PCTSTR g_CurrentConnection = NULL;
  2161. UINT g_CurrentDevice = 0;
  2162. UINT g_CurrentDeviceType = 0;
  2163. #define RAS_BUFFER_SIZE MEMDB_MAX
  2164. TCHAR g_TempBuffer [RAS_BUFFER_SIZE];
  2165. HASHTABLE g_DeviceTable = NULL;
  2166. BOOL
  2167. pIs9xRasInstalled (
  2168. void
  2169. )
  2170. {
  2171. HKEY testKey = NULL;
  2172. BOOL rf = FALSE;
  2173. testKey = OpenRegKeyStr (S_SERVICEREMOTEACCESS);
  2174. if (testKey) {
  2175. //
  2176. // Open key succeeded. Assume RAS is installed.
  2177. //
  2178. rf = TRUE;
  2179. CloseRegKey(testKey);
  2180. }
  2181. return rf;
  2182. }
  2183. static BYTE NEAR PASCAL GenerateEncryptKey (LPCSTR szKey)
  2184. {
  2185. BYTE bKey;
  2186. LPBYTE lpKey;
  2187. for (bKey = 0, lpKey = (LPBYTE)szKey; *lpKey != 0; lpKey++)
  2188. {
  2189. bKey += *lpKey;
  2190. };
  2191. return bKey;
  2192. }
  2193. DWORD NEAR PASCAL EnDecryptEntry (LPCSTR szEntry, LPBYTE lpEnt,
  2194. DWORD cb)
  2195. {
  2196. BYTE bKey;
  2197. // Generate the encryption key from the entry name
  2198. bKey = GenerateEncryptKey(szEntry);
  2199. // Encrypt the address entry one byte at a time
  2200. for (;cb > 0; cb--, lpEnt++)
  2201. {
  2202. *lpEnt ^= bKey;
  2203. };
  2204. return ERROR_SUCCESS;
  2205. }
  2206. PTSTR
  2207. pGetComPort (
  2208. IN PCTSTR DriverDesc
  2209. )
  2210. {
  2211. PTSTR rPort = NULL;
  2212. if (!HtFindStringEx (g_DeviceTable, DriverDesc, &rPort, FALSE)) {
  2213. DEBUGMSG ((DBG_WARNING, "Could not find com port for device %s."));
  2214. }
  2215. if (!rPort) {
  2216. rPort = S_EMPTY;
  2217. }
  2218. return rPort;
  2219. }
  2220. VOID
  2221. pInitializeDeviceTable (
  2222. VOID
  2223. )
  2224. {
  2225. MIG_OBJECTSTRINGHANDLE encodedRegPattern;
  2226. REGTREE_ENUM e;
  2227. PTSTR com;
  2228. PTSTR desc;
  2229. PTSTR p;
  2230. encodedRegPattern = IsmCreateSimpleObjectPattern (S_MODEMS, TRUE, TEXT("*"), TRUE);
  2231. if (EnumFirstRegObjectInTreeEx (
  2232. &e,
  2233. encodedRegPattern,
  2234. TRUE,
  2235. TRUE,
  2236. TRUE,
  2237. TRUE,
  2238. 1,
  2239. FALSE,
  2240. TRUE,
  2241. RegEnumDefaultCallback
  2242. )) {
  2243. do {
  2244. // we don't care about value names, we only want subkeys
  2245. if (!e.CurrentValueData) {
  2246. com = desc = NULL;
  2247. com = GetRegValueString (e.CurrentKeyHandle, S_ATTACHEDTO);
  2248. desc = GetRegValueString (e.CurrentKeyHandle, S_DRIVERDESC);
  2249. if (com && desc) {
  2250. p = PmDuplicateString (g_RasPool, com);
  2251. HtAddStringEx (g_DeviceTable, desc, (PBYTE) &p, FALSE);
  2252. DEBUGMSG ((DBG_RASMIG, "%s on %s added to driver table.", desc, com));
  2253. }
  2254. if (com) {
  2255. MemFree (g_hHeap, 0, com);
  2256. }
  2257. if (desc) {
  2258. MemFree (g_hHeap, 0, desc);
  2259. }
  2260. }
  2261. } while (EnumNextRegObjectInTree (&e));
  2262. }
  2263. //
  2264. // Clean up resources.
  2265. //
  2266. IsmDestroyObjectHandle (encodedRegPattern);
  2267. }
  2268. BOOL
  2269. pGetPerUserSettings (
  2270. VOID
  2271. )
  2272. {
  2273. HKEY settingsKey;
  2274. PDWORD data;
  2275. PCTSTR entryStr;
  2276. BOOL rSuccess = TRUE;
  2277. settingsKey = OpenRegKeyStr (S_REMOTE_ACCESS_KEY);
  2278. if (settingsKey) {
  2279. //
  2280. // Get UI settings.
  2281. //
  2282. data = (PDWORD) GetRegValueBinary (settingsKey, S_DIALUI);
  2283. //
  2284. // Save Dial User Interface info into memdb for this user.
  2285. //
  2286. if (data) {
  2287. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_DIALUI, NULL));
  2288. rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
  2289. MemFree (g_hHeap, 0, data);
  2290. }
  2291. ELSE_DEBUGMSG ((DBG_RASMIG, "No user UI settings found for current user."));
  2292. //
  2293. // Get Redial information.
  2294. //
  2295. data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_REDIAL);
  2296. if (data) {
  2297. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_ENABLE_REDIAL, NULL));
  2298. rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
  2299. MemFree (g_hHeap, 0, data);
  2300. }
  2301. ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
  2302. data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_TRY);
  2303. if (data) {
  2304. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_REDIAL_TRY, NULL));
  2305. rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
  2306. MemFree (g_hHeap, 0, data);
  2307. }
  2308. ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
  2309. data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_WAIT);
  2310. if (data) {
  2311. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_REDIAL_WAIT, NULL));
  2312. rSuccess &= (MemDbSetValue (entryStr, HIWORD(*data) * 60 + LOWORD(*data)) != 0);
  2313. MemFree (g_hHeap, 0, data);
  2314. }
  2315. ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
  2316. //
  2317. // Get implicit connection information. (Controls wether connection ui should be displayed or not)
  2318. //
  2319. data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_IMPLICIT);
  2320. if (data) {
  2321. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_ENABLE_IMPLICIT, NULL));
  2322. rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
  2323. MemFree(g_hHeap,0,data);
  2324. }
  2325. ELSE_DEBUGMSG ((DBG_RASMIG, "No user implicit connection information found for current user."));
  2326. CloseRegKey(settingsKey);
  2327. }
  2328. return rSuccess;
  2329. }
  2330. VOID
  2331. pSaveConnectionDataToMemDb (
  2332. IN PCTSTR Entry,
  2333. IN PCTSTR ValueName,
  2334. IN DWORD ValueType,
  2335. IN PBYTE Value
  2336. )
  2337. {
  2338. KEYHANDLE keyHandle;
  2339. PCTSTR entryStr;
  2340. PCTSTR entryTmp;
  2341. entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, Entry, ValueName, NULL));
  2342. switch (ValueType) {
  2343. case REG_SZ:
  2344. case REG_MULTI_SZ:
  2345. case REG_EXPAND_SZ:
  2346. DEBUGMSG ((DBG_RASMIG, "String Data - %s = %s", ValueName, (PCTSTR) Value));
  2347. entryTmp = JoinPaths (MEMDB_CATEGORY_RAS_DATA, (PCTSTR) Value);
  2348. keyHandle = MemDbSetKey (entryTmp);
  2349. if (!keyHandle) {
  2350. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  2351. }
  2352. FreePathString (entryTmp);
  2353. if (!MemDbSetValueAndFlagsEx (entryStr, TRUE, keyHandle, TRUE, REG_SZ, 0)) {
  2354. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  2355. }
  2356. break;
  2357. case REG_DWORD:
  2358. DEBUGMSG ((DBG_RASMIG, "DWORD Data - %s = %u", ValueName, (DWORD)(ULONG_PTR) Value));
  2359. if (!MemDbSetValueAndFlagsEx (entryStr, TRUE, (DWORD)(ULONG_PTR) Value, TRUE, ValueType, 0)) {
  2360. DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
  2361. }
  2362. break;
  2363. case REG_BINARY:
  2364. DEBUGMSG ((DBG_RASMIG, "Binary data for %s.", ValueName));
  2365. if (StringIMatch (S_IPINFO, ValueName)) {
  2366. //
  2367. // Save IP address information.
  2368. //
  2369. pSaveConnectionDataToMemDb (Entry, S_IP_FTCPIP, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> fdwTCPIP);
  2370. pSaveConnectionDataToMemDb (Entry, S_IP_IPADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwIPAddr);
  2371. pSaveConnectionDataToMemDb (Entry, S_IP_DNSADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwDNSAddr);
  2372. pSaveConnectionDataToMemDb (Entry, S_IP_DNSADDR2, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwDNSAddrAlt);
  2373. pSaveConnectionDataToMemDb (Entry, S_IP_WINSADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwWINSAddr);
  2374. pSaveConnectionDataToMemDb (Entry, S_IP_WINSADDR2, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwWINSAddrAlt);
  2375. } else if (StringIMatch (S_TERMINAL, ValueName)) {
  2376. //
  2377. // save information on the showcmd state. This will tell us how to set the ui display.
  2378. //
  2379. pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD, (PBYTE)(ULONG_PTR)((PWINDOWPLACEMENT) Value) -> showCmd);
  2380. } else if (StringIMatch (S_MODE, ValueName)) {
  2381. //
  2382. // This value tells what to do with scripting.
  2383. //
  2384. pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD, (PBYTE)(ULONG_PTR) *((PDWORD) Value));
  2385. } else if (StringIMatch (S_MULTILINK, ValueName)) {
  2386. //
  2387. // Save wether or not multilink is enabled.
  2388. //
  2389. pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD,(PBYTE)(ULONG_PTR) *((PDWORD) Value));
  2390. } ELSE_DEBUGMSG ((DBG_WARNING, "Don't know how to handle binary data %s. It will be ignored.", ValueName));
  2391. break;
  2392. default:
  2393. DEBUGMSG ((DBG_WHOOPS, "Unknown type of registry data found in RAS settings. %s", ValueName));
  2394. break;
  2395. }
  2396. FreePathString (entryStr);
  2397. }
  2398. BOOL
  2399. pGetRasEntryAddressInfo (
  2400. IN PCTSTR KeyName,
  2401. IN PCTSTR EntryName
  2402. )
  2403. {
  2404. BOOL rSuccess = TRUE;
  2405. MIG_OBJECTSTRINGHANDLE encodedRegPattern;
  2406. MIG_OBJECTSTRINGHANDLE encodedSubPattern;
  2407. PBYTE data = NULL;
  2408. UINT count = 0;
  2409. UINT type = 0;
  2410. PADDRENTRY entry;
  2411. PSUBCONNENTRY subEntry;
  2412. PSMMCFG smmCfg;
  2413. PDEVICEINFO devInfo;
  2414. REGTREE_ENUM e;
  2415. PTSTR subEntriesKeyStr;
  2416. UINT sequencer = 0;
  2417. REGTREE_ENUM eSubEntries;
  2418. TCHAR buffer[MAX_TCHAR_PATH];
  2419. PMODEMDEVINFO modemInfo;
  2420. #ifdef UNICODE
  2421. PCSTR tempStr = NULL;
  2422. PCWSTR tempStrW = NULL;
  2423. #endif
  2424. //
  2425. // First we have to get the real entry name. It must match exactly even case. Unfortunately, it isn't neccessarily a given
  2426. // that the case between HKCU\RemoteAccess\Profiles\<Foo> and HKCU\RemoteAccess\Addresses\[Foo] is the same. The registry
  2427. // apis will of course work fine because they work case insensitively. However, I will be unable to decrypt the value
  2428. // if I use the wrong name.
  2429. //
  2430. encodedRegPattern = IsmCreateSimpleObjectPattern (KeyName, FALSE, TEXT("*"), TRUE);
  2431. if (EnumFirstRegObjectInTreeEx (
  2432. &e,
  2433. encodedRegPattern,
  2434. TRUE,
  2435. TRUE,
  2436. TRUE,
  2437. TRUE,
  2438. REGENUM_ALL_SUBLEVELS,
  2439. FALSE,
  2440. TRUE,
  2441. RegEnumDefaultCallback
  2442. )) {
  2443. do {
  2444. if (StringIMatch (e.Name, EntryName)) {
  2445. //
  2446. // Found the correct entry. Use it.
  2447. //
  2448. data = e.CurrentValueData;
  2449. if (data) {
  2450. entry = (PADDRENTRY) data;
  2451. #ifdef UNICODE
  2452. tempStr = ConvertWtoA (e.Name);
  2453. DECRYPTENTRY(tempStr, entry, e.CurrentValueDataSize);
  2454. FreeConvertedStr (tempStr);
  2455. #else
  2456. DECRYPTENTRY(e.Name, entry, e.CurrentValueDataSize);
  2457. #endif
  2458. smmCfg = PAESMMCFG(entry);
  2459. devInfo = PAEDI(entry);
  2460. pSaveConnectionDataToMemDb (EntryName, S_PHONE_NUMBER, REG_SZ, (PBYTE) PAEPHONE(entry));
  2461. pSaveConnectionDataToMemDb (EntryName, S_AREA_CODE, REG_SZ, (PBYTE) PAEAREA(entry));
  2462. pSaveConnectionDataToMemDb (EntryName, S_SMM, REG_SZ, (PBYTE) PAESMM(entry));
  2463. pSaveConnectionDataToMemDb (EntryName, S_COUNTRY_CODE, REG_DWORD, (PBYTE)(ULONG_PTR) entry -> dwCountryCode);
  2464. pSaveConnectionDataToMemDb (EntryName, S_COUNTRY_ID, REG_DWORD, (PBYTE)(ULONG_PTR) entry -> dwCountryID);
  2465. pSaveConnectionDataToMemDb (EntryName, S_DEVICE_NAME, REG_SZ, (PBYTE) devInfo -> szDeviceName);
  2466. pSaveConnectionDataToMemDb (EntryName, S_DEVICE_TYPE, REG_SZ, (PBYTE) devInfo -> szDeviceType);
  2467. pSaveConnectionDataToMemDb (EntryName, S_PROTOCOLS, REG_DWORD, (PBYTE)(ULONG_PTR) smmCfg -> fdwProtocols);
  2468. pSaveConnectionDataToMemDb (EntryName, S_SMM_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) smmCfg -> fdwOptions);
  2469. //
  2470. // Save device information away.
  2471. //
  2472. if (StringIMatchA (devInfo -> szDeviceType, S_MODEMA)) {
  2473. modemInfo = (PMODEMDEVINFO) (devInfo->szDeviceType + RAS_MaxDeviceType + 3);
  2474. if (modemInfo -> Size >= sizeof (MODEMDEVINFO)) {
  2475. DEBUGMSG_IF ((modemInfo -> Size > sizeof (MODEMDEVINFO), DBG_RASMIG, "Structure size larger than our known size."));
  2476. pSaveConnectionDataToMemDb (EntryName, S_MODEM_UI_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ModemUiOptions);
  2477. pSaveConnectionDataToMemDb (EntryName, S_MODEM_SPEED, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ConnectionSpeed);
  2478. pSaveConnectionDataToMemDb (EntryName, S_MODEM_SPEAKER_VOLUME, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> SpeakerVolume);
  2479. pSaveConnectionDataToMemDb (EntryName, S_MODEM_IDLE_DISCONNECT_SECONDS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> IdleDisconnectSeconds);
  2480. pSaveConnectionDataToMemDb (EntryName, S_MODEM_CANCEL_SECONDS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> CancelSeconds);
  2481. pSaveConnectionDataToMemDb (EntryName, S_MODEM_CFG_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ConfigOptions);
  2482. #ifdef UNICODE
  2483. tempStrW = ConvertAtoW (devInfo->szDeviceName);
  2484. pSaveConnectionDataToMemDb (EntryName, S_MODEM_COM_PORT, REG_SZ, (PBYTE) pGetComPort (tempStrW));
  2485. FreeConvertedStr (tempStrW);
  2486. #else
  2487. pSaveConnectionDataToMemDb (EntryName, S_MODEM_COM_PORT, REG_SZ, (PBYTE) pGetComPort (devInfo->szDeviceName));
  2488. #endif
  2489. }
  2490. ELSE_DEBUGMSG ((DBG_WHOOPS, "No modem configuration data saved. Size smaller than known structure. Investigate."));
  2491. }
  2492. //
  2493. // If SMM is not SLIP, CSLIP or PPP, we need to add a message to the upgrade report.
  2494. //
  2495. if (!StringIMatchA (PAESMM(entry), S_SLIPA) && !StringIMatchA (PAESMM(entry), S_PPPA) && !StringIMatchA (PAESMM(entry), S_CSLIPA)) {
  2496. LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, EntryName));
  2497. }
  2498. }
  2499. //
  2500. // Check to see if there are any sub-entries for this connection (MULTILINK settings..)
  2501. //
  2502. //
  2503. // Luckily, we don't have to do the same enumeration of these entries as we had to above to get around
  2504. // the case sensitivity bug. the 9x code uses the address key name above for encryption/decryption.
  2505. //
  2506. subEntriesKeyStr = JoinPathsInPoolEx ((NULL, KeyName, S_SUBENTRIES, e.Name, NULL));
  2507. sequencer = 1;
  2508. encodedSubPattern = IsmCreateSimpleObjectPattern (subEntriesKeyStr, FALSE, TEXT("*"), TRUE);
  2509. if (EnumFirstRegObjectInTreeEx (
  2510. &eSubEntries,
  2511. encodedSubPattern,
  2512. TRUE,
  2513. TRUE,
  2514. TRUE,
  2515. TRUE,
  2516. REGENUM_ALL_SUBLEVELS,
  2517. FALSE,
  2518. TRUE,
  2519. RegEnumDefaultCallback
  2520. )) {
  2521. do {
  2522. DEBUGMSG ((DBG_RASMIG, "Multi-Link Subentries found for entry %s. Processing.", e.Name));
  2523. data = eSubEntries.CurrentValueData;
  2524. if (data) {
  2525. subEntry = (PSUBCONNENTRY) data;
  2526. #ifdef UNICODE
  2527. tempStr = ConvertWtoA (e.Name);
  2528. DECRYPTENTRY (tempStr, subEntry, eSubEntries.CurrentValueDataSize);
  2529. FreeConvertedStr (tempStr);
  2530. #else
  2531. DECRYPTENTRY (e.Name, subEntry, eSubEntries.CurrentValueDataSize);
  2532. #endif
  2533. wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_DEVICE_TYPE);
  2534. pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szDeviceType);
  2535. wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_DEVICE_NAME);
  2536. pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szDeviceName);
  2537. wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_PHONE_NUMBER);
  2538. pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szLocal);
  2539. wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_MODEM_COM_PORT);
  2540. #ifdef UNICODE
  2541. tempStrW = ConvertAtoW (subEntry->szDeviceName);
  2542. pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) pGetComPort (tempStrW));
  2543. FreeConvertedStr (tempStrW);
  2544. #else
  2545. pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) pGetComPort (subEntry->szDeviceName));
  2546. #endif
  2547. }
  2548. sequencer++;
  2549. } while (EnumNextRegObjectInTree (&eSubEntries));
  2550. }
  2551. IsmDestroyObjectHandle (encodedSubPattern);
  2552. FreePathString (subEntriesKeyStr);
  2553. //
  2554. // Save away the number of devices associated with this connection
  2555. //
  2556. pSaveConnectionDataToMemDb (EntryName, S_DEVICECOUNT, REG_DWORD, (PBYTE)(ULONG_PTR) sequencer);
  2557. //
  2558. // We're done. Break out of the enumeration.
  2559. //
  2560. AbortRegObjectInTreeEnum (&e);
  2561. break;
  2562. }
  2563. } while (EnumNextRegObjectInTree (&e));
  2564. }
  2565. IsmDestroyObjectHandle (encodedRegPattern);
  2566. return rSuccess;
  2567. }
  2568. BOOL
  2569. pGetRasEntrySettings (
  2570. IN PCTSTR KeyName,
  2571. IN PCTSTR EntryName
  2572. )
  2573. {
  2574. REGTREE_ENUM e;
  2575. MIG_OBJECTSTRINGHANDLE encodedRegPattern;
  2576. PBYTE curData = NULL;
  2577. BOOL rSuccess = TRUE;
  2578. encodedRegPattern = IsmCreateSimpleObjectPattern (KeyName, FALSE, TEXT("*"), TRUE);
  2579. if (EnumFirstRegObjectInTreeEx (
  2580. &e,
  2581. encodedRegPattern,
  2582. TRUE,
  2583. TRUE,
  2584. TRUE,
  2585. TRUE,
  2586. REGENUM_ALL_SUBLEVELS,
  2587. FALSE,
  2588. TRUE,
  2589. RegEnumDefaultCallback
  2590. )) {
  2591. do {
  2592. if (e.CurrentValueData) {
  2593. pSaveConnectionDataToMemDb (
  2594. EntryName,
  2595. e.Name,
  2596. e.CurrentValueType,
  2597. e.CurrentValueType == REG_DWORD ? (PBYTE)(ULONG_PTR) (*((PDWORD)e.CurrentValueData)) : e.CurrentValueData
  2598. );
  2599. }
  2600. } while (EnumNextRegObjectInTree (&e));
  2601. }
  2602. IsmDestroyObjectHandle (encodedRegPattern);
  2603. return rSuccess;
  2604. }
  2605. BOOL
  2606. pGetPerConnectionSettings (
  2607. VOID
  2608. )
  2609. {
  2610. MIG_OBJECTSTRINGHANDLE encodedRegPattern;
  2611. REGTREE_ENUM e;
  2612. PCTSTR entryKey = NULL;
  2613. BOOL rSuccess = TRUE;
  2614. encodedRegPattern = IsmCreateSimpleObjectPattern (S_ADDRESSES_KEY, FALSE, TEXT("*"), TRUE);
  2615. //
  2616. // Enumerate each entry for this user.
  2617. //
  2618. if (EnumFirstRegObjectInTreeEx (
  2619. &e,
  2620. encodedRegPattern,
  2621. TRUE,
  2622. TRUE,
  2623. TRUE,
  2624. TRUE,
  2625. REGENUM_ALL_SUBLEVELS,
  2626. FALSE,
  2627. TRUE,
  2628. RegEnumDefaultCallback
  2629. )) {
  2630. do {
  2631. //
  2632. // Get base connection info -- stored as binary blob under address key.
  2633. // All connections will have this info -- It contains such things
  2634. // as the phone number, area code, dialing rules, etc.. It does
  2635. // not matter wether the connection has been used or not.
  2636. //
  2637. rSuccess &= pGetRasEntryAddressInfo (S_ADDRESSES_KEY, e.Name);
  2638. //
  2639. // Under the profile key are negotiated options for the connection.
  2640. // This key will only exist if the entry has actually been connected
  2641. // to by the user.
  2642. //
  2643. entryKey = JoinPaths (S_PROFILE_KEY, e.Name);
  2644. if (entryKey) {
  2645. rSuccess &= pGetRasEntrySettings (entryKey, e.Name);
  2646. FreePathString (entryKey);
  2647. }
  2648. } while (EnumNextRegObjectInTree (&e));
  2649. }
  2650. //
  2651. // Clean up resources.
  2652. //
  2653. IsmDestroyObjectHandle (encodedRegPattern);
  2654. return rSuccess;
  2655. }
  2656. BOOL
  2657. pGetRasDataFromMemDb (
  2658. IN PCTSTR DataName,
  2659. OUT PMEMDB_RAS_DATA Data
  2660. )
  2661. {
  2662. BOOL rSuccess = FALSE;
  2663. PCTSTR key;
  2664. DWORD value;
  2665. DWORD flags;
  2666. PCTSTR tempBuffer;
  2667. MYASSERT(DataName && Data && g_CurrentConnection);
  2668. key = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, g_CurrentConnection, DataName, NULL));
  2669. rSuccess = MemDbGetValueAndFlags (key, &value, &flags);
  2670. FreePathString (key);
  2671. //
  2672. // If that wasn't successful, we need to look in the per-user settings.
  2673. //
  2674. if (!rSuccess) {
  2675. key = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, DataName, NULL));
  2676. rSuccess = MemDbGetValueAndFlags (key, &value, &flags);
  2677. flags = REG_DWORD;
  2678. }
  2679. if (rSuccess) {
  2680. //
  2681. // There is information stored here. Fill it in and send it back to the user.
  2682. //
  2683. if (flags == REG_SZ) {
  2684. //
  2685. // String data, the value points to the offset for the string.
  2686. //
  2687. tempBuffer = MemDbGetKeyFromHandle (value, 1);
  2688. if (!tempBuffer) {
  2689. DEBUGMSG ((
  2690. DBG_ERROR,
  2691. "Could not retrieve RAS string information stored in Memdb. Entry=%s,Setting=%s",
  2692. g_CurrentConnection,
  2693. DataName
  2694. ));
  2695. return FALSE;
  2696. }
  2697. Data -> String = PmDuplicateString (g_RasPool, tempBuffer);
  2698. MemDbReleaseMemory (tempBuffer);
  2699. }
  2700. else {
  2701. //
  2702. // Not string data. The data is stored as the value.
  2703. //
  2704. Data -> Value = value;
  2705. }
  2706. Data -> DataType = (WORD) flags;
  2707. }
  2708. return rSuccess;
  2709. }
  2710. BOOL
  2711. pWritePhoneBookLine (
  2712. IN HANDLE FileHandle,
  2713. IN PCTSTR SettingName,
  2714. IN PCTSTR SettingValue
  2715. )
  2716. {
  2717. BOOL rSuccess = TRUE;
  2718. rSuccess &= WriteFileString (FileHandle, SettingName);
  2719. rSuccess &= WriteFileString (FileHandle, TEXT("="));
  2720. rSuccess &= WriteFileString (FileHandle, SettingValue ? SettingValue : S_EMPTY);
  2721. rSuccess &= WriteFileString (FileHandle, TEXT("\r\n"));
  2722. return rSuccess;
  2723. }
  2724. BOOL
  2725. pWriteSettings (
  2726. IN HANDLE FileHandle,
  2727. IN PRAS_SETTING SettingList
  2728. )
  2729. {
  2730. BOOL rSuccess = TRUE;
  2731. while (SettingList->SettingName) {
  2732. rSuccess &= pWritePhoneBookLine (
  2733. FileHandle,
  2734. SettingList->SettingName,
  2735. SettingList->SettingValue ?
  2736. SettingList->SettingValue :
  2737. SettingList->SettingFunction ());
  2738. SettingList++;
  2739. }
  2740. return rSuccess;
  2741. }
  2742. PCTSTR
  2743. pGetSpeaker (
  2744. VOID
  2745. )
  2746. {
  2747. MEMDB_RAS_DATA d;
  2748. if (g_CurrentDevice) {
  2749. return S_ONE;
  2750. }
  2751. if (!pGetRasDataFromMemDb (S_MODEM_SPEAKER_VOLUME, &d)) {
  2752. return S_ONE;
  2753. }
  2754. if (d.Value) {
  2755. return S_ONE;
  2756. }
  2757. return S_ZERO;
  2758. }
  2759. PCTSTR
  2760. pGetCompression (
  2761. VOID
  2762. )
  2763. {
  2764. MEMDB_RAS_DATA d;
  2765. if (g_CurrentDevice) {
  2766. return S_EMPTY;
  2767. }
  2768. if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
  2769. return S_EMPTY;
  2770. }
  2771. if (d.Value & RAS_CFG_FLAG_COMPRESS_DATA) {
  2772. return S_ONE;
  2773. }
  2774. return S_ZERO;
  2775. }
  2776. PCTSTR
  2777. pGetProtocol (
  2778. VOID
  2779. )
  2780. {
  2781. MEMDB_RAS_DATA d;
  2782. if (g_CurrentDevice) {
  2783. return S_EMPTY;
  2784. }
  2785. if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
  2786. return S_EMPTY;
  2787. }
  2788. if (d.Value & RAS_CFG_FLAG_USE_ERROR_CONTROL) {
  2789. return S_ONE;
  2790. }
  2791. return S_ZERO;
  2792. }
  2793. PCTSTR
  2794. pGetHwFlowControl (
  2795. VOID
  2796. )
  2797. {
  2798. MEMDB_RAS_DATA d;
  2799. if (g_CurrentDevice) {
  2800. return S_EMPTY;
  2801. }
  2802. if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
  2803. return S_EMPTY;
  2804. }
  2805. if (d.Value & RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL) {
  2806. return S_ONE;
  2807. }
  2808. return S_ZERO;
  2809. }
  2810. PCTSTR
  2811. pGetUseDialingRules (
  2812. VOID
  2813. )
  2814. {
  2815. MEMDB_RAS_DATA d;
  2816. //
  2817. // Win9x sets the areacode, countrycode, countryid to zero if
  2818. // use dialing rules is disabled. For ease, we test off of country
  2819. // code. If we can't get it, or, it is set to zero, we assume
  2820. // that we should _not_ use dialing rules.
  2821. //
  2822. if (!pGetRasDataFromMemDb(S_COUNTRY_CODE, &d) || !d.Value) {
  2823. return S_ZERO;
  2824. }
  2825. return S_ONE;
  2826. }
  2827. PCTSTR
  2828. pGetCountryID (
  2829. VOID
  2830. )
  2831. {
  2832. MEMDB_RAS_DATA d;
  2833. if (!pGetRasDataFromMemDb (S_COUNTRY_ID, &d) || !d.Value) {
  2834. return S_EMPTY;
  2835. }
  2836. wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
  2837. return g_TempBuffer;
  2838. }
  2839. PCTSTR
  2840. pGetCountryCode (
  2841. VOID
  2842. )
  2843. {
  2844. MEMDB_RAS_DATA d;
  2845. if (!pGetRasDataFromMemDb(S_COUNTRY_CODE, &d) || !d.Value) {
  2846. return S_EMPTY;
  2847. }
  2848. wsprintf(g_TempBuffer,TEXT("%d"),d.Value);
  2849. return g_TempBuffer;
  2850. }
  2851. PCTSTR
  2852. pGetAreaCode (
  2853. VOID
  2854. )
  2855. {
  2856. MEMDB_RAS_DATA d;
  2857. if (!pGetRasDataFromMemDb(S_AREA_CODE, &d)) {
  2858. return S_EMPTY;
  2859. }
  2860. return d.String;
  2861. }
  2862. PCTSTR
  2863. pGetPhoneNumber (
  2864. VOID
  2865. )
  2866. {
  2867. MEMDB_RAS_DATA d;
  2868. TCHAR buffer[MAX_TCHAR_PATH];
  2869. if (g_CurrentDevice == 0) {
  2870. if (!pGetRasDataFromMemDb(S_PHONE_NUMBER, &d)) {
  2871. return S_EMPTY;
  2872. }
  2873. }
  2874. else {
  2875. wsprintf(buffer,TEXT("ml%d%s"),g_CurrentDevice,S_PHONE_NUMBER);
  2876. if (!pGetRasDataFromMemDb(buffer, &d)) {
  2877. return S_EMPTY;
  2878. }
  2879. }
  2880. return d.String;
  2881. }
  2882. PCTSTR
  2883. pGetScript (
  2884. VOID
  2885. )
  2886. {
  2887. MEMDB_RAS_DATA d;
  2888. if (!pGetRasDataFromMemDb (S_PPPSCRIPT, &d)) {
  2889. return S_ZERO;
  2890. }
  2891. return S_ONE;
  2892. }
  2893. PCTSTR
  2894. pGetTerminal (
  2895. VOID
  2896. )
  2897. {
  2898. MEMDB_RAS_DATA d;
  2899. if (!pGetRasDataFromMemDb (S_MODEM_UI_OPTIONS, &d)) {
  2900. return S_EMPTY;
  2901. }
  2902. if (d.Value & (RAS_UI_FLAG_TERMBEFOREDIAL | RAS_UI_FLAG_TERMAFTERDIAL)) {
  2903. return S_ONE;
  2904. }
  2905. return S_ZERO;
  2906. }
  2907. PCTSTR
  2908. pGetName (
  2909. VOID
  2910. )
  2911. {
  2912. MEMDB_RAS_DATA d;
  2913. if (!pGetRasDataFromMemDb (S_PPPSCRIPT, &d)) {
  2914. return S_EMPTY;
  2915. }
  2916. else {
  2917. return d.String;
  2918. }
  2919. }
  2920. PCTSTR
  2921. pGetDEVICE (
  2922. VOID
  2923. )
  2924. {
  2925. if (g_InSwitchSection) {
  2926. return TEXT("Switch");
  2927. }
  2928. if (g_CurrentDeviceType == RASTYPE_VPN) {
  2929. return TEXT("rastapi");
  2930. }
  2931. return TEXT("modem");
  2932. }
  2933. PCTSTR
  2934. pGetConnectBps (
  2935. VOID
  2936. )
  2937. {
  2938. MEMDB_RAS_DATA d;
  2939. if (!g_CurrentDevice) {
  2940. if (!pGetRasDataFromMemDb (S_MODEM_SPEED, &d)) {
  2941. return S_EMPTY;
  2942. }
  2943. wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
  2944. return g_TempBuffer;
  2945. }
  2946. return S_EMPTY;
  2947. }
  2948. PCTSTR
  2949. pGetDevice (
  2950. VOID
  2951. )
  2952. {
  2953. PTSTR p = S_MODEM_COM_PORT;
  2954. PTSTR value = NULL;
  2955. MEMDB_RAS_DATA d;
  2956. //
  2957. // Very easy if this is a vpn connection.
  2958. //
  2959. if (g_CurrentDeviceType == RASTYPE_VPN) {
  2960. return TEXT("rastapi");
  2961. }
  2962. if (g_CurrentDevice) {
  2963. wsprintf (g_TempBuffer, TEXT("ml%d%s"), g_CurrentDevice, S_MODEM_COM_PORT);
  2964. p = g_TempBuffer;
  2965. }
  2966. if (!pGetRasDataFromMemDb (p, &d)) {
  2967. return S_EMPTY;
  2968. }
  2969. if (!HtFindStringEx (g_DeviceTable, d.String, &value, FALSE)) {
  2970. return S_EMPTY;
  2971. }
  2972. return value;
  2973. }
  2974. PCTSTR
  2975. pGetPort (
  2976. VOID
  2977. )
  2978. {
  2979. PTSTR value = NULL;
  2980. MEMDB_RAS_DATA d;
  2981. PTSTR p = S_MODEM_COM_PORT;
  2982. if (g_CurrentDeviceType == RASTYPE_VPN) {
  2983. return TEXT("VPN2-0");
  2984. }
  2985. if (g_CurrentDevice) {
  2986. wsprintf (g_TempBuffer, TEXT("ml%d%s"), g_CurrentDevice, S_MODEM_COM_PORT);
  2987. p = g_TempBuffer;
  2988. }
  2989. if (!pGetRasDataFromMemDb (p, &d)) {
  2990. return S_EMPTY;
  2991. }
  2992. if (!HtFindStringEx (g_DeviceTable, d.String, &value, FALSE)) {
  2993. return S_EMPTY;
  2994. }
  2995. return d.String;
  2996. }
  2997. PCTSTR
  2998. pGetMEDIA (
  2999. VOID
  3000. )
  3001. {
  3002. if (g_CurrentDeviceType == RASTYPE_VPN) {
  3003. return TEXT("rastapi");
  3004. }
  3005. else {
  3006. return TEXT("Serial");
  3007. }
  3008. }
  3009. PCTSTR
  3010. pGetIpNameAssign (
  3011. VOID
  3012. )
  3013. {
  3014. MEMDB_RAS_DATA d;
  3015. if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
  3016. return S_EMPTY;
  3017. }
  3018. else if (d.Value & IPF_NAME_SPECIFIED) {
  3019. return TEXT("2");
  3020. }
  3021. else {
  3022. return S_ONE;
  3023. }
  3024. }
  3025. PCTSTR
  3026. pGetNetAddress (
  3027. IN PCTSTR Setting
  3028. )
  3029. {
  3030. MEMDB_RAS_DATA d;
  3031. BYTE address[4];
  3032. if (!pGetRasDataFromMemDb (Setting, &d) || !d.Value) {
  3033. return S_EMPTY;
  3034. }
  3035. //
  3036. // Data is stored as a REG_DWORD.
  3037. // We need to write it in dotted decimal form.
  3038. //
  3039. *((LPDWORD)address) = d.Value;
  3040. wsprintf (
  3041. g_TempBuffer,
  3042. TEXT("%d.%d.%d.%d"),
  3043. address[3],
  3044. address[2],
  3045. address[1],
  3046. address[0]
  3047. );
  3048. return g_TempBuffer;
  3049. }
  3050. PCTSTR
  3051. pGetIpWINS2Address (
  3052. VOID
  3053. )
  3054. {
  3055. return pGetNetAddress (S_IP_WINSADDR2);
  3056. }
  3057. PCTSTR
  3058. pGetIpWINSAddress (
  3059. VOID
  3060. )
  3061. {
  3062. return pGetNetAddress (S_IP_WINSADDR);
  3063. }
  3064. PCTSTR
  3065. pGetIpDns2Address (
  3066. VOID
  3067. )
  3068. {
  3069. return pGetNetAddress (S_IP_DNSADDR2);
  3070. }
  3071. PCTSTR
  3072. pGetIpDnsAddress (
  3073. VOID
  3074. )
  3075. {
  3076. return pGetNetAddress (S_IP_DNSADDR);
  3077. }
  3078. PCTSTR
  3079. pGetIpAssign (
  3080. VOID
  3081. )
  3082. {
  3083. MEMDB_RAS_DATA d;
  3084. if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
  3085. return S_EMPTY;
  3086. }
  3087. else if (d.Value & IPF_IP_SPECIFIED) {
  3088. return TEXT("2");
  3089. }
  3090. else {
  3091. return S_ONE;
  3092. }
  3093. }
  3094. PCTSTR
  3095. pGetIpAddress (
  3096. VOID
  3097. )
  3098. {
  3099. return pGetNetAddress (S_IP_IPADDR);
  3100. }
  3101. PCTSTR
  3102. pGetIpHeaderCompression (
  3103. VOID
  3104. )
  3105. {
  3106. MEMDB_RAS_DATA d;
  3107. if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
  3108. return S_EMPTY;
  3109. }
  3110. else if (d.Value & IPF_NO_COMPRESS) {
  3111. return S_ZERO;
  3112. }
  3113. else {
  3114. return S_ONE;
  3115. }
  3116. }
  3117. PCTSTR
  3118. pGetIpPrioritizeRemote (
  3119. VOID
  3120. )
  3121. {
  3122. MEMDB_RAS_DATA d;
  3123. if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
  3124. return S_ONE;
  3125. }
  3126. else if (d.Value & IPF_NO_WAN_PRI) {
  3127. return S_ZERO;
  3128. }
  3129. else {
  3130. return S_ONE;
  3131. }
  3132. }
  3133. PCTSTR
  3134. pGetPreviewUserPw (
  3135. VOID
  3136. )
  3137. {
  3138. MEMDB_RAS_DATA d;
  3139. if (!pGetRasDataFromMemDb (S_DIALUI, &d)) {
  3140. return S_ONE;
  3141. }
  3142. if (d.Value & DIALUI_DONT_PROMPT_FOR_INFO) {
  3143. return S_ZERO;
  3144. }
  3145. return S_ONE;
  3146. }
  3147. PCTSTR
  3148. pGetPreviewPhoneNumber (
  3149. VOID
  3150. )
  3151. {
  3152. if (g_CurrentDeviceType == RASTYPE_VPN) {
  3153. return S_ZERO;
  3154. }
  3155. return pGetPreviewUserPw ();
  3156. }
  3157. PCTSTR
  3158. pGetPreviewDomain (
  3159. VOID
  3160. )
  3161. {
  3162. MEMDB_RAS_DATA d;
  3163. if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
  3164. return S_ONE;
  3165. }
  3166. //
  3167. // if 0x04 is set, then preview domain, otherwise don't.
  3168. //
  3169. if (d.Value & SMMCFG_NW_LOGON) {
  3170. return S_ONE;
  3171. }
  3172. return S_ZERO;
  3173. }
  3174. PCTSTR
  3175. pGetIdleDisconnectSeconds (
  3176. VOID
  3177. )
  3178. {
  3179. MEMDB_RAS_DATA d;
  3180. if (!pGetRasDataFromMemDb (S_MODEM_IDLE_DISCONNECT_SECONDS, &d)) {
  3181. return S_EMPTY;
  3182. }
  3183. wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
  3184. return g_TempBuffer;
  3185. }
  3186. PCTSTR
  3187. pGetRedialSeconds (
  3188. VOID
  3189. )
  3190. {
  3191. MEMDB_RAS_DATA d;
  3192. //
  3193. // NT wants this as a total number of seconds. The data we have from 9x has
  3194. // the number of minutes in the hiword and the number of seconds in the loword.
  3195. //
  3196. if (!pGetRasDataFromMemDb (S_REDIAL_WAIT, &d)) {
  3197. return S_EMPTY;
  3198. }
  3199. wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
  3200. return g_TempBuffer;
  3201. }
  3202. PCTSTR
  3203. pGetRedialAttempts (
  3204. VOID
  3205. )
  3206. {
  3207. MEMDB_RAS_DATA d;
  3208. //
  3209. // Before getting the number of redial attempts on windows 9x,
  3210. // we need to ensure that redialing is enabled. If it is not
  3211. // enabled, we set this field to zero, regardless.
  3212. //
  3213. if (pGetRasDataFromMemDb (S_ENABLE_REDIAL, &d)) {
  3214. if (!d.Value) {
  3215. return S_ZERO;
  3216. }
  3217. }
  3218. //
  3219. // If we have gotten this far, then redialing is enabled.
  3220. //
  3221. if (!pGetRasDataFromMemDb (S_REDIAL_TRY, &d)) {
  3222. DEBUGMSG((DBG_WARNING, "Redialing enabled, but no redial attempts info found."));
  3223. return S_ZERO;
  3224. }
  3225. wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
  3226. return g_TempBuffer;
  3227. }
  3228. PCTSTR
  3229. pGetAuthRestrictions (
  3230. VOID
  3231. )
  3232. {
  3233. MEMDB_RAS_DATA d;
  3234. if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
  3235. return S_EMPTY;
  3236. }
  3237. //
  3238. // password should be encrypted if 0x02 is set.
  3239. //
  3240. if (d.Value & SMMCFG_PW_ENCRYPTED) {
  3241. return TEXT("2");
  3242. }
  3243. return S_EMPTY;
  3244. }
  3245. PCTSTR
  3246. pGetShowMonitorIconInTaskBar (
  3247. VOID
  3248. )
  3249. {
  3250. MEMDB_RAS_DATA d;
  3251. //
  3252. // This information is stored packed with other Dialing UI on
  3253. // windows 9x. All we need to do is look for the specific
  3254. // bit which is set when this is turned off.
  3255. //
  3256. if (pGetRasDataFromMemDb (S_DIALUI, &d) && (d.Value & DIALUI_DONT_SHOW_ICON)) {
  3257. return S_ZERO;
  3258. }
  3259. return S_ONE;
  3260. }
  3261. PCTSTR
  3262. pGetSwCompression (
  3263. VOID
  3264. )
  3265. {
  3266. MEMDB_RAS_DATA d;
  3267. if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
  3268. return S_EMPTY;
  3269. }
  3270. //
  3271. // the 1 bit in SMM_OPTIONS controls software based compression.
  3272. // if it is set, the connection is able to handled compression,
  3273. // otherwise, it cannot.
  3274. //
  3275. if (d.Value & SMMCFG_SW_COMPRESSION) {
  3276. return S_ONE;
  3277. }
  3278. return S_ZERO;
  3279. }
  3280. PCTSTR
  3281. pGetDataEncryption (
  3282. VOID
  3283. )
  3284. {
  3285. MEMDB_RAS_DATA d;
  3286. BOOL reqDataEncrypt;
  3287. if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
  3288. return S_EMPTY;
  3289. }
  3290. //
  3291. // data should be encrypted if 0x1000 is set.
  3292. //
  3293. reqDataEncrypt = (d.Value & 0x1000);
  3294. if (!reqDataEncrypt) {
  3295. reqDataEncrypt = (d.Value & 0x200);
  3296. }
  3297. return reqDataEncrypt ? TEXT("256") : TEXT("8");
  3298. }
  3299. PCTSTR
  3300. pGetExcludedProtocols (
  3301. VOID
  3302. )
  3303. {
  3304. MEMDB_RAS_DATA d;
  3305. //
  3306. // Excluded protocols lists what protocols
  3307. // are _not_ available for a particular ras connection.
  3308. // This is a bit field where bits are set for each protocol
  3309. // that is excluded.
  3310. // NP_Nbf (0x1), NP_Ipx (0x2), NP_Ip (0x4)
  3311. // Luckily, these are the same definitions as for win9x, except
  3312. // each bit represents a protocol that is _enabled_ not
  3313. // _disabled_. Therefore, all we need to do is reverse the bottom
  3314. // three bits of the number.
  3315. //
  3316. if (!pGetRasDataFromMemDb (S_PROTOCOLS, &d)) {
  3317. //
  3318. // No data found, so we default to all protocols enabled.
  3319. //
  3320. return S_ZERO;
  3321. }
  3322. wsprintf (g_TempBuffer, TEXT("%d"), ~d.Value & 0x7);
  3323. return g_TempBuffer;
  3324. }
  3325. PCTSTR
  3326. pGetVpnStrategy (
  3327. VOID
  3328. )
  3329. {
  3330. if (g_CurrentDeviceType == RASTYPE_VPN) {
  3331. return TEXT("2");
  3332. }
  3333. return S_EMPTY;
  3334. }
  3335. PCTSTR
  3336. pGetBaseProtocol (
  3337. VOID
  3338. )
  3339. {
  3340. MEMDB_RAS_DATA d;
  3341. //
  3342. // Only supported protocol types for NT 5 are
  3343. // BP_PPP (0x1), BP_SLIP (0x2), and BP_RAS (0x3)
  3344. //
  3345. // If we can't find one, we default to BP_PPP.
  3346. //
  3347. if (!pGetRasDataFromMemDb (S_SMM, &d) || StringIMatch (d.String, S_PPP)) {
  3348. return S_ONE;
  3349. }
  3350. //
  3351. // MaP CSLIP to SLIP -- Header Compression will be on.
  3352. //
  3353. if (StringIMatch (d.String, S_SLIP) || StringIMatch (d.String, S_CSLIP)) {
  3354. return TEXT("2");
  3355. }
  3356. DEBUGMSG ((
  3357. DBG_WARNING,
  3358. "RAS Migration: Unusable base protocol type (%s) for entry %s. Forcing PPP.",
  3359. d.String,
  3360. g_CurrentConnection
  3361. ));
  3362. // we are going to return an invalid protocol so the connection
  3363. // does not get migrated.
  3364. return TEXT("3");
  3365. }
  3366. PCTSTR
  3367. pGetCredPassword (
  3368. VOID
  3369. )
  3370. {
  3371. return S_EMPTY;
  3372. }
  3373. PCTSTR
  3374. pGetCredDomain (
  3375. VOID
  3376. )
  3377. {
  3378. MEMDB_RAS_DATA d;
  3379. if (!pGetRasDataFromMemDb (S_DOMAIN, &d)) {
  3380. return S_EMPTY;
  3381. }
  3382. return d.String;
  3383. }
  3384. PCTSTR
  3385. pGetCredName (
  3386. VOID
  3387. )
  3388. {
  3389. MEMDB_RAS_DATA d;
  3390. if (!pGetRasDataFromMemDb (S_USER, &d)) {
  3391. return S_EMPTY;
  3392. }
  3393. return d.String;
  3394. }
  3395. PCTSTR
  3396. pGetCredMask (
  3397. VOID
  3398. )
  3399. {
  3400. return TEXT("0x00000005");
  3401. }
  3402. PCTSTR
  3403. pGetType (
  3404. VOID
  3405. )
  3406. {
  3407. if (g_CurrentDeviceType == RASTYPE_VPN) {
  3408. return TEXT("2");
  3409. }
  3410. else {
  3411. return S_ONE;
  3412. }
  3413. }
  3414. BOOL
  3415. pCreateUserPhonebook (
  3416. IN PCTSTR PbkFile
  3417. )
  3418. {
  3419. PCTSTR tempKey;
  3420. BOOL noError = FALSE;
  3421. MEMDB_RAS_DATA d;
  3422. MEMDB_ENUM e;
  3423. HANDLE file;
  3424. UINT i;
  3425. UINT count;
  3426. tempKey = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, TEXT("\\*"), NULL));
  3427. if (MemDbEnumFirst (&e, tempKey, ENUMFLAG_ALL, 1, 1)) {
  3428. //
  3429. // Open the phonebook file and set the file pointer to the EOF.
  3430. //
  3431. file = CreateFile (
  3432. PbkFile,
  3433. GENERIC_READ | GENERIC_WRITE,
  3434. 0, // No sharing.
  3435. NULL, // No inheritance
  3436. OPEN_ALWAYS,
  3437. FILE_ATTRIBUTE_NORMAL,
  3438. NULL // No template file.
  3439. );
  3440. if (file == INVALID_HANDLE_VALUE) {
  3441. DEBUGMSG ((DBG_ERROR, "Unable to open the phonebook file (%s)", PbkFile));
  3442. FreePathString (tempKey);
  3443. return FALSE;
  3444. }
  3445. SetFilePointer (file, 0, NULL, FILE_END);
  3446. //
  3447. // Now, enumerate all of the entries and write a phonebook entry to this
  3448. // file for each.
  3449. //
  3450. do {
  3451. g_CurrentConnection = e.KeyName;
  3452. g_CurrentDevice = 0;
  3453. if (!pGetRasDataFromMemDb (S_DEVICE_TYPE, &d)) {
  3454. g_CurrentDeviceType = RASTYPE_PHONE;
  3455. }
  3456. else {
  3457. if (StringIMatch (d.String, S_MODEM)) {
  3458. g_CurrentDeviceType = RASTYPE_PHONE;
  3459. }
  3460. else if (StringIMatch (d.String, S_VPN)) {
  3461. g_CurrentDeviceType = RASTYPE_VPN;
  3462. }
  3463. else {
  3464. g_CurrentDeviceType = RASTYPE_PHONE;
  3465. }
  3466. }
  3467. noError = TRUE;
  3468. //
  3469. // Add this entry to the phonebook.
  3470. //
  3471. //
  3472. // Write title.
  3473. //
  3474. noError &= WriteFileString (file, TEXT("["));
  3475. noError &= WriteFileString (file, g_CurrentConnection);
  3476. noError &= WriteFileString (file, TEXT("]\r\n"));
  3477. //
  3478. // Write base entry settings.
  3479. //
  3480. noError &= pWriteSettings (file, g_EntrySettings);
  3481. if (!pGetRasDataFromMemDb (S_DEVICECOUNT, &d)) {
  3482. count = 1;
  3483. DEBUGMSG ((DBG_WHOOPS, "No devices listed in memdb for connections %s.", g_CurrentConnection));
  3484. }
  3485. else {
  3486. count = d.Value;
  3487. }
  3488. for (i = 0; i < count; i++) {
  3489. g_CurrentDevice = i;
  3490. //
  3491. // Write media settings.
  3492. //
  3493. noError &= WriteFileString (file, TEXT("\r\n"));
  3494. noError &= pWriteSettings (file, g_MediaSettings);
  3495. //
  3496. // Write modem Device settings.
  3497. //
  3498. noError &= WriteFileString (file, TEXT("\r\n"));
  3499. noError &= pWriteSettings (file, g_ModemDeviceSettings);
  3500. noError &= WriteFileString (file, TEXT("\r\n\r\n"));
  3501. }
  3502. g_InSwitchSection = TRUE;
  3503. noError &= WriteFileString (file, TEXT("\r\n"));
  3504. noError &= pWriteSettings (file, g_SwitchDeviceSettings);
  3505. noError &= WriteFileString (file, TEXT("\r\n\r\n"));
  3506. g_InSwitchSection = FALSE;
  3507. if (!noError) {
  3508. LOG ((
  3509. LOG_ERROR,
  3510. "Error while writing phonebook for %s.",
  3511. g_CurrentConnection
  3512. ));
  3513. }
  3514. } while (MemDbEnumNext (&e));
  3515. //
  3516. // Close the handle to the phone book file.
  3517. //
  3518. CloseHandle (file);
  3519. }
  3520. ELSE_DEBUGMSG ((DBG_RASMIG, "No dial-up entries for current user."));
  3521. FreePathString (tempKey);
  3522. return noError;
  3523. }
  3524. MIG_OBJECTSTRINGHANDLE
  3525. pCreate9xPbkFile (
  3526. VOID
  3527. )
  3528. {
  3529. MIG_OBJECTSTRINGHANDLE result = NULL;
  3530. PCTSTR nativeName = NULL;
  3531. TCHAR windir [MAX_PATH];
  3532. BOOL b = FALSE;
  3533. GetWindowsDirectory (windir, MAX_PATH);
  3534. result = IsmCreateObjectHandle (windir, TEXT("usmt.pbk"));
  3535. if (!result) {
  3536. return NULL;
  3537. }
  3538. nativeName = IsmGetNativeObjectName (g_FileTypeId, result);
  3539. if (!nativeName) {
  3540. IsmDestroyObjectHandle (result);
  3541. return NULL;
  3542. }
  3543. if (pIs9xRasInstalled ()) {
  3544. g_DeviceTable = HtAllocWithData (sizeof (PTSTR));
  3545. MYASSERT (g_DeviceTable);
  3546. pInitializeDeviceTable ();
  3547. __try {
  3548. b = pGetPerUserSettings ();
  3549. b = b && pGetPerConnectionSettings ();
  3550. b = b && pCreateUserPhonebook (nativeName);
  3551. }
  3552. __except (TRUE) {
  3553. DEBUGMSG ((DBG_WHOOPS, "Caught an exception while processing ras settings."));
  3554. }
  3555. HtFree (g_DeviceTable);
  3556. }
  3557. IsmReleaseMemory (nativeName);
  3558. if (!b) {
  3559. IsmDestroyObjectHandle (result);
  3560. result = NULL;
  3561. }
  3562. return result;
  3563. }