WinAPI equivalent of Win32_ComputerSystem.Domain - c#

My app is running on a computer that is joined to an Active Directory domain. Is there a way to get that domain's DNS name using WinAPI methods? I want something that will work even if there are no DNS servers or Domain Controllers available.
Right now, the only way I can find is through the Domain property of the Win32_ComputerSystem WMI class:
using System.Management;
public class WMIUtility
{
public static ManagementScope GetDefaultScope(string computerName)
{
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Authentication = AuthenticationLevel.PacketPrivacy;
connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
string path = string.Format("\\\\{0}\\root\\cimv2", computerName);
return new ManagementScope(path, connectionOptions);
}
public static ManagementObject GetComputerSystem(string computerName)
{
string path = string.Format("Win32_ComputerSystem.Name='{0}'", computerName);
return new ManagementObject(
GetDefaultScope(computerName),
new ManagementPath(path),
new ObjectGetOptions()
);
}
public static string GetDNSDomainName(string computerName)
{
using (ManagementObject computerSystem = GetComputerSystem(computerName))
{
object isInDomain = computerSystem.Properties["PartOfDomain"].Value;
if (isInDomain == null) return null;
if(!(bool)isInDomain) return null;
return computerSystem.Properties["Domain"].Value.ToString();
}
}
}
The only thing I can find in WinAPI is the NetGetJoinInformation method, which returns the NetBIOS domain name:
using System.Runtime.InteropServices;
public class PInvoke
{
public const int NERR_SUCCESS = 0;
public enum NETSETUP_JOIN_STATUS
{
NetSetupUnknownStatus = 0,
NetSetupUnjoined,
NetSetupWorkgroupName,
NetSetupDomainName
}
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
protected static extern int NetGetJoinInformation(string lpServer, out IntPtr lpNameBuffer, out NETSETUP_JOIN_STATUS BufferType);
[DllImport("netapi32.dll", SetLastError = true)]
protected static extern int NetApiBufferFree(IntPtr Buffer);
public static NETSETUP_JOIN_STATUS GetComputerJoinInfo(string computerName, out string name)
{
IntPtr pBuffer;
NETSETUP_JOIN_STATUS type;
int lastError = NetGetJoinInformation(computerName, out pBuffer, out type);
if(lastError != NERR_SUCCESS)
{
throw new System.ComponentModel.Win32Exception(lastError);
}
try
{
if(pBuffer == IntPtr.Zero)
{
name = null;
}
else
{
switch(type)
{
case NETSETUP_JOIN_STATUS.NetSetupUnknownStatus:
case NETSETUP_JOIN_STATUS.NetSetupUnjoined:
{
name = null;
break;
}
default:
{
name = Marshal.PtrToStringUni(pBuffer);
break;
}
}
}
return type;
}
finally
{
if(pBuffer != IntPtr.Zero)
{
NetApiBufferFree(pBuffer);
}
}
}
}

I think what you are looking for is GetComputerNameEx with ComputerNameDnsDomain as first parameter. But it's possible that you want one of the other types there. Still, GetComputerNameEx is the function you are looking for from how I understand the question.
PInvoke details here.
You raise a fair point in your comment, so sure, in this case LsaQueryInformationPolicy with PolicyDnsDomainInformation may be the better way to get the DNS name of the domain of which the computer is a member.
But it is a special case and your question didn't mention any such special cases. This should only ever be the case when the primary DNS suffix has been set and differs from the DNS domain name of which the machine is a member. For all practical purposes GetComputerNameEx will do exactly what you want.

Related

Force close an open network file on Windows Server 2012 with C#

Is there any way to force closed any instance of a specific file on Server 2012?
For arguments sake, call the link to the file D:\Shares\Shared\Sharedfile.exe
I have C# code which copies the latest version of a program into this directory, which often has people using the program during the day. Closing open file handles and replacing the file has worked well, because it just means next time the user opens the program they have all the latest changes.
However it gets a little monotonous doing this from computer management on the server, so I was wondering if there was a way to do it from C# code?
I tried this but it doesn't have the right overloads that I need. Perhaps is there something in the File class I could use?
EDIT The C# code to close the file will NOT be running on the host server.
[DllImport("Netapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
public static extern int NetFileClose(string servername, int id);
You can wrap the NetFileClose API, which also requires wrapping the NetFileEnum API. Something like this:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct FILE_INFO_3 {
public int fi3_id;
public int fi3_permissions;
public int fi3_num_locks;
public string fi3_pathname;
public string fi3_username;
}
static class NativeMethods {
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public extern static int NetFileEnum(
string servername,
string basepath,
string username,
int level,
out IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
ref IntPtr resume_handle
);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public extern static int NetFileClose(string servername, int fileid);
[DllImport("netapi32.dll")]
public extern static int NetApiBufferFree(IntPtr buffer);
}
Pretty ugly signatures, right? Let's wrap a little managed love around it.
class RemoteFile {
public RemoteFile(string serverName, int id, string path, string userName) {
ServerName = serverName;
Id = id;
Path = path;
UserName = userName;
}
public string ServerName { get; }
public int Id { get; }
public string Path { get; }
public string UserName { get; }
public void Close() {
int result = NativeMethods.NetFileClose(ServerName, Id);
if (result != 0) {
// handle error decently, omitted for laziness
throw new Exception($"Error: {result}");
}
}
}
IEnumerable<RemoteFile> EnumRemoteFiles(string serverName, string basePath = null) {
int entriesRead;
int totalEntries;
IntPtr resumeHandle = IntPtr.Zero;
IntPtr fileEntriesPtr = IntPtr.Zero;
try {
int result = NativeMethods.NetFileEnum(
servername: serverName,
basepath: basePath,
username: null,
level: 3,
bufptr: out fileEntriesPtr,
prefmaxlen: -1,
entriesread: out entriesRead,
totalentries: out totalEntries,
resume_handle: ref resumeHandle
);
if (result != 0) {
// handle error decently, omitted for laziness
throw new Exception($"Error: {result}");
}
for (int i = 0; i != entriesRead; ++i) {
FILE_INFO_3 fileInfo = (FILE_INFO_3) Marshal.PtrToStructure(
fileEntriesPtr + i * Marshal.SizeOf(typeof(FILE_INFO_3)),
typeof(FILE_INFO_3)
);
yield return new RemoteFile(
serverName,
fileInfo.fi3_id,
fileInfo.fi3_pathname,
fileInfo.fi3_username
);
}
} finally {
if (fileEntriesPtr != IntPtr.Zero) {
NativeMethods.NetApiBufferFree(fileEntriesPtr);
}
}
}
And now closing a particular file is easy: close all open instances of it.
foreach (var file in EnumRemoteFiles(server, path)) {
Console.WriteLine($"Closing {file.Path} at {file.ServerName} (opened by {file.UserName})");
file.Close();
}
Please note that this code is not quite production ready, in particular, the error handling sucks. Also, in my tests, it appears file paths can be subject to some mangling, depending on exactly how they're opened (like a file appearing as C:\\Path\File, with an extra backslash after the drive root) so you may want to do normalization before validating the name. Still, this covers the ground.

Why might this user impersonation code fail to grant me permission?

I have an application that is meant to mirror files from one location to another. In one segment of this program ( likely the most important ) the application opens impersonation contexts for both the source and destination; assuming that credentials have been provided. Once these contexts have been opened, the program executes the actual mirroring of files from one location to another, and then closes the aforementioned contexts.
It looks something like this:
protected virtual void MirrorChanges()
{
if (this.Source == null)
throw new InvalidOperationException();
else if (!this.Source.Exists)
throw new InvalidOperationException();
else
{
if( this.SourceImpersonator != null )
if(!this.SourceImpersonator.Open())
{
throw new Exception("FolderMirror cannot impersonate Source user. Please review the associated credentials.");
}
if( this.DestinationImpersonator != null )
if(!this.DestinationImpersonator.Open())
{
throw new Exception("FolderMirror cannot impersonate Destination user. Please review the associated credentials.");
}
this.MirrorChanges(this.Source);
if( this.DestinationImpersonator != null )
this.DestinationImpersonator.Close();
if( this.SourceImpersonator != null )
this.SourceImpersonator.Close();
return;
}
}
Now; the question you're all begging - what's in the 'Open' and 'Close' methods of these supposed 'impersonators'? Much of this was taken from some other examples found about the internet, but here we go:
public class UserImpersonator
{
public Boolean Open()
{
// Actively researching why the 'DuplicateToken' method is necessary in this method - like
// I said earlier, much of this is sourced from examples. I did some research and do note that
// there is a 'SECURITY_IMPERSONATION_LEVEL' variable in this method; but that strikes me as
// rather perplexing if this method's action is to simply 'duplicate a token' - but I'm off to
//the manual for reviewing that information.
if (!LogonUser(this.Username, this.Domain, this.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref this.PrimaryToken))
{
RaiseLastError();
return false;
}
else if (!DuplicateToken(this.PrimaryToken, 2, ref this.MutatedToken))
{
RaiseLastError();
return false;
}
else
{
try
{
this._TargetIdentity = new WindowsIdentity(this.MutatedToken);
this._ImpersonationContext = this._TargetIdentity.Impersonate();
return true;
}
catch (Exception e)
{
return false;
}
}
}
public void Close()
{
if( this._ImpersonationContext != null )
this._ImpersonationContext.Undo();
if( this.PrimaryToken != null )
if (!CloseHandle(this.PrimaryToken))
RaiseLastError();
}
// With some of this action, actually toward the top of the file...
DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);
}
Now - there are clearly some things I could tighten up, but to get to the root of the issue here - In a situation where I provide a known valid username, password, and domain - I am denied access to actually replace the file in the destination.
[Edit] I've now ( as any sane programmer would )( edits applied above ) wrapped conditionals around the 'Impersonator.Open' clauses to ensure that they sort out - with true evaluations. After stepping through execution of the 'Open' method I'm coming up with successes all the way through.
[Edit] It's probably valuable to mention that I've taken these open and close methods and placed them in an 'Execute' method that takes a Delegate as a parameter. At the time it seemed more appropriate than the current implementation; but after writing an extra thousand lines or so and still getting the same result ( most of which was for actually negotiating the files while int he context of the execute method ); I gave up and haven't come back to it. Here's that tidbit, in-case someone is interested.
public class UserImpersonator()
{
public Object Execute(System.Delegate Method)
{
if (Method == null)
throw new InvalidOperationException("Impersonator fixed-method already provided. Cannot implement another method on this impersonator." );
else if (!this.Open())
return null;
else
{
try
{
this._Executing = true;
Object ReturnValue = Method.DynamicInvoke();
this.Close();
this._Executing = false;
return ReturnValue;
}
catch (Exception e)
{
return null;
}
}
}
}
[Add] I should also mention that on my local system ( have yet to test in the deployment [server] environment ), if I provide totally invalid credentials, I still get access to both read and write. I presume that this means that I retain credentials that have already been opened - but if that's the case my [uneducated] assumption that 'stacking impersonation won't work' really falls apart.
I've taken quite a few passes at this to no avail; so if anyone has any suggestions or questions I am all ears.
Sometimes trial and error prevails.
The adjustment that is required to correct this issue is a modification of the LogonType, and LogonProvider variables in the LogonUser method. In this particular instance, the valid ( seemingly only working ) uses are with the LOGON32_PROVIDER_DEFAULT and LOGON32_LOGON_INTERACTIVE constants.
I personally do not know why[, but would be very interested in some greater detail than that found here].
After some general trial and error, for my application, the corrected code follows. I hope that this can serve as an [early revision of an] authoritative reference for the community; as most of the implementations are ... less than thorough.
Before the code dump, it would be remiss of me to not note the potential implementations of this code.
1. Create a new UserImpersonator using the UserImpersonator(String Username,String Password,String Domain,System.Delegate Method) constructor to define the credentials, and the method to be invoked; and then 'Execute' the UserImpersonator using either of the overloaded Execute methods that do not require a delegate. By nature, these methods refer directly to the method that was stored at construction, or set at a later time.
2. Create a new UserImpersonator using the UserImpersonator(String Username, String Password, String Domain) constructor, and perform one of a few actions:
1. Set the UserImpersonator's Method and Execute it at a later time.
2. Run an Execute overload that requires a delegate parameter on the UserImpersonator, and provide a delegate method for the impersonator to execute.
3. Execute the 'UserImpersonator.Open' method to open the user context, execute your user-specific code, and then execute the 'UserImpersonator.Close' method to finalize the operation.
Here we go though:
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Security.Principal;
using System.Linq;
using System.Text;
namespace TopSekrit.Credentials
{
public class UserImpersonator : IDisposable
{
#region Delegates
// Port from generic event handler
public delegate void SimpleEventDelegate(SimpleEventArgument Argument);
#endregion
#region Supporting Classes
// Port from generic event handler
public class SimpleEventArgument
{
public Object Source = null;
public Object Message = null;
public SimpleEventArgument(Object Source, String Message)
{
this.Source = Source;
this.Message = Message;
}
}
#endregion
#region Imports
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr existingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr duplicateTokenHandle);
#endregion
#region Constants
// Logon Types as defined in Winbase.h
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNKNOWN = 6;
const int LOGON32_LOGON_UNLOCK = 7;
const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// Logon Providers as defined in Winbase.h
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT35 = 1;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT50 = 3;
#endregion
#region Events
public event SimpleEventDelegate OnImpersonationReset = null;
public event SimpleEventDelegate OnImpersonationOpened = null;
public event SimpleEventDelegate OnImpersonationClosed = null;
public event SimpleEventDelegate OnImpersonatedExecutionStarted = null;
public event SimpleEventDelegate OnImpersonatedExecutionFinished = null;
#endregion
#region Properties
protected String _Username = String.Empty;
public String Username
{
get
{
return this._Username;
}
set
{
if (this.IsExecuting)
throw new InvalidOperationException("Cannot set Username on UserImpersonator while impersonation is executing.");
else if (this.IsOpen)
throw new InvalidOperationException("Cannot set Username on UserImpersonator while impersonation context is open.");
else
{
this._Username = value;
this.ResetImpersonation();
}
}
}
protected String _Password = String.Empty;
public String Password
{
get
{
return this._Password;
}
set
{
if (this.IsExecuting)
throw new InvalidOperationException("Cannot set Password on UserImpersonator while impersonation is executing.");
else if (this.IsOpen)
throw new InvalidOperationException("Cannot set Password on UserImpersonator while impersonation context is open.");
else
{
this._Password = value;
this.ResetImpersonation();
}
}
}
protected String _Domain = String.Empty;
public String Domain
{
get
{
return this._Domain;
}
set
{
if (this.IsExecuting)
throw new InvalidOperationException("Cannot set Domain on UserImpersonator while impersonation is executing.");
else if (this.IsOpen)
throw new InvalidOperationException("Cannot set Domain on UserImpersonator while impersonation context is open.");
else
{
this._Domain = value;
this.ResetImpersonation();
}
}
}
protected System.Delegate _Method = null;
public System.Delegate Method
{
get
{
return this._Method;
}
set
{
this._Method = value;
}
}
protected IntPtr PrimaryToken = IntPtr.Zero;
protected IntPtr MutatedToken = IntPtr.Zero;
protected WindowsIdentity _TargetIdentity = null;
public WindowsIdentity TargetIdentity
{
get
{
return this._TargetIdentity;
}
}
protected WindowsImpersonationContext _ImpersonationContext = null;
public WindowsImpersonationContext ImpersonationContext
{
get
{
return this._ImpersonationContext;
}
}
protected Boolean _IsExecuting = false;
public Boolean IsExecuting
{
get
{
return this._IsExecuting;
}
}
public Boolean IsOpen
{
get
{
if (this.PrimaryToken != null)
return true;
else if (this.MutatedToken != null)
return true;
else if (this.TargetIdentity != null)
return true;
else if (this.ImpersonationContext != null)
return true;
else
return false;
}
}
protected int _LogonType = LOGON32_LOGON_INTERACTIVE;
public int LogonType
{
get
{
return this._LogonType;
}
set
{
if (this.IsExecuting)
throw new InvalidOperationException("Cannot set LogonType on UserImpersonator while impersonation is executing.");
else if (this.IsOpen)
throw new InvalidOperationException("Cannot set LogonType on UserImpersonator while impersonation context is open.");
else
{
this._LogonType = value;
this.ResetImpersonation();
}
}
}
protected int _LogonProvider = LOGON32_PROVIDER_DEFAULT;
public int LogonProvider
{
get
{
return this._LogonProvider;
}
set
{
if (this.IsExecuting)
throw new InvalidOperationException("Cannot set LogonProvider on UserImpersonator while impersonation is executing.");
else if (this.IsOpen)
throw new InvalidOperationException("Cannot set LogonProvider on UserImpersonator while impersonation context is open.");
else
{
this._LogonProvider = value;
this.ResetImpersonation();
}
}
}
#endregion
#region Constructors
public UserImpersonator(String Username,String Password,String Domain,System.Delegate Method,int LogonType,int LogonProvider)
{
if (String.IsNullOrEmpty(Username))
throw new ArgumentNullException();
else
{
this._Username = Username;
this._Password = Password;
this._Domain = Domain;
this._Method = Method;
this._LogonType = LogonType;
this._LogonProvider = LogonProvider;
return;
}
}
public UserImpersonator(String Username, String Password, String Domain, System.Delegate Method, int LogonType)
: this(Username, Password, Domain, Method, LogonType, LOGON32_PROVIDER_DEFAULT)
{
}
public UserImpersonator(String Username, String Password, String Domain, System.Delegate Method)
: this(Username,Password,Domain,Method,LOGON32_LOGON_INTERACTIVE)
{
}
public UserImpersonator(String Username, String Password, String Domain)
:this( Username, Password, Domain, null)
{
}
public UserImpersonator(String Username, String Password)
: this(Username, Password,String.Empty)
{
}
public UserImpersonator(String Username)
: this(Username, String.Empty)
{
}
#endregion
#region Impersonated Execution
public virtual Object Execute()
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot Execute while another execution is already in progress.");
else if (this.Method == null)
throw new InvalidOperationException("UserImpersonator cannot Execute without a supplied, or stored Method to invoke.");
else if (!this.Open())
throw new InvalidOperationException("Could not open security context.");
else
{
try
{
this._IsExecuting = true;
Object ReturnValue = this.Method.DynamicInvoke();
this.Close();
this._IsExecuting = false;
return ReturnValue;
}
catch (Exception e)
{
return null;
}
}
}
public virtual Object Execute(params object[] Arguments)
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot Execute while another execution is already in progress.");
else if (this.Method == null)
throw new InvalidOperationException("UserImpersonator cannot Execute without a supplied, or stored Method to invoke.");
else if (!this.Open())
throw new InvalidOperationException("Could not open security context.");
else
{
try
{
this._IsExecuting = true;
Object ReturnValue = this.Method.DynamicInvoke(Arguments);
this.Close();
this._IsExecuting = false;
return ReturnValue;
}
catch (Exception e)
{
return null;
}
}
}
public virtual Object Execute(System.Delegate Method)
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot Execute while another execution is already in progress.");
else if (Method == null)
throw new InvalidOperationException("UserImpersonator cannot Execute without a supplied, or stored Method to invoke.");
else if (!this.Open())
throw new InvalidOperationException("Could not open security context.");
else
{
try
{
this._IsExecuting = true;
Object ReturnValue = Method.DynamicInvoke();
this.Close();
this._IsExecuting = false;
return ReturnValue;
}
catch (Exception e)
{
return null;
}
}
}
public virtual Object Execute(System.Delegate Method, params object[] Arguments)
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot Execute while another execution is already in progress.");
else if (Method == null)
throw new InvalidOperationException("UserImpersonator cannot Execute without a supplied, or stored Method to invoke.");
else if (!this.Open())
throw new InvalidOperationException("Could not open security context.");
else
{
try
{
this._IsExecuting = true;
Object ReturnValue = Method.DynamicInvoke(Arguments);
this.Close();
this._IsExecuting = false;
return ReturnValue;
}
catch (Exception e)
{
return null;
}
}
}
#endregion
#region Impersonation / Depersonation
public virtual Boolean Open()
{
if (this.IsOpen)
{
if( this.IsExecuting )
throw new InvalidOperationException("UserImpersonator cannot Open user context while a user context is already open and executing.");
else
{
this.Close();
return this.Open();
}
}
else if (!LogonUser(this.Username, this.Domain, this.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref this.PrimaryToken))
throw this.GetLastException();
else if (!DuplicateToken(this.PrimaryToken, 2, ref this.MutatedToken))
throw this.GetLastException();
else
{
try
{
this._TargetIdentity = new WindowsIdentity(this.MutatedToken);
}
catch (Exception e)
{
throw new Exception("UserImpersonator could not Open user context. An exception was encountered while creating the WindowsIdentity.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
try
{
this._ImpersonationContext = this._TargetIdentity.Impersonate();
}
catch (Exception e)
{
throw new Exception("UserImpersonator could not Open user context. An exception was encountered while creating the WindowsImpersonationContext.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
this.FireImpersonationOpened();
}
}
return true;
}
}
public virtual void Close()
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot Close impersonation context while in execution.");
else
{
try
{
if (this._TargetIdentity != null)
{
this._TargetIdentity.Dispose();
this._TargetIdentity = null;
}
}
catch (Exception e)
{
throw new Exception("Exception encountered while disposing TargetIdentity on UserImpersonator.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
try
{
if (this._ImpersonationContext != null)
{
this._ImpersonationContext.Undo();
this._ImpersonationContext.Dispose();
this._ImpersonationContext = null;
}
}
catch (Exception e)
{
throw new Exception("Exception encountered while undoing or disposing ImpersonationContext on UserImpersonator.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
try
{
if (this.MutatedToken != null)
if (!CloseHandle(MutatedToken))
this.GetLastException();
}
catch (Exception e)
{
throw new Exception("Exception encountered while closing MutatedToken on UserImpersonator.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
try
{
if (this.PrimaryToken != null)
if (!CloseHandle(this.PrimaryToken))
this.GetLastException();
}
catch (Exception e)
{
throw new Exception("Exception encountered while closing PrimaryToken on UserImpersonator.\r\n" + e.Message + "\r\n" + e.StackTrace);
}
finally
{
this.FireImpersonationClosed();
}
}
}
}
return;
}
}
protected virtual void ResetImpersonation()
{
if (this.IsExecuting)
throw new InvalidOperationException("UserImpersonator cannot ResetImpersonation while impersonation is already executing.");
else if (this.IsOpen)
{
this.Close();
this.ResetImpersonation();
return;
}
else
{
this.Open();
this.FireImpersonationReset();
return;
}
}
#endregion
#region Error Handling
private Exception GetLastException()
{
return new ApplicationException(this.GetErrorMessage(Marshal.GetLastWin32Error()));
}
public unsafe string GetErrorMessage(int ErrorCode)
{
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
int messageSize = 255;
string lpMsgBuf = "";
int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
IntPtr ptrlpSource = IntPtr.Zero;
IntPtr ptrArguments = IntPtr.Zero;
int retVal = FormatMessage(dwFlags, ref ptrlpSource, ErrorCode, 0, ref lpMsgBuf, messageSize, &ptrArguments);
if (retVal == 0)
return string.Format("Failed to format message for error code '{0}'.", ErrorCode);
return lpMsgBuf;
}
#endregion
#region Disposability
public virtual void Dispose()
{
this.Close();
this._Username = null;
this._Password = null;
this._Domain = null;
this._Method = null;
return;
}
#endregion
#region Event Firing
protected virtual void FireImpersonationReset()
{
if (this.OnImpersonationReset != null)
this.OnImpersonationReset(new Events.SimpleArgument(this, "Impersonation context has been reset."));
return;
}
protected virtual void FireImpersonationOpened()
{
if (this.OnImpersonationOpened != null)
this.OnImpersonationOpened(new Events.SimpleArgument(this, "Impersonation context has been opened."));
return;
}
protected virtual void FireImpersonationClosed()
{
if (this.OnImpersonationClosed != null)
this.OnImpersonationClosed(new Events.SimpleArgument(this, "Impersonation context has been closed."));
return;
}
protected virtual void FireImpersonationExecutionStarted()
{
if (this.OnImpersonatedExecutionStarted != null )
this.OnImpersonatedExecutionStarted(new Events.SimpleArgument(this, "Impersonated execution has started."));
return;
}
protected virtual void FireImpersonationExecutionFinished()
{
if (this.OnImpersonatedExecutionFinished != null)
this.OnImpersonatedExecutionFinished(new Events.SimpleArgument(this, "Impersonated execution has finished."));
return;
}
#endregion
}
}
[Edit]: Updated 8/12/14 - Added LogonType and LogonProvider constructors. Open method overrides to follow at my first availability.
My feeling is that this is one of the more thorough implementations of windows user impersonation - I hope you all find some use in it. Questions or comments are welcome; as I am sure this has room for improvement still.

How to Programmatically Set GPO to Not Configured or Disabled

I'm looking for a programmatic solution that has the same effect as setting the "Configure Windows NTP Client" state in GPOE Administrative Templates > System > Windows Time Service > Time Providers > Configure Windows NTP Client to Not Configured or Disabled, but I'll take any help I can get at this point.
Is there a registry key I can modify using the .NET Registry class or a property I can modify using the RSoP WMI classes? I've been looking in both places for days, but haven't found anything that will effectively disable the GPO or have the same effect as disabling or setting it to Not Configured in the GUI.
Firstly you have to find the registry value to edit. They are all listed in the XLS document downloadable at http://www.microsoft.com/en-us/download/details.aspx?id=25250. This document does not indicate the type of the value (REGSZ, DWORD, etc), so you have to set the setting by using the editor and then look the type of the value with regedit.
Now you have the registry key, the value name and its type, let's add some C# and use the COM interface IGroupPolicyObject
[ComImport, Guid("EA502722-A23D-11d1-A7D3-0000F87571E3")]
internal class GPClass
{
}
[ComImport, Guid("EA502723-A23D-11d1-A7D3-0000F87571E3"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IGroupPolicyObject
{
uint New([MarshalAs(UnmanagedType.LPWStr)] string domainName, [MarshalAs(UnmanagedType.LPWStr)] string displayName, uint flags);
uint OpenDSGPO([MarshalAs(UnmanagedType.LPWStr)] string path, uint flags);
uint OpenLocalMachineGPO(uint flags);
uint OpenRemoteMachineGPO([MarshalAs(UnmanagedType.LPWStr)] string computerName, uint flags);
uint Save([MarshalAs(UnmanagedType.Bool)] bool machine, [MarshalAs(UnmanagedType.Bool)] bool add, [MarshalAs(UnmanagedType.LPStruct)] Guid extension, [MarshalAs(UnmanagedType.LPStruct)] Guid app);
uint Delete();
uint GetName([MarshalAs(UnmanagedType.LPWStr)] StringBuilder name, int maxLength);
uint GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] StringBuilder name, int maxLength);
uint SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name);
uint GetPath([MarshalAs(UnmanagedType.LPWStr)] StringBuilder path, int maxPath);
uint GetDSPath(uint section, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path, int maxPath);
uint GetFileSysPath(uint section, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path, int maxPath);
uint GetRegistryKey(uint section, out IntPtr key);
uint GetOptions(out uint options);
uint SetOptions(uint options, uint mask);
uint GetType(out IntPtr gpoType);
uint GetMachineName([MarshalAs(UnmanagedType.LPWStr)] StringBuilder name, int maxLength);
uint GetPropertySheetPages(out IntPtr pages);
}
public enum GroupPolicySection
{
Root = 0,
User = 1,
Machine = 2,
}
public abstract class GroupPolicyObject
{
protected const int MaxLength = 1024;
/// <summary>
/// The snap-in that processes .pol files
/// </summary>
private static readonly Guid RegistryExtension = new Guid(0x35378EAC, 0x683F, 0x11D2, 0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2);
/// <summary>
/// This application
/// </summary>
private static readonly Guid LocalGuid = new Guid(GetAssemblyAttribute<GuidAttribute>(Assembly.GetExecutingAssembly()).Value);
protected IGroupPolicyObject Instance = null;
static T GetAssemblyAttribute<T>(ICustomAttributeProvider assembly) where T : Attribute
{
object[] attributes = assembly.GetCustomAttributes(typeof(T), true);
if (attributes.Length == 0)
return null;
return (T)attributes[0];
}
internal GroupPolicyObject()
{
Instance = GetInstance();
}
public void Save()
{
var result = Instance.Save(true, true, RegistryExtension, LocalGuid);
if (result != 0)
{
throw new Exception("Error saving machine settings");
}
result = Instance.Save(false, true, RegistryExtension, LocalGuid);
if (result != 0)
{
throw new Exception("Error saving user settings");
}
}
public void Delete()
{
var result = Instance.Delete();
if (result != 0)
{
throw new Exception("Error deleting the GPO");
}
Instance = null;
}
public RegistryKey GetRootRegistryKey(GroupPolicySection section)
{
IntPtr key;
var result = Instance.GetRegistryKey((uint)section, out key);
if (result != 0)
{
throw new Exception(string.Format("Unable to get section '{0}'", Enum.GetName(typeof(GroupPolicySection), section)));
}
var handle = new SafeRegistryHandle(key, true);
return RegistryKey.FromHandle(handle, RegistryView.Default);
}
public abstract string GetPathTo(GroupPolicySection section);
protected static IGroupPolicyObject GetInstance()
{
var concrete = new GPClass();
return (IGroupPolicyObject)concrete;
}
}
public class GroupPolicyObjectSettings
{
public readonly bool LoadRegistryInformation;
public readonly bool Readonly;
public GroupPolicyObjectSettings(bool loadRegistryInfo = true, bool readOnly = false)
{
LoadRegistryInformation = loadRegistryInfo;
Readonly = readOnly;
}
private const uint RegistryFlag = 0x00000001;
private const uint ReadonlyFlag = 0x00000002;
internal uint Flag
{
get
{
uint flag = 0x00000000;
if (LoadRegistryInformation)
{
flag |= RegistryFlag;
}
if (Readonly)
{
flag |= ReadonlyFlag;
}
return flag;
}
}
}
public class ComputerGroupPolicyObject : GroupPolicyObject
{
public readonly bool IsLocal;
public ComputerGroupPolicyObject(GroupPolicyObjectSettings options = null)
{
options = options ?? new GroupPolicyObjectSettings();
var result = Instance.OpenLocalMachineGPO(options.Flag);
if (result != 0)
{
throw new Exception("Unable to open local machine GPO");
}
IsLocal = true;
}
public ComputerGroupPolicyObject(string computerName, GroupPolicyObjectSettings options = null)
{
options = options ?? new GroupPolicyObjectSettings();
var result = Instance.OpenRemoteMachineGPO(computerName, options.Flag);
if (result != 0)
{
throw new Exception(string.Format("Unable to open GPO on remote machine '{0}'", computerName));
}
IsLocal = false;
}
public static void SetPolicySetting(string registryInformation, string settingValue, RegistryValueKind registryValueKind)
{
string valueName;
GroupPolicySection section;
string key = Key(registryInformation, out valueName, out section);
// Thread must be STA
Exception exception = null;
var t = new Thread(() =>
{
try
{
var gpo = new ComputerGroupPolicyObject();
using (RegistryKey rootRegistryKey = gpo.GetRootRegistryKey(section))
{
// Data can't be null so we can use this value to indicate key must be delete
if (settingValue == null)
{
using (RegistryKey subKey = rootRegistryKey.OpenSubKey(key, true))
{
if (subKey != null)
{
subKey.DeleteValue(valueName);
}
}
}
else
{
using (RegistryKey subKey = rootRegistryKey.CreateSubKey(key))
{
subKey.SetValue(valueName, settingValue, registryValueKind);
}
}
}
gpo.Save();
}
catch (Exception ex)
{
exception = ex;
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
if (exception != null)
throw exception;
}
public static object GetPolicySetting(string registryInformation)
{
string valueName;
GroupPolicySection section;
string key = Key(registryInformation, out valueName, out section);
// Thread must be STA
object result = null;
var t = new Thread(() =>
{
var gpo = new ComputerGroupPolicyObject();
using (RegistryKey rootRegistryKey = gpo.GetRootRegistryKey(section))
{
// Data can't be null so we can use this value to indicate key must be delete
using (RegistryKey subKey = rootRegistryKey.OpenSubKey(key, true))
{
if (subKey == null)
{
result = null;
}
else
{
result = subKey.GetValue(valueName);
}
}
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
return result;
}
private static string Key(string registryInformation, out string value, out GroupPolicySection section)
{
// Parse parameter of format HKCU\Software\Policies\Microsoft\Windows\Personalization!NoChangingSoundScheme
string[] split = registryInformation.Split('!');
string key = split[0];
string hive = key.Substring(0, key.IndexOf('\\'));
key = key.Substring(key.IndexOf('\\') + 1);
value = split[1];
if (hive.Equals(#"HKLM", StringComparison.OrdinalIgnoreCase)
|| hive.Equals(#"HKEY_LOCAL_MACHINE", StringComparison.OrdinalIgnoreCase))
{
section = GroupPolicySection.Machine;
}
else
{
section = GroupPolicySection.User;
}
return key;
}
/// <summary>
/// Retrieves the file system path to the root of the specified GPO section.
/// The path is in UNC format.
/// </summary>
public override string GetPathTo(GroupPolicySection section)
{
var sb = new StringBuilder(MaxLength);
var result = Instance.GetFileSysPath((uint)section, sb, MaxLength);
if (result != 0)
{
throw new Exception(string.Format("Unable to retrieve path to section '{0}'", Enum.GetName(typeof(GroupPolicySection), section)));
}
return sb.ToString();
}
}
And how to use it:
static void Main(string[] args)
{
ComputerGroupPolicyObject.SetPolicySetting(#"HKLM\Software\Policies\Microsoft\Windows\HomeGroup!DisableHomeGroup", "0", RegistryValueKind.DWord);
ComputerGroupPolicyObject.SetPolicySetting(#"HKLM\Software\Policies\Microsoft\Windows\HomeGroup!DisableHomeGroup", "1", RegistryValueKind.DWord);
ComputerGroupPolicyObject.SetPolicySetting(#"HKLM\Software\Policies\Microsoft\Windows\HomeGroup!DisableHomeGroup", null, RegistryValueKind.Unknown);
}
Code inspired from https://bitbucket.org/MartinEden/local-policy

Way to determine framework version without Registry

I've searching a long time, but i couldn't find answer.
Is there any way to determine framework and service pack .NET installed on PC, without access to registry in C#?
I can use registry keys, but i have to do this without access to registry.
I read something about directories in C:\Windows\Microsoft .NET, but there, I only found framework version, nothing about SP. But I need framework and Service Pack.
Can somebody help me?
Regards, Greg
string clrVersion = System.Environment.Version.ToString();
string dotNetVersion = Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "mscorlib").First().Version.ToString();
you could use WMI to get a list of all the installed software filtering the result to achieve your goal
public static class MyClass
{
public static void Main()
{
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
foreach (ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
}
}
I think it's possible to ask the WMI.
Query for all Win32_Product elements and look for the Name Property contains "Microsoft .NET Framework"
ServicePack information is also provided by WMI.. But I don't know exactly where.
You can do this:
System.Environment.Version.ToString()
(CLR Version only)
or this
from MSDN blog on Updated sample .NET Framework detection code that does more in-depth checking
or this
No registry access. Borrowed from this blog.
using System;
using System.IO;
using System.Security;
using System.Text.RegularExpressions;
namespace YourNameSpace
{
public class SystemInfo
{
private const string FRAMEWORK_PATH = "\\Microsoft.NET\\Framework";
private const string WINDIR1 = "windir";
private const string WINDIR2 = "SystemRoot";
public static string FrameworkVersion
{
get
{
try
{
return getHighestVersion(NetFrameworkInstallationPath);
}
catch (SecurityException)
{
return "Unknown";
}
}
}
private static string getHighestVersion(string installationPath)
{
string[] versions = Directory.GetDirectories(installationPath, "v*");
string version = "Unknown";
for (int i = versions.Length - 1; i >= 0; i--)
{
version = extractVersion(versions[i]);
if (isNumber(version))
return version;
}
return version;
}
private static string extractVersion(string directory)
{
int startIndex = directory.LastIndexOf("\\") + 2;
return directory.Substring(startIndex, directory.Length - startIndex);
}
private static bool isNumber(string str)
{
return new Regex(#"^[0-9]+\.?[0-9]*$").IsMatch(str);
}
public static string NetFrameworkInstallationPath
{
get { return WindowsPath + FRAMEWORK_PATH; }
}
public static string WindowsPath
{
get
{
string winDir = Environment.GetEnvironmentVariable(WINDIR1);
if (String.IsNullOrEmpty(winDir))
winDir = Environment.GetEnvironmentVariable(WINDIR2);
return winDir;
}
}
}
}
Here is an improved example that includes service packs,
string path = System.Environment.SystemDirectory;
path = path.Substring( 0, path.LastIndexOf('\\') );
path = Path.Combine( path, "Microsoft.NET" );
// C:\WINDOWS\Microsoft.NET\
string[] versions = new string[]{
"Framework\\v1.0.3705",
"Framework64\\v1.0.3705",
"Framework\\v1.1.4322",
"Framework64\\v1.1.4322",
"Framework\\v2.0.50727",
"Framework64\\v2.0.50727",
"Framework\\v3.0",
"Framework64\\v3.0",
"Framework\\v3.5",
"Framework64\\v3.5",
"Framework\\v3.5\\Microsoft .NET Framework 3.5 SP1",
"Framework64\\v3.5\\Microsoft .NET Framework 3.5 SP1",
"Framework\\v4.0",
"Framework64\\v4.0"
};
foreach( string version in versions )
{
string versionPath = Path.Combine( path, version );
DirectoryInfo dir = new DirectoryInfo( versionPath );
if( dir.Exists )
{
Response.Output.Write( "{0}<br/>", version );
}
}
The problem is that you will have to keep up with the versions as they come out.
You can use the MSI API functions to get a list of all installed products and then check whether the required .NET Framework version is installed.
Just don't tell you boss that these functions will read from the Registry.
Here's the code:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
[DllImport("msi.dll", SetLastError = true)]
static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);
public const int ERROR_SUCCESS = 0;
public const int ERROR_MORE_DATA = 234;
public const int ERROR_NO_MORE_ITEMS = 259;
static void Main(string[] args)
{
int index = 0;
StringBuilder sb = new StringBuilder(39);
while (MsiEnumProducts(index++, sb) == 0)
{
var productCode = sb.ToString();
var product = new Product(productCode);
Console.WriteLine(product);
}
}
class Product
{
public string ProductCode { get; set; }
public string ProductName { get; set; }
public string ProductVersion { get; set; }
public Product(string productCode)
{
this.ProductCode = productCode;
this.ProductName = GetProperty(productCode, "InstalledProductName");
this.ProductVersion = GetProperty(productCode, "VersionString");
}
public override string ToString()
{
return this.ProductCode + " - Name: " + this.ProductName + ", Version: " + this.ProductVersion;
}
static string GetProperty(string productCode, string name)
{
int size = 0;
int ret = MsiGetProductInfo(productCode, name, null, ref size); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
{
StringBuilder buffer = new StringBuilder(++size);
ret = MsiGetProductInfo(productCode, name, buffer, ref size);
if (ret == ERROR_SUCCESS)
return buffer.ToString();
}
throw new System.ComponentModel.Win32Exception(ret);
}
}
}
This page may be of use:
http://blogs.msdn.com/b/astebner/archive/2009/06/16/9763379.aspx
Although the registry bit is irrelevant to you, the checking using mscoree.dll may be of help - its just that I cant access skydrive from work hence cant look through the code.
Ill see if i find something else.

Setting IE Proxy by C#

Hello i want to set IE proxy using a C# program as WebProxy class have get proxy method.But there is no method to set it!
Here are some alternatives found by Googling:
1- GlobalProxySelection
This is from http://www.hccp.org/csharp-http-proxy.html
Sample Code:
System.Net.Uri proxyURI = new System.Net.Uri("http://64.202.165.130:3128");
System.Net.GlobalProxySelection.Select = new System.Net.WebProxy(proxyURI);
2- Another discussion on StackOverflow: Programmatically Set Browser Proxy Settings in C#
Read it if you want the proxy only for your app.
For global change, it suggests looking at: http://msdn.microsoft.com/en-us/library/aa384113.aspx
Sample Code:
WINHTTP_PROXY_INFO proxyInfo;
// Allocate memory for string members.
proxyInfo.lpszProxy = new WCHAR[25];
proxyInfo.lpszProxyBypass = new WCHAR[25];
// Set the members of the proxy info structure.
proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
swprintf_s(proxyInfo.lpszProxy, 25, L"proxy_server");
swprintf_s(proxyInfo.lpszProxyBypass, 25, L"<local>");
// Set the default proxy configuration.
if (WinHttpSetDefaultProxyConfiguration( &proxyInfo ))
printf("Proxy Configuration Set.\n");
// Free memory allocated to the strings.
delete [] proxyInfo.lpszProxy;
delete [] proxyInfo.lpszProxyBypass;
3- Using Native Code
This is from http://huddledmasses.org/setting-windows-internet-connection-proxy-from-c/
Sample Code:
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace PoshHttp
{
public class Proxies
{
public static bool UnsetProxy()
{
return SetProxy(null, null);
}
public static bool SetProxy(string strProxy)
{
return SetProxy(strProxy, null);
}
public static bool SetProxy(string strProxy, string exceptions)
{
InternetPerConnOptionList list = new InternetPerConnOptionList();
int optionCount = string.IsNullOrEmpty(strProxy) ? 1 : (string.IsNullOrEmpty(exceptions) ? 2 : 3);
InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
// USE a proxy server ...
options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY));
// use THIS proxy server
if (optionCount > 1)
{
options[1].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER;
options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy);
// except for these addresses ...
if (optionCount > 2)
{
options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS;
options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions);
}
}
// default stuff
list.dwSize = Marshal.SizeOf(list);
list.szConnection = IntPtr.Zero;
list.dwOptionCount = options.Length;
list.dwOptionError = 0;
int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
// make a pointer out of all that ...
IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length);
// copy the array over into that spot in memory ...
for (int i = 0; i < options.Length; ++i)
{
IntPtr opt = new IntPtr(optionsPtr.ToInt32() + (i * optSize));
Marshal.StructureToPtr(options[i], opt, false);
}
list.options = optionsPtr;
// and then make a pointer out of the whole list
IntPtr ipcoListPtr = Marshal.AllocCoTaskMem((Int32)list.dwSize);
Marshal.StructureToPtr(list, ipcoListPtr, false);
// and finally, call the API method!
int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero,
InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
ipcoListPtr, list.dwSize) ? -1 : 0;
if (returnvalue == 0)
{ // get the error codes, they might be helpful
returnvalue = Marshal.GetLastWin32Error();
}
// FREE the data ASAP
Marshal.FreeCoTaskMem(optionsPtr);
Marshal.FreeCoTaskMem(ipcoListPtr);
if (returnvalue > 0)
{ // throw the error codes, they might be helpful
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return (returnvalue < 0);
}
}
#region WinInet structures
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct InternetPerConnOptionList
{
public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct
public IntPtr szConnection; // connection name to set/query options
public int dwOptionCount; // number of options to set/query
public int dwOptionError; // on error, which option failed
//[MarshalAs(UnmanagedType.)]
public IntPtr options;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct InternetConnectionOption
{
static readonly int Size;
public PerConnOption m_Option;
public InternetConnectionOptionValue m_Value;
static InternetConnectionOption()
{
InternetConnectionOption.Size = Marshal.SizeOf(typeof(InternetConnectionOption));
}
// Nested Types
[StructLayout(LayoutKind.Explicit)]
public struct InternetConnectionOptionValue
{
// Fields
[FieldOffset(0)]
public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime;
[FieldOffset(0)]
public int m_Int;
[FieldOffset(0)]
public IntPtr m_StringPtr;
}
}
#endregion
#region WinInet enums
//
// options manifests for Internet{Query|Set}Option
//
public enum InternetOption : uint
{
INTERNET_OPTION_PER_CONNECTION_OPTION = 75
}
//
// Options used in INTERNET_PER_CONN_OPTON struct
//
public enum PerConnOption
{
INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags
INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers.
INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server.
INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script.
}
//
// PER_CONN_FLAGS
//
[Flags]
public enum PerConnFlags
{
PROXY_TYPE_DIRECT = 0x00000001, // direct to net
PROXY_TYPE_PROXY = 0x00000002, // via named proxy
PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
}
#endregion
internal static class NativeMethods
{
[DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength);
}
}
Please check the links themselves for details and complete parts of the solutions.

Categories