PageRenderTime 28ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/referencesource/System.ServiceModel/System/ServiceModel/ComIntegration/SafeNativeMethods.cs

https://github.com/pruiz/mono
C# | 888 lines | 780 code | 103 blank | 5 comment | 96 complexity | 87a80581672db98132f7b50828b25224 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.ComIntegration
  5. {
  6. using System;
  7. using System.Collections.Specialized;
  8. using System.ComponentModel;
  9. using System.Runtime;
  10. using System.Runtime.InteropServices;
  11. using System.Runtime.InteropServices.ComTypes;
  12. using System.Runtime.Versioning;
  13. using System.Security;
  14. using System.Security.Permissions;
  15. using System.Security.Principal;
  16. using System.ServiceModel.Diagnostics;
  17. using System.Text;
  18. using Microsoft.Win32.SafeHandles;
  19. using SafeCloseHandle = System.IdentityModel.SafeCloseHandle;
  20. using SafeHGlobalHandle = System.IdentityModel.SafeHGlobalHandle;
  21. [Flags]
  22. enum CLSCTX
  23. {
  24. INPROC_SERVER = 0x1,
  25. INPROC_HANDLER = 0x2,
  26. LOCAL_SERVER = 0x4,
  27. INPROC_SERVER16 = 0x8,
  28. REMOTE_SERVER = 0x10,
  29. INPROC_HANDLER16 = 0x20,
  30. RESERVED1 = 0x40,
  31. RESERVED2 = 0x80,
  32. RESERVED3 = 0x100,
  33. RESERVED4 = 0x200,
  34. NO_CODE_DOWNLOAD = 0x400,
  35. RESERVED5 = 0x800,
  36. NO_CUSTOM_MARSHAL = 0x1000,
  37. ENABLE_CODE_DOWNLOAD = 0x2000,
  38. NO_FAILURE_LOG = 0x4000,
  39. DISABLE_AAA = 0x8000,
  40. ENABLE_AAA = 0x10000,
  41. FROM_DEFAULT_CONTEXT = 0x20000,
  42. ACTIVATE_32_BIT_SERVER = 0x40000,
  43. ACTIVATE_64_BIT_SERVER = 0x80000,
  44. INPROC = INPROC_SERVER | INPROC_HANDLER,
  45. SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
  46. ALL = SERVER | INPROC_HANDLER
  47. }
  48. [Flags]
  49. enum ComRights
  50. {
  51. EXECUTE = 0x01,
  52. EXECUTE_LOCAL = 0x02,
  53. EXECUTE_REMOTE = 0x04,
  54. ACTIVATE_LOCAL = 0x08,
  55. ACTIVATE_REMOTE = 0x10
  56. }
  57. enum TOKEN_INFORMATION_CLASS
  58. {
  59. TokenUser = 1,
  60. TokenGroups,
  61. TokenPrivileges,
  62. TokenOwner,
  63. TokenPrimaryGroup,
  64. TokenDefaultDacl,
  65. TokenSource,
  66. TokenType,
  67. TokenImpersonationLevel,
  68. TokenStatistics,
  69. TokenRestrictedSids,
  70. TokenSessionId,
  71. TokenGroupsAndPrivileges,
  72. TokenSessionReference,
  73. TokenSandBoxInert
  74. }
  75. enum SecurityImpersonationLevel
  76. {
  77. Anonymous = 0,
  78. Identification = 1,
  79. Impersonation = 2,
  80. Delegation = 3,
  81. }
  82. enum TokenType
  83. {
  84. TokenPrimary = 1,
  85. TokenImpersonation
  86. }
  87. enum Win32Error
  88. {
  89. ERROR_SUCCESS = 0,
  90. ERROR_INSUFFICIENT_BUFFER = 122,
  91. ERROR_NO_TOKEN = 1008,
  92. ERROR_NONE_MAPPED = 1332,
  93. ERROR_NO_SUCH_DOMAIN = 1355,
  94. }
  95. enum EXTENDED_NAME_FORMAT
  96. {
  97. NameUnknown = 0,
  98. NameFullyQualifiedDN = 1,
  99. NameSamCompatible = 2,
  100. NameDisplay = 3,
  101. NameUniqueId = 6,
  102. NameCanonical = 7,
  103. NameUserPrincipalName = 8,
  104. NameCanonicalEx = 9,
  105. NameServicePrincipalName = 10,
  106. NameDnsDomainName = 12
  107. }
  108. [Flags]
  109. enum DSFlags : uint
  110. {
  111. DS_FORCE_REDISCOVERY = 0x00000001,
  112. DS_DIRECTORY_SERVICE_REQUIRED = 0x00000010,
  113. DS_DIRECTORY_SERVICE_PREFERRED = 0x00000020,
  114. DS_GC_SERVER_REQUIRED = 0x00000040,
  115. DS_PDC_REQUIRED = 0x00000080,
  116. DS_BACKGROUND_ONLY = 0x00000100,
  117. DS_IP_REQUIRED = 0x00000200,
  118. DS_KDC_REQUIRED = 0x00000400,
  119. DS_TIMESERV_REQUIRED = 0x00000800,
  120. DS_WRITABLE_REQUIRED = 0x00001000,
  121. DS_GOOD_TIMESERV_PREFERRED = 0x00002000,
  122. DS_AVOID_SELF = 0x00004000,
  123. DS_ONLY_LDAP_NEEDED = 0x00008000,
  124. DS_IS_FLAT_NAME = 0x00010000,
  125. DS_IS_DNS_NAME = 0x00020000,
  126. DS_TRY_NEXTCLOSEST_SITE = 0x00040000,
  127. DS_DIRECTORY_SERVICE_6_REQUIRED = 0x00080000,
  128. DS_WEB_SERVICE_REQUIRED = 0x00100000,
  129. DS_DIRECTORY_SERVICE_8_REQUIRED = 0x00200000,
  130. DS_RETURN_DNS_NAME = 0x40000000,
  131. DS_RETURN_FLAT_NAME = 0x80000000,
  132. }
  133. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  134. struct TagVariant
  135. {
  136. public ushort vt;
  137. public ushort reserved1;
  138. public ushort reserved2;
  139. public ushort reserved3;
  140. public IntPtr ptr;
  141. public IntPtr pRecInfo;
  142. }
  143. static class HR
  144. {
  145. internal static readonly int S_OK = 0;
  146. internal static readonly int S_FALSE = 1;
  147. internal static readonly int MK_E_SYNTAX = unchecked((int)0x800401e4);
  148. internal static readonly int E_INVALIDARG = unchecked((int)0x80070057);
  149. internal static readonly int E_UNEXPECTED = unchecked((int)0x8000ffff);
  150. internal static readonly int DISP_E_UNKNOWNINTERFACE = unchecked((int)0x80020001);
  151. internal static readonly int DISP_E_MEMBERNOTFOUND = unchecked((int)0x80020003);
  152. internal static readonly int DISP_E_PARAMNOTFOUND = unchecked((int)0x80020004);
  153. internal static readonly int DISP_E_TYPEMISMATCH = unchecked((int)0x80020005);
  154. internal static readonly int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006);
  155. internal static readonly int DISP_E_NONAMEDARGS = unchecked((int)0x80020007);
  156. internal static readonly int DISP_E_BADVARTYPE = unchecked((int)0x80020008);
  157. internal static readonly int DISP_E_EXCEPTION = unchecked((int)0x80020009);
  158. internal static readonly int DISP_E_OVERFLOW = unchecked((int)0x8002000A);
  159. internal static readonly int DISP_E_BADINDEX = unchecked((int)0x8002000B);
  160. internal static readonly int DISP_E_UNKNOWNLCID = unchecked((int)0x8002000C);
  161. internal static readonly int DISP_E_ARRAYISLOCKED = unchecked((int)0x8002000D);
  162. internal static readonly int DISP_E_BADPARAMCOUNT = unchecked((int)0x8002000E);
  163. internal static readonly int DISP_E_PARAMNOTOPTIONAL = unchecked((int)0x8002000F);
  164. internal static readonly int DISP_E_BADCALLEE = unchecked((int)0x80020010);
  165. internal static readonly int DISP_E_NOTACOLLECTION = unchecked((int)0x80020011);
  166. internal static readonly int DISP_E_DIVBYZERO = unchecked((int)0x80020012);
  167. internal static readonly int DISP_E_BUFFERTOOSMALL = unchecked((int)0x80020013);
  168. internal static readonly int RPC_E_TOO_LATE = unchecked((int)0x80010119);
  169. internal static readonly int RPC_NT_BINDING_HAS_NO_AUTH = unchecked((int)0x800706d2);
  170. internal static readonly int E_FAIL = unchecked((int)0x80040005);
  171. internal static readonly int COMADMIN_E_PARTITIONS_DISABLED = unchecked((int)0x80110824);
  172. internal static readonly int CONTEXT_E_NOTRANSACTION = unchecked((int)0x8004E027);
  173. internal static readonly int ERROR_BAD_IMPERSONATION_LEVEL = unchecked((int)(0x80070542));
  174. }
  175. static class InterfaceID
  176. {
  177. public static readonly Guid idISupportErrorInfo = new Guid("{df0b3d60-548f-101b-8e65-08002b2bd119}");
  178. public static readonly Guid idIDispatch = new Guid("00020400-0000-0000-C000-000000000046");
  179. }
  180. [StructLayout(LayoutKind.Sequential)]
  181. struct LUID
  182. {
  183. internal uint LowPart;
  184. internal int HighPart;
  185. }
  186. [StructLayout(LayoutKind.Sequential)]
  187. struct TOKEN_STATISTICS
  188. {
  189. internal LUID TokenId;
  190. internal LUID AuthenticationId;
  191. internal Int64 ExpirationTime;
  192. internal uint TokenType;
  193. internal SecurityImpersonationLevel ImpersonationLevel;
  194. internal uint DynamicCharged;
  195. internal uint DynamicAvailable;
  196. internal uint GroupCount;
  197. internal uint PrivilegeCount;
  198. internal LUID ModifiedId;
  199. }
  200. [StructLayout(LayoutKind.Sequential)]
  201. class GENERIC_MAPPING
  202. {
  203. internal uint genericRead = 0;
  204. internal uint genericWrite = 0;
  205. internal uint genericExecute = 0;
  206. internal uint genericAll = 0;
  207. }
  208. [Flags]
  209. internal enum PrivilegeAttribute : uint
  210. {
  211. SE_PRIVILEGE_DISABLED = 0x00000000, // note that this is not defined in the header files
  212. SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001,
  213. SE_PRIVILEGE_ENABLED = 0x00000002,
  214. SE_PRIVILEGE_REMOVED = 0X00000004,
  215. SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000,
  216. }
  217. [StructLayout(LayoutKind.Sequential)]
  218. struct LUID_AND_ATTRIBUTES
  219. {
  220. internal LUID Luid;
  221. internal PrivilegeAttribute Attributes;
  222. }
  223. [StructLayout(LayoutKind.Sequential)]
  224. class PRIVILEGE_SET
  225. {
  226. internal uint PrivilegeCount = 1;
  227. internal uint Control = 0;
  228. internal LUID_AND_ATTRIBUTES Privilege;
  229. }
  230. [SuppressUnmanagedCodeSecurity]
  231. static class SafeNativeMethods
  232. {
  233. internal const String KERNEL32 = "kernel32.dll";
  234. internal const String ADVAPI32 = "advapi32.dll";
  235. internal const String OLE32 = "ole32.dll";
  236. internal const String OLEAUT32 = "oleaut32.dll";
  237. internal const String COMSVCS = "comsvcs.dll";
  238. internal const String SECUR32 = "secur32.dll";
  239. internal const String NETAPI32 = "netapi32.dll";
  240. internal const int ERROR_MORE_DATA = 0xEA;
  241. internal const int ERROR_SUCCESS = 0;
  242. internal const int ERROR_INVALID_HANDLE = 6;
  243. internal const int ERROR_NOT_SUPPORTED = 50;
  244. internal const int READ_CONTROL = 0x00020000;
  245. internal const int SYNCHRONIZE = 0x00100000;
  246. internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
  247. internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
  248. internal const int KEY_QUERY_VALUE = 0x0001;
  249. internal const int KEY_SET_VALUE = 0x0002;
  250. internal const int KEY_CREATE_SUB_KEY = 0x0004;
  251. internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008;
  252. internal const int KEY_NOTIFY = 0x0010;
  253. internal const int KEY_CREATE_LINK = 0x0020;
  254. internal const int KEY_READ = ((STANDARD_RIGHTS_READ |
  255. KEY_QUERY_VALUE |
  256. KEY_ENUMERATE_SUB_KEYS |
  257. KEY_NOTIFY)
  258. &
  259. (~SYNCHRONIZE));
  260. internal const int KEY_WRITE = STANDARD_RIGHTS_WRITE |
  261. KEY_SET_VALUE |
  262. KEY_CREATE_SUB_KEY;
  263. internal const int REG_NONE = 0; // No value type
  264. internal const int REG_SZ = 1; // Unicode nul terminated string
  265. internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string
  266. internal const int KEY_WOW64_32KEY = (0x0200);
  267. internal const int KEY_WOW64_64KEY = (0x0100);
  268. // (with environment variable references)
  269. internal const int REG_BINARY = 3; // Free form binary
  270. internal const int REG_DWORD = 4; // 32-bit number
  271. internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD)
  272. internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number
  273. internal const int REG_LINK = 6; // Symbolic Link (unicode)
  274. internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings
  275. internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map
  276. internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description
  277. internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10;
  278. internal const int REG_QWORD = 11; // 64-bit number
  279. internal const int HWND_BROADCAST = 0xffff;
  280. internal const int WM_SETTINGCHANGE = 0x001A;
  281. [DllImport(ADVAPI32, CharSet = CharSet.Unicode, BestFitMapping = false)]
  282. [ResourceExposure(ResourceScope.Machine)]
  283. internal static extern int RegOpenKeyEx(RegistryHandle hKey, String lpSubKey,
  284. int ulOptions, int samDesired, out RegistryHandle hkResult);
  285. [DllImport(ADVAPI32, CharSet = CharSet.Unicode, BestFitMapping = false)]
  286. [ResourceExposure(ResourceScope.None)]
  287. internal static extern int RegSetValueEx(RegistryHandle hKey, String lpValueName,
  288. int Reserved, int dwType, String val, int cbData);
  289. [DllImport(ADVAPI32, SetLastError = false)]
  290. [ResourceExposure(ResourceScope.None)]
  291. internal static extern int RegCloseKey(IntPtr handle);
  292. [DllImport(ADVAPI32, CharSet = CharSet.Unicode, BestFitMapping = false)]
  293. [ResourceExposure(ResourceScope.None)]
  294. internal static extern int RegQueryValueEx(RegistryHandle hKey, String lpValueName,
  295. int[] lpReserved, ref int lpType, [Out] byte[] lpData,
  296. ref int lpcbData);
  297. [DllImport(ADVAPI32, CharSet = CharSet.Unicode, BestFitMapping = false)]
  298. [ResourceExposure(ResourceScope.None)]
  299. internal static extern int RegEnumKey(RegistryHandle hKey, int index, StringBuilder lpName, ref int len);
  300. [DllImport(ADVAPI32, CharSet = CharSet.Unicode, BestFitMapping = false)]
  301. [ResourceExposure(ResourceScope.None)]
  302. internal static extern int RegDeleteKey(RegistryHandle hKey, String lpValueName);
  303. [DllImport(ADVAPI32, SetLastError = true)]
  304. [ResourceExposure(ResourceScope.None)]
  305. internal static extern bool
  306. DuplicateTokenEx(
  307. [In] SafeCloseHandle ExistingToken,
  308. [In] TokenAccessLevels DesiredAccess,
  309. [In] IntPtr TokenAttributes,
  310. [In] SecurityImpersonationLevel ImpersonationLevel,
  311. [In] TokenType TokenType,
  312. [Out] out SafeCloseHandle NewToken);
  313. [DllImport(ADVAPI32, SetLastError = true)]
  314. [ResourceExposure(ResourceScope.None)]
  315. internal static extern bool
  316. AccessCheck(
  317. [In] byte[] SecurityDescriptor,
  318. [In] SafeCloseHandle ClientToken,
  319. [In] int DesiredAccess,
  320. [In] GENERIC_MAPPING GenericMapping,
  321. [Out] out PRIVILEGE_SET PrivilegeSet,
  322. [In, Out] ref uint PrivilegeSetLength,
  323. [Out] out uint GrantedAccess,
  324. [Out] out bool AccessStatus);
  325. [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "ImpersonateAnonymousToken")]
  326. [ResourceExposure(ResourceScope.None)]
  327. internal static extern bool
  328. ImpersonateAnonymousUserOnCurrentThread(
  329. [In] IntPtr CurrentThread);
  330. [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "OpenThreadToken")]
  331. [ResourceExposure(ResourceScope.None)]
  332. internal static extern bool
  333. OpenCurrentThreadToken(
  334. [In] IntPtr ThreadHandle,
  335. [In] TokenAccessLevels DesiredAccess,
  336. [In] bool OpenAsSelf,
  337. [Out] out SafeCloseHandle TokenHandle);
  338. [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "SetThreadToken")]
  339. [ResourceExposure(ResourceScope.None)]
  340. internal static extern bool
  341. SetCurrentThreadToken(
  342. [In] IntPtr ThreadHandle,
  343. [In] SafeCloseHandle TokenHandle);
  344. [DllImport(KERNEL32, SetLastError = true)]
  345. [ResourceExposure(ResourceScope.None)]
  346. internal static extern IntPtr
  347. GetCurrentThread();
  348. [DllImport(KERNEL32, SetLastError = false)]
  349. [ResourceExposure(ResourceScope.None)]
  350. internal static extern int
  351. GetCurrentThreadId();
  352. [DllImport(ADVAPI32, SetLastError = true)]
  353. [ResourceExposure(ResourceScope.None)]
  354. internal static extern bool
  355. RevertToSelf();
  356. [DllImport(ADVAPI32, SetLastError = true)]
  357. [ResourceExposure(ResourceScope.None)]
  358. internal static extern bool
  359. GetTokenInformation(
  360. [In] SafeCloseHandle TokenHandle,
  361. [In] TOKEN_INFORMATION_CLASS TokenInformationClass,
  362. [In] SafeHandle TokenInformation,
  363. [Out] uint TokenInformationLength,
  364. [Out] out uint ReturnLength);
  365. [DllImport(KERNEL32, SetLastError = true)]
  366. [ResourceExposure(ResourceScope.None)]
  367. internal static extern IntPtr
  368. GetCurrentProcess();
  369. [DllImport(ADVAPI32, SetLastError = true, EntryPoint = "OpenProcessToken")]
  370. [ResourceExposure(ResourceScope.None)]
  371. internal static extern bool
  372. GetCurrentProcessToken(
  373. [In]IntPtr ProcessHandle,
  374. [In]TokenAccessLevels DesiredAccess,
  375. [Out]out SafeCloseHandle TokenHandle);
  376. [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
  377. [return: MarshalAs(UnmanagedType.Interface)]
  378. [ResourceExposure(ResourceScope.None)]
  379. public static extern object CoCreateInstance(
  380. [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
  381. [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
  382. [In] CLSCTX dwClsContext,
  383. [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
  384. [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
  385. [return: MarshalAs(UnmanagedType.Interface)]
  386. [ResourceExposure(ResourceScope.None)]
  387. public static extern IStream CreateStreamOnHGlobal(
  388. [In] SafeHGlobalHandle hGlobal,
  389. [In, MarshalAs(UnmanagedType.Bool)] bool fDeleteOnRelease);
  390. [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
  391. [ResourceExposure(ResourceScope.None)]
  392. public static extern SafeHGlobalHandle GetHGlobalFromStream(IStream stream);
  393. [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
  394. [return: MarshalAs(UnmanagedType.Interface)]
  395. [ResourceExposure(ResourceScope.None)]
  396. public static extern object CoGetObjectContext(
  397. [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
  398. [DllImport(COMSVCS, ExactSpelling = true, PreserveSig = false)]
  399. [return: MarshalAs(UnmanagedType.Interface)]
  400. [ResourceExposure(ResourceScope.None)]
  401. public static extern object CoCreateActivity(
  402. [In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknown,
  403. [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
  404. [DllImport(OLE32, ExactSpelling = true, PreserveSig = false)]
  405. [ResourceExposure(ResourceScope.None)]
  406. internal static extern IntPtr CoSwitchCallContext(IntPtr newSecurityObject);
  407. [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)]
  408. [ResourceExposure(ResourceScope.None)]
  409. internal static extern IntPtr GlobalLock(SafeHGlobalHandle hGlobal);
  410. [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)]
  411. [return: MarshalAs(UnmanagedType.Bool)]
  412. [ResourceExposure(ResourceScope.None)]
  413. internal static extern bool GlobalUnlock(SafeHGlobalHandle hGlobal);
  414. [DllImport(KERNEL32, ExactSpelling = true, PreserveSig = true)]
  415. [ResourceExposure(ResourceScope.None)]
  416. internal static extern IntPtr GlobalSize(SafeHGlobalHandle hGlobal);
  417. [DllImport(OLEAUT32,
  418. ExactSpelling = true,
  419. CharSet = CharSet.Unicode,
  420. PreserveSig = true)]
  421. [ResourceExposure(ResourceScope.None)]
  422. internal static extern int LoadRegTypeLib(ref Guid rguid, ushort major, ushort minor, int lcid,
  423. [MarshalAs(UnmanagedType.Interface)] out object typeLib);
  424. [DllImport(OLEAUT32,
  425. ExactSpelling = true,
  426. CharSet = CharSet.Unicode,
  427. PreserveSig = true)]
  428. [ResourceExposure(ResourceScope.None)]
  429. internal static extern int SafeArrayGetDim(IntPtr pSafeArray);
  430. [DllImport(OLEAUT32,
  431. ExactSpelling = true,
  432. CharSet = CharSet.Unicode,
  433. PreserveSig = true)]
  434. [ResourceExposure(ResourceScope.None)]
  435. internal static extern int SafeArrayGetElemsize(IntPtr pSafeArray);
  436. [DllImport(OLEAUT32,
  437. ExactSpelling = true,
  438. CharSet = CharSet.Unicode,
  439. PreserveSig = false)]
  440. [ResourceExposure(ResourceScope.None)]
  441. internal static extern int SafeArrayGetLBound(IntPtr pSafeArray, int cDims);
  442. [DllImport(OLEAUT32,
  443. ExactSpelling = true,
  444. CharSet = CharSet.Unicode,
  445. PreserveSig = false)]
  446. [ResourceExposure(ResourceScope.None)]
  447. internal static extern int SafeArrayGetUBound(IntPtr pSafeArray, int cDims);
  448. [DllImport(OLEAUT32,
  449. ExactSpelling = true,
  450. CharSet = CharSet.Unicode,
  451. PreserveSig = false)]
  452. [ResourceExposure(ResourceScope.None)]
  453. internal static extern IntPtr SafeArrayAccessData(IntPtr pSafeArray);
  454. [DllImport(OLEAUT32,
  455. ExactSpelling = true,
  456. CharSet = CharSet.Unicode,
  457. PreserveSig = false)]
  458. [ResourceExposure(ResourceScope.None)]
  459. internal static extern void SafeArrayUnaccessData(IntPtr pSafeArray);
  460. [DllImport(SECUR32, CharSet = CharSet.Unicode, SetLastError = true)]
  461. [return: MarshalAs(UnmanagedType.U1)]
  462. [ResourceExposure(ResourceScope.None)]
  463. internal static extern bool TranslateName(string input, EXTENDED_NAME_FORMAT inputFormat, EXTENDED_NAME_FORMAT outputFormat, StringBuilder outputString, out uint size);
  464. [DllImport(NETAPI32, ExactSpelling = true, EntryPoint = "DsGetDcNameW", CharSet = CharSet.Unicode, SetLastError = true)]
  465. [ResourceExposure(ResourceScope.None)]
  466. internal static extern int DsGetDcName(
  467. [In] string computerName,
  468. [In] string domainName,
  469. [In] IntPtr domainGuid,
  470. [In] string siteName,
  471. [In] uint flags,
  472. [Out] out IntPtr domainControllerInfo);
  473. [DllImport(NETAPI32)]
  474. [ResourceExposure(ResourceScope.None)]
  475. internal static extern int NetApiBufferFree([In] IntPtr buffer);
  476. }
  477. internal static class InterfaceHelper
  478. {
  479. // only use this helper to get interfaces that are guaranteed to be supported
  480. internal static IntPtr GetInterfacePtrForObject(Guid iid, object obj)
  481. {
  482. IntPtr pUnk = Marshal.GetIUnknownForObject(obj);
  483. if (IntPtr.Zero == pUnk)
  484. {
  485. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.UnableToRetrievepUnk)));
  486. }
  487. IntPtr ppv = IntPtr.Zero;
  488. int hr = Marshal.QueryInterface(pUnk, ref iid, out ppv);
  489. Marshal.Release(pUnk);
  490. if (hr != HR.S_OK)
  491. {
  492. throw Fx.AssertAndThrow("QueryInterface should succeed");
  493. }
  494. return ppv;
  495. }
  496. }
  497. internal class RegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
  498. {
  499. internal static readonly RegistryHandle HKEY_CLASSES_ROOT = new RegistryHandle(new IntPtr(unchecked((int)0x80000000)), false);
  500. internal static readonly RegistryHandle HKEY_CURRENT_USER = new RegistryHandle(new IntPtr(unchecked((int)0x80000001)), false);
  501. internal static readonly RegistryHandle HKEY_LOCAL_MACHINE = new RegistryHandle(new IntPtr(unchecked((int)0x80000002)), false);
  502. internal static readonly RegistryHandle HKEY_USERS = new RegistryHandle(new IntPtr(unchecked((int)0x80000003)), false);
  503. internal static readonly RegistryHandle HKEY_PERFORMANCE_DATA = new RegistryHandle(new IntPtr(unchecked((int)0x80000004)), false);
  504. internal static readonly RegistryHandle HKEY_CURRENT_CONFIG = new RegistryHandle(new IntPtr(unchecked((int)0x80000005)), false);
  505. internal static readonly RegistryHandle HKEY_DYN_DATA = new RegistryHandle(new IntPtr(unchecked((int)0x80000006)), false);
  506. [ResourceConsumption(ResourceScope.Machine)]
  507. static RegistryHandle GetHKCR()
  508. {
  509. RegistryHandle regHandle = null;
  510. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ, out regHandle);
  511. if (status != SafeNativeMethods.ERROR_SUCCESS)
  512. {
  513. Utility.CloseInvalidOutSafeHandle(regHandle);
  514. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  515. }
  516. if (null == regHandle || regHandle.IsInvalid)
  517. {
  518. Fx.Assert("GetHKCR: RegOpenKeyEx returned null but with an invalid handle.");
  519. Utility.CloseInvalidOutSafeHandle(regHandle);
  520. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  521. }
  522. return regHandle;
  523. }
  524. [ResourceConsumption(ResourceScope.Machine)]
  525. static RegistryHandle Get64bitHKCR()
  526. {
  527. RegistryHandle regHandle = null;
  528. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY, out regHandle);
  529. if (status != SafeNativeMethods.ERROR_SUCCESS)
  530. {
  531. Utility.CloseInvalidOutSafeHandle(regHandle);
  532. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  533. }
  534. if (null == regHandle || regHandle.IsInvalid)
  535. {
  536. Fx.Assert("Get64bitHKCR: RegOpenKeyEx returned null but with an invalid handle.");
  537. Utility.CloseInvalidOutSafeHandle(regHandle);
  538. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  539. }
  540. return regHandle;
  541. }
  542. [ResourceConsumption(ResourceScope.Machine)]
  543. static RegistryHandle Get32bitHKCR()
  544. {
  545. RegistryHandle regHandle = null;
  546. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, @"Software\Classes", 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_32KEY, out regHandle);
  547. if (status != SafeNativeMethods.ERROR_SUCCESS)
  548. {
  549. Utility.CloseInvalidOutSafeHandle(regHandle);
  550. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  551. }
  552. if (null == regHandle || regHandle.IsInvalid)
  553. {
  554. Fx.Assert("Get64bitHKCR: RegOpenKeyEx returned null but with an invalid handle.");
  555. Utility.CloseInvalidOutSafeHandle(regHandle);
  556. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  557. }
  558. return regHandle;
  559. }
  560. static RegistryHandle GetCorrectBitnessHive(bool is64bit)
  561. {
  562. if (is64bit && IntPtr.Size == 8) // No worries we are trying to open up a 64 bit hive just return
  563. return GetHKCR();
  564. else if (is64bit && IntPtr.Size == 4) // we are running under wow get the 64 bit hive
  565. return Get64bitHKCR();
  566. else if (!is64bit && IntPtr.Size == 8) // we are running in 64 bit but need to open a 32 bit hive
  567. return Get32bitHKCR();
  568. else if (!is64bit && IntPtr.Size == 4)
  569. return GetHKCR();
  570. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_NOT_SUPPORTED));
  571. }
  572. public static RegistryHandle GetBitnessHKCR(bool is64bit)
  573. {
  574. return GetCorrectBitnessHive(is64bit);
  575. }
  576. public static RegistryHandle GetCorrectBitnessHKLMSubkey(bool is64bit, string key)
  577. {
  578. if (is64bit && IntPtr.Size == 8) // No worries we are trying to open up a 64 bit hive just return
  579. return GetHKLMSubkey(key);
  580. else if (is64bit && IntPtr.Size == 4) // we are running under wow get the 64 bit hive
  581. return Get64bitHKLMSubkey(key);
  582. else if (!is64bit && IntPtr.Size == 8) // we are running in 64 bit but need to open a 32 bit hive
  583. return Get32bitHKLMSubkey(key);
  584. else if (!is64bit && IntPtr.Size == 4)
  585. return GetHKLMSubkey(key);
  586. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_NOT_SUPPORTED));
  587. }
  588. [ResourceConsumption(ResourceScope.Machine)]
  589. static RegistryHandle GetHKLMSubkey(string key)
  590. {
  591. RegistryHandle regHandle = null;
  592. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ, out regHandle);
  593. if (status != SafeNativeMethods.ERROR_SUCCESS)
  594. {
  595. Utility.CloseInvalidOutSafeHandle(regHandle);
  596. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  597. }
  598. if (null == regHandle || regHandle.IsInvalid)
  599. {
  600. Fx.Assert("GetHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle.");
  601. Utility.CloseInvalidOutSafeHandle(regHandle);
  602. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  603. }
  604. return regHandle;
  605. }
  606. [ResourceConsumption(ResourceScope.Machine)]
  607. static RegistryHandle Get64bitHKLMSubkey(string key)
  608. {
  609. RegistryHandle regHandle = null;
  610. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY, out regHandle);
  611. if (status != SafeNativeMethods.ERROR_SUCCESS)
  612. {
  613. Utility.CloseInvalidOutSafeHandle(regHandle);
  614. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  615. }
  616. if (null == regHandle || regHandle.IsInvalid)
  617. {
  618. Fx.Assert("Get64bitHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle.");
  619. Utility.CloseInvalidOutSafeHandle(regHandle);
  620. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  621. }
  622. return regHandle;
  623. }
  624. [ResourceConsumption(ResourceScope.Machine)]
  625. static RegistryHandle Get32bitHKLMSubkey(string key)
  626. {
  627. RegistryHandle regHandle = null;
  628. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_32KEY, out regHandle);
  629. if (status != SafeNativeMethods.ERROR_SUCCESS)
  630. {
  631. Utility.CloseInvalidOutSafeHandle(regHandle);
  632. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  633. }
  634. if (null == regHandle || regHandle.IsInvalid)
  635. {
  636. Fx.Assert("Get32bitHKLMSubkey: RegOpenKeyEx returned null but with an invalid handle.");
  637. Utility.CloseInvalidOutSafeHandle(regHandle);
  638. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(SafeNativeMethods.ERROR_INVALID_HANDLE));
  639. }
  640. return regHandle;
  641. }
  642. [ResourceConsumption(ResourceScope.Machine)]
  643. internal static RegistryHandle GetNativeHKLMSubkey(string subKey, bool writeable)
  644. {
  645. RegistryHandle regHandle = null;
  646. int samDesired = SafeNativeMethods.KEY_READ | SafeNativeMethods.KEY_WOW64_64KEY;
  647. if (writeable)
  648. {
  649. samDesired |= SafeNativeMethods.KEY_WRITE;
  650. }
  651. int status = SafeNativeMethods.RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, samDesired, out regHandle);
  652. if (status != SafeNativeMethods.ERROR_SUCCESS || regHandle == null || regHandle.IsInvalid)
  653. {
  654. Utility.CloseInvalidOutSafeHandle(regHandle);
  655. return null;
  656. }
  657. return regHandle;
  658. }
  659. public RegistryHandle(IntPtr hKey, bool ownHandle)
  660. : base(ownHandle)
  661. {
  662. handle = hKey;
  663. }
  664. public RegistryHandle()
  665. : base(true)
  666. {
  667. }
  668. public bool DeleteKey(string key)
  669. {
  670. int status = SafeNativeMethods.RegDeleteKey(this, key);
  671. if (status == SafeNativeMethods.ERROR_SUCCESS)
  672. return true;
  673. else
  674. return false;
  675. }
  676. public void SetValue(string valName, string value)
  677. {
  678. int status = SafeNativeMethods.RegSetValueEx(this, valName, 0, SafeNativeMethods.REG_SZ, value, (value.Length * 2) + 2);
  679. if (status != SafeNativeMethods.ERROR_SUCCESS)
  680. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(status));
  681. }
  682. [ResourceConsumption(ResourceScope.Machine)]
  683. public RegistryHandle OpenSubKey(string subkey)
  684. {
  685. RegistryHandle regHandle = null;
  686. int status = SafeNativeMethods.RegOpenKeyEx(this, subkey, 0, SafeNativeMethods.KEY_READ, out regHandle);
  687. if (status != SafeNativeMethods.ERROR_SUCCESS || regHandle == null || regHandle.IsInvalid)
  688. {
  689. Utility.CloseInvalidOutSafeHandle(regHandle);
  690. return null;
  691. }
  692. return regHandle;
  693. }
  694. public string GetStringValue(string valName)
  695. {
  696. int type = 0;
  697. int datasize = 0;
  698. int ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])null, ref datasize);
  699. if (ret == SafeNativeMethods.ERROR_SUCCESS)
  700. if (type == SafeNativeMethods.REG_SZ)
  701. {
  702. byte[] blob = new byte[datasize];
  703. ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])blob, ref datasize);
  704. UnicodeEncoding unicode = new UnicodeEncoding();
  705. return unicode.GetString(blob);
  706. }
  707. return null;
  708. }
  709. public StringCollection GetSubKeyNames()
  710. {
  711. int ret = 0;
  712. int index = 0;
  713. StringCollection keyNames = new StringCollection();
  714. do
  715. {
  716. int lengthInChars = 0;
  717. ret = SafeNativeMethods.RegEnumKey(this, index, null, ref lengthInChars);
  718. if (ret == SafeNativeMethods.ERROR_MORE_DATA)
  719. {
  720. StringBuilder keyName = new StringBuilder(lengthInChars + 1);
  721. ret = SafeNativeMethods.RegEnumKey(this, index, keyName, ref lengthInChars);
  722. if (ret == SafeNativeMethods.ERROR_SUCCESS)
  723. keyNames.Add(keyName.ToString());
  724. }
  725. index++;
  726. }
  727. while (ret == SafeNativeMethods.ERROR_SUCCESS);
  728. return keyNames;
  729. }
  730. [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
  731. internal unsafe object GetValue(string valName)
  732. {
  733. object retVal = null;
  734. int type = 0;
  735. int datasize = 0;
  736. int ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])null, ref datasize);
  737. if (SafeNativeMethods.ERROR_SUCCESS == ret)
  738. {
  739. byte[] blob = new byte[datasize];
  740. ret = SafeNativeMethods.RegQueryValueEx(this, valName, null, ref type, (byte[])blob, ref datasize);
  741. if (SafeNativeMethods.ERROR_SUCCESS == ret)
  742. {
  743. UnicodeEncoding unicode = new UnicodeEncoding();
  744. string stringVal = unicode.GetString(blob);
  745. switch (type)
  746. {
  747. case (SafeNativeMethods.REG_BINARY):
  748. retVal = blob;
  749. break;
  750. case (SafeNativeMethods.REG_DWORD):
  751. fixed (byte* pBuffer = blob)
  752. {
  753. retVal = Marshal.ReadInt32((IntPtr)pBuffer);
  754. }
  755. break;
  756. case (SafeNativeMethods.REG_MULTI_SZ):
  757. retVal = stringVal.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
  758. break;
  759. case (SafeNativeMethods.REG_QWORD):
  760. fixed (byte* pBuffer = blob)
  761. {
  762. retVal = Marshal.ReadInt64((IntPtr)pBuffer);
  763. }
  764. break;
  765. case (SafeNativeMethods.REG_EXPAND_SZ):
  766. case (SafeNativeMethods.REG_SZ):
  767. retVal = stringVal.Trim(new char[] { '\0' });
  768. break;
  769. default:
  770. retVal = blob;
  771. break;
  772. }
  773. }
  774. }
  775. return retVal;
  776. }
  777. protected override bool ReleaseHandle()
  778. {
  779. if (SafeNativeMethods.RegCloseKey(handle) == SafeNativeMethods.ERROR_SUCCESS)
  780. return true;
  781. else
  782. return false;
  783. }
  784. }
  785. }