You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

RAS.cs 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Shadowsocks.Util.SystemProxy
  8. {
  9. public static class RAS
  10. {
  11. private enum RasFieldSizeConstants
  12. {
  13. #region original header
  14. //#if (WINVER >= 0x400)
  15. //#define RAS_MaxEntryName 256
  16. //#define RAS_MaxDeviceName 128
  17. //#define RAS_MaxCallbackNumber RAS_MaxPhoneNumber
  18. //#else
  19. //#define RAS_MaxEntryName 20
  20. //#define RAS_MaxDeviceName 32
  21. //#define RAS_MaxCallbackNumber 48
  22. //#endif
  23. #endregion
  24. RAS_MaxEntryName = 256,
  25. RAS_MaxPath = 260
  26. }
  27. private const int ERROR_SUCCESS = 0;
  28. private const int RASBASE = 600;
  29. private const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3;
  30. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  31. private struct RasEntryName
  32. {
  33. #region original header
  34. //#define RASENTRYNAMEW struct tagRASENTRYNAMEW
  35. //RASENTRYNAMEW
  36. //{
  37. // DWORD dwSize;
  38. // WCHAR szEntryName[RAS_MaxEntryName + 1];
  39. //
  40. //#if (WINVER >= 0x500)
  41. // //
  42. // // If this flag is REN_AllUsers then its a
  43. // // system phonebook.
  44. // //
  45. // DWORD dwFlags;
  46. // WCHAR szPhonebookPath[MAX_PATH + 1];
  47. //#endif
  48. //};
  49. //
  50. //#define RASENTRYNAMEA struct tagRASENTRYNAMEA
  51. //RASENTRYNAMEA
  52. //{
  53. // DWORD dwSize;
  54. // CHAR szEntryName[RAS_MaxEntryName + 1];
  55. //
  56. //#if (WINVER >= 0x500)
  57. // DWORD dwFlags;
  58. // CHAR szPhonebookPath[MAX_PATH + 1];
  59. //#endif
  60. //};
  61. #endregion
  62. public int dwSize;
  63. [MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName + 1)]
  64. public string szEntryName;
  65. public int dwFlags;
  66. [MarshalAs(UnmanagedType.ByValTStr,SizeConst=(int)RasFieldSizeConstants.RAS_MaxPath + 1)]
  67. public string szPhonebookPath;
  68. }
  69. [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
  70. private static extern uint RasEnumEntries(
  71. string reserved, // reserved, must be NULL
  72. string lpszPhonebook, // pointer to full path and file name of phone-book file
  73. [In, Out] RasEntryName[] lprasentryname, // buffer to receive phone-book entries
  74. ref int lpcb, // size in bytes of buffer
  75. out int lpcEntries // number of entries written to buffer
  76. );
  77. /// <summary>
  78. /// Get all entries from RAS
  79. /// </summary>
  80. /// <param name="allConns"></param>
  81. /// <returns>
  82. /// 0: success with entries
  83. /// 1: success but no entries found
  84. /// 2: failed
  85. /// </returns>
  86. public static uint GetAllConns(ref string[] allConns)
  87. {
  88. int lpNames = 1;
  89. int entryNameSize = 0;
  90. int lpSize = 0;
  91. uint retval = ERROR_SUCCESS;
  92. RasEntryName[] names = null;
  93. entryNameSize = Marshal.SizeOf(typeof(RasEntryName));
  94. lpSize = lpNames * entryNameSize;
  95. names = new RasEntryName[lpNames];
  96. names[0].dwSize = entryNameSize;
  97. retval = RAS.RasEnumEntries(null, null, names, ref lpSize, out lpNames);
  98. //if we have more than one connection, we need to resize
  99. if (retval == ERROR_BUFFER_TOO_SMALL)
  100. {
  101. names = new RasEntryName[lpNames];
  102. for (int i = 0; i < names.Length; i++)
  103. {
  104. names[i].dwSize = entryNameSize;
  105. }
  106. retval = RAS.RasEnumEntries(null, null, names, ref lpSize, out lpNames);
  107. }
  108. if (retval == ERROR_SUCCESS)
  109. {
  110. if (lpNames == 0)
  111. {
  112. // no entries found.
  113. return 1;
  114. }
  115. allConns = new string[names.Length];
  116. for (int i = 0; i < names.Length; i++)
  117. {
  118. allConns[i] = names[i].szEntryName;
  119. }
  120. return 0;
  121. }
  122. else
  123. {
  124. return 2;
  125. }
  126. }
  127. }
  128. }