c# how to determine session id of specific logged in windows user - c#

like the title said, i want to create a method to search a windows user session id by the domainname\username.
I already finished to read the currently logged in users, but id do not know to determine their session id.
My goal is to kill the session of specific users.

Based on the code from: How do you retrieve a list of logged-in/connected users in .NET?
Modified a bit, the following code will list the logged in users and their corresponding session ids.
class Program
{
static void Main(string[] args)
{
var userLogins = new UserLogins();
// this code gets the users from localhost -
// can change this to a remote hostname on the network
var users = UserLogins.GetUsers("localhost");
foreach (var user in users)
{
Console.WriteLine("User: " + user);
}
Console.ReadKey();
}
public class UserLogins
{
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll")]
static extern Int32 WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] Int32 Reserved,
[MarshalAs(UnmanagedType.U4)] Int32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("Wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(
System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public String pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public static IntPtr OpenServer(String Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
public static IEnumerable<UserInfo> GetUsers(String ServerName)
{
IntPtr serverHandle = IntPtr.Zero;
List<String> resultList = new List<string>();
serverHandle = OpenServer(ServerName);
try
{
IntPtr SessionInfoPtr = IntPtr.Zero;
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
Int32 sessionCount = 0;
Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int32 currentSession = (int)SessionInfoPtr;
uint bytes = 0;
if (retVal != 0)
{
for (int i = 0; i < sessionCount; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
currentSession += dataSize;
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
yield return new UserInfo
{
Domain = Marshal.PtrToStringAnsi(domainPtr),
User = Marshal.PtrToStringAnsi(userPtr),
SessionID = si.SessionID
};
WTSFreeMemory(userPtr);
WTSFreeMemory(domainPtr);
}
WTSFreeMemory(SessionInfoPtr);
}
}
finally
{
CloseServer(serverHandle);
}
}
}
public class UserInfo
{
public string Domain { get; set; }
public string User { get; set; }
public int SessionID { get; set; }
public override string ToString()
{
return string.Format("{0}\\{1}: {2}", Domain, User, SessionID);
}
}
}

create a commandline application.
call the command "query session" and store the results in a list for example sessionList.
than you can say:
var sessionList = Process.Start("cmd", "c:\>query session").ToList();
sessionList = sessionList.Where(x => x.Username == "Piet")
foreach( var item in sessionList)
{
console.WriteLine(item.id)
}
maybe you need to finetune it a little bit but it will work

Related

How i change console application project to windows form app. project

I made a console application project for my project but its console application so how I change it to Form application... can anyone help me to change this console application to Windows form application.
Who know change console application codes to form application codes.
Please help me.. i want put "static void Main(string[] args) "codes in a button..
public class Win32API
{
[DllImport("ntdll.dll")]
public static extern int NtQueryObject(IntPtr ObjectHandle, int
ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength,
ref int returnLength);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
[DllImport("ntdll.dll")]
public static extern uint NtQuerySystemInformation(int
SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength,
ref int returnLength);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr OpenMutex(UInt32 desiredAccess, bool inheritHandle, string name);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentProcess();
public enum ObjectInformationClass : int
{
ObjectBasicInformation = 0,
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
ObjectAllTypesInformation = 3,
ObjectHandleInformation = 4
}
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_BASIC_INFORMATION
{ // Information Class 0
public int Attributes;
public int GrantedAccess;
public int HandleCount;
public int PointerCount;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int NameInformationLength;
public int TypeInformationLength;
public int SecurityDescriptorLength;
public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_TYPE_INFORMATION
{ // Information Class 2
public UNICODE_STRING Name;
public int ObjectCount;
public int HandleCount;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int Reserved4;
public int PeakObjectCount;
public int PeakHandleCount;
public int Reserved5;
public int Reserved6;
public int Reserved7;
public int Reserved8;
public int InvalidAttributes;
public GENERIC_MAPPING GenericMapping;
public int ValidAccess;
public byte Unknown;
public byte MaintainHandleDatabase;
public int PoolType;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_NAME_INFORMATION
{ // Information Class 1
public UNICODE_STRING Name;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct GENERIC_MAPPING
{
public int GenericRead;
public int GenericWrite;
public int GenericExecute;
public int GenericAll;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_HANDLE_INFORMATION
{ // Information Class 16
public int ProcessID;
public byte ObjectTypeNumber;
public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
public ushort Handle;
public int Object_Pointer;
public UInt32 GrantedAccess;
}
public const int MAX_PATH = 260;
public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
public const int DUPLICATE_SAME_ACCESS = 0x2;
public const int DUPLICATE_CLOSE_SOURCE = 0x1;
}
public class Win32Processes
{
const int CNST_SYSTEM_HANDLE_INFORMATION = 16;
const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;
public static string getObjectTypeName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process)
{
IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);
IntPtr ipHandle = IntPtr.Zero;
var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
IntPtr ipBasic = IntPtr.Zero;
var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();
IntPtr ipObjectType = IntPtr.Zero;
IntPtr ipObjectName = IntPtr.Zero;
string strObjectTypeName = "";
int nLength = 0;
int nReturn = 0;
IntPtr ipTemp = IntPtr.Zero;
if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle,
Win32API.GetCurrentProcess(), out ipHandle,
0, false, Win32API.DUPLICATE_SAME_ACCESS))
return null;
ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation,
ipBasic, Marshal.SizeOf(objBasic), ref nLength);
objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
Marshal.FreeHGlobal(ipBasic);
ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);
nLength = objBasic.TypeInformationLength;
while ((uint)(nReturn = Win32API.NtQueryObject(
ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType,
nLength, ref nLength)) ==
Win32API.STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(ipObjectType);
ipObjectType = Marshal.AllocHGlobal(nLength);
}
objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());
if (Is64Bits())
{
ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32);
}
else
{
ipTemp = objObjectType.Name.Buffer;
}
strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);
Marshal.FreeHGlobal(ipObjectType);
return strObjectTypeName;
}
public static string getObjectName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process)
{
IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);
IntPtr ipHandle = IntPtr.Zero;
var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
IntPtr ipBasic = IntPtr.Zero;
IntPtr ipObjectType = IntPtr.Zero;
var objObjectName = new Win32API.OBJECT_NAME_INFORMATION();
IntPtr ipObjectName = IntPtr.Zero;
string strObjectName = "";
int nLength = 0;
int nReturn = 0;
IntPtr ipTemp = IntPtr.Zero;
if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle, Win32API.GetCurrentProcess(),
out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS))
return null;
ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation,
ipBasic, Marshal.SizeOf(objBasic), ref nLength);
objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
Marshal.FreeHGlobal(ipBasic);
nLength = objBasic.NameInformationLength;
ipObjectName = Marshal.AllocHGlobal(nLength);
while ((uint)(nReturn = Win32API.NtQueryObject(
ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation,
ipObjectName, nLength, ref nLength))
== Win32API.STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(ipObjectName);
ipObjectName = Marshal.AllocHGlobal(nLength);
}
objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType());
if (Is64Bits())
{
ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
}
else
{
ipTemp = objObjectName.Name.Buffer;
}
if (ipTemp != IntPtr.Zero)
{
byte[] baTemp2 = new byte[nLength];
try
{
Marshal.Copy(ipTemp, baTemp2, 0, nLength);
strObjectName = Marshal.PtrToStringUni(Is64Bits() ?
new IntPtr(ipTemp.ToInt64()) :
new IntPtr(ipTemp.ToInt32()));
return strObjectName;
}
catch (AccessViolationException)
{
return null;
}
finally
{
Marshal.FreeHGlobal(ipObjectName);
Win32API.CloseHandle(ipHandle);
}
}
return null;
}
public static List<Win32API.SYSTEM_HANDLE_INFORMATION>
GetHandles(Process process = null, string IN_strObjectTypeName = null, string IN_strObjectName = null)
{
uint nStatus;
int nHandleInfoSize = 0x10000;
IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
int nLength = 0;
IntPtr ipHandle = IntPtr.Zero;
while ((nStatus = Win32API.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer,
nHandleInfoSize, ref nLength)) ==
STATUS_INFO_LENGTH_MISMATCH)
{
nHandleInfoSize = nLength;
Marshal.FreeHGlobal(ipHandlePointer);
ipHandlePointer = Marshal.AllocHGlobal(nLength);
}
byte[] baTemp = new byte[nLength];
Marshal.Copy(ipHandlePointer, baTemp, 0, nLength);
long lHandleCount = 0;
if (Is64Bits())
{
lHandleCount = Marshal.ReadInt64(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
}
else
{
lHandleCount = Marshal.ReadInt32(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
}
Win32API.SYSTEM_HANDLE_INFORMATION shHandle;
List<Win32API.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<Win32API.SYSTEM_HANDLE_INFORMATION>();
for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
{
shHandle = new Win32API.SYSTEM_HANDLE_INFORMATION();
if (Is64Bits())
{
shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
}
else
{
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
}
if (process != null)
{
if (shHandle.ProcessID != process.Id) continue;
}
string strObjectTypeName = "";
if (IN_strObjectTypeName != null){
strObjectTypeName = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
if (strObjectTypeName != IN_strObjectTypeName) continue;
}
string strObjectName = "";
if (IN_strObjectName != null){
strObjectName = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
if (strObjectName != IN_strObjectName) continue;
}
string strObjectTypeName2 = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
string strObjectName2 = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
Console.WriteLine("{0} {1} {2}", shHandle.ProcessID, strObjectTypeName2, strObjectName2);
lstHandles.Add(shHandle);
}
return lstHandles;
}
public static bool Is64Bits()
{
return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
}
}
class Program
{
static void Main(string[] args)
{
String MutexName = "MSCTF.Asm.MutexDefault1";
String ProcessName = "notepad";
try
{
Process process = Process.GetProcessesByName(ProcessName)[0];
var handles = Win32Processes.GetHandles(process, "Mutant", "\\Sessions\\1\\BaseNamedObjects\\" + MutexName);
if (handles.Count == 0) throw new System.ArgumentException("NoMutex", "original");
foreach (var handle in handles)
{
IntPtr ipHandle = IntPtr.Zero;
if (!Win32API.DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_CLOSE_SOURCE))
Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error());
Console.WriteLine("Mutex was killed");
}
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("The process name '{0}' is not currently running", ProcessName);
}
catch (ArgumentException)
{
Console.WriteLine("The Mutex '{0}' was not found in the process '{1}'", MutexName, ProcessName);
}
Console.ReadLine();
}
}
}
`
Create a new project using the Visual Studio "New Project' dialogue and select:
C# Windows Form App (.NET Framework)
Go to the designer and add a button, which can be found in the toolbox.
Then add a button click event handler, put your code inside the button click event handler.
Here's a 3 minute video showing you how to do it

Detect if device is using USB 3.0

Does anyone know a way to detect if a USB device connected to a USB 3.0 host port is running at 3.0 or 2.0 using C#?
We are manufacturing USB 3.0 extension cables and we need to verify that all the pins have been soldered correctly. We would like to do this in software. We would like to connect a 3.0 thumb drive to the cable and check if the device is operating in USB 3.0 mode. If it is in 2.0 mode, we know their is a problem with 1 or more of the USB 3.0 lines.
I've managed to cook up a working demo with the help of some source code I found.
private static void Main(string[] args)
{
var hostCtrls = USB.GetHostControllers();
foreach (var hostCtrl in hostCtrls)
{
var hub = hostCtrl.GetRootHub();
foreach (var port in hub.GetPorts())
{
if (port.IsDeviceConnected && !port.IsHub)
{
var device = port.GetDevice();
Console.WriteLine("Serial: " + device.DeviceSerialNumber);
Console.WriteLine("Speed: " + port.Speed);
Console.WriteLine("Port: " + device.PortNumber + Environment.NewLine);
}
}
}
}
The application enumerates the USB Host Controllers. Then it gets the Root Hub and enumarates the ports belonging to it. If there is a device connected and it's not a hub then it displays the required information.
In your case you probably know which device you want to check so you can modify the source (both the above and the linked code) to specifically check only that device.
You'll need to create a method in the USB class to get a specific port from a specific hub by specifying port number and the path to the hub.
Something like:
GetDeviceSpeed(string hubPath, int portNumber) { ... }
and the call it with the appropriate values:
var hubPath = #"\\.\NUSB3#ROOT_HUB30#5&b235176&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}";
var portNumber = 2;
GetDeviceSpeed(hubPath, portNumber);
If you however are reluctant to do this then you can simply use the above code and make notice of the serial number of the device you want to test and only check the speed then:
if (device.DeviceSerialNumber == "xxxxxx")
Console.WriteLine("Speed: " + port.Speed);
If you are to use this in an application with a GUI you could just select the device you want to check in a dropdown.
Well... There are some thoughts and hopefully a working solution.
Addendum
For the sake of longevity I'll include the modified classes I used for the demo.
(Comments and empty lines removed due to SO limitations on 30000 characters):
public class USB
{
const int GENERIC_WRITE = 0x40000000;
const int FILE_SHARE_READ = 0x1;
const int FILE_SHARE_WRITE = 0x2;
const int OPEN_EXISTING = 0x3;
const int INVALID_HANDLE_VALUE = -1;
const int IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
const int IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
const int IOCTL_USB_GET_NODE_INFORMATION = 0x220408;
const int IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
const int IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410;
const int IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
const int IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420;
const int USB_DEVICE_DESCRIPTOR_TYPE = 0x1;
const int USB_STRING_DESCRIPTOR_TYPE = 0x3;
const int BUFFER_SIZE = 2048;
const int MAXIMUM_USB_STRING_LENGTH = 255;
const string GUID_DEVINTERFACE_HUBCONTROLLER = "3abf6f2d-71c4-462a-8a92-1e6861e6af27";
const string REGSTR_KEY_USB = "USB";
const int DIGCF_PRESENT = 0x2;
const int DIGCF_ALLCLASSES = 0x4;
const int DIGCF_DEVICEINTERFACE = 0x10;
const int SPDRP_DRIVER = 0x9;
const int SPDRP_DEVICEDESC = 0x0;
const int REG_SZ = 1;
enum USB_HUB_NODE
{
UsbHub,
UsbMIParent
}
enum USB_CONNECTION_STATUS
{
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
}
enum USB_DEVICE_SPEED : byte
{
UsbLowSpeed,
UsbFullSpeed,
UsbHighSpeed,
UsbSuperSpeed
}
[StructLayout(LayoutKind.Sequential)]
struct SP_DEVINFO_DATA
{
public int cbSize;
public Guid ClassGuid;
public IntPtr DevInst;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential)]
struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public Guid InterfaceClassGuid;
public int Flags;
public IntPtr Reserved;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
public string DevicePath;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct USB_HCD_DRIVERKEY_NAME
{
public int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
public string DriverKeyName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct USB_ROOT_HUB_NAME
{
public int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
public string RootHubName;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct USB_HUB_DESCRIPTOR
{
public byte bDescriptorLength;
public byte bDescriptorType;
public byte bNumberOfPorts;
public short wHubCharacteristics;
public byte bPowerOnToPowerGood;
public byte bHubControlCurrent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] bRemoveAndPowerMask;
}
[StructLayout(LayoutKind.Sequential)]
struct USB_HUB_INFORMATION
{
public USB_HUB_DESCRIPTOR HubDescriptor;
public byte HubIsBusPowered;
}
[StructLayout(LayoutKind.Sequential)]
struct USB_NODE_INFORMATION
{
public int NodeType;
public USB_HUB_INFORMATION HubInformation;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct USB_NODE_CONNECTION_INFORMATION_EX
{
public int ConnectionIndex;
public USB_DEVICE_DESCRIPTOR DeviceDescriptor;
public byte CurrentConfigurationValue;
public byte Speed;
public byte DeviceIsHub;
public short DeviceAddress;
public int NumberOfOpenPipes;
public int ConnectionStatus;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct USB_DEVICE_DESCRIPTOR
{
public byte bLength;
public byte bDescriptorType;
public short bcdUSB;
public byte bDeviceClass;
public byte bDeviceSubClass;
public byte bDeviceProtocol;
public byte bMaxPacketSize0;
public short idVendor;
public short idProduct;
public short bcdDevice;
public byte iManufacturer;
public byte iProduct;
public byte iSerialNumber;
public byte bNumConfigurations;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct USB_STRING_DESCRIPTOR
{
public byte bLength;
public byte bDescriptorType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
public string bString;
}
[StructLayout(LayoutKind.Sequential)]
struct USB_SETUP_PACKET
{
public byte bmRequest;
public byte bRequest;
public short wValue;
public short wIndex;
public short wLength;
}
[StructLayout(LayoutKind.Sequential)]
struct USB_DESCRIPTOR_REQUEST
{
public int ConnectionIndex;
public USB_SETUP_PACKET SetupPacket;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct USB_NODE_CONNECTION_NAME
{
public int ConnectionIndex;
public int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
public string NodeName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct USB_NODE_CONNECTION_DRIVERKEY_NAME
{
public int ConnectionIndex;
public int ActualLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
public string DriverKeyName;
}
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid,
int Enumerator,
IntPtr hwndParent,
int Flags
);
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static extern IntPtr SetupDiGetClassDevs(
int ClassGuid,
string Enumerator,
IntPtr hwndParent,
int Flags
);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInterfaces(
IntPtr DeviceInfoSet,
IntPtr DeviceInfoData,
ref Guid InterfaceClassGuid,
int MemberIndex,
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInterfaceDetail(
IntPtr DeviceInfoSet,
ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
int DeviceInterfaceDetailDataSize,
ref int RequiredSize,
ref SP_DEVINFO_DATA DeviceInfoData
);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceRegistryProperty(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
int iProperty,
ref int PropertyRegDataType,
IntPtr PropertyBuffer,
int PropertyBufferSize,
ref int RequiredSize
);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiEnumDeviceInfo(
IntPtr DeviceInfoSet,
int MemberIndex,
ref SP_DEVINFO_DATA DeviceInfoData
);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiDestroyDeviceInfoList(
IntPtr DeviceInfoSet
);
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool SetupDiGetDeviceInstanceId(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
int DeviceInstanceIdSize,
out int RequiredSize
);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(
IntPtr hDevice,
int dwIoControlCode,
IntPtr lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFile(
string lpFileName,
int dwDesiredAccess,
int dwShareMode,
IntPtr lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CloseHandle(
IntPtr hObject
);
static public System.Collections.ObjectModel.ReadOnlyCollection<USBController> GetHostControllers()
{
List<USBController> HostList = new List<USBController>();
Guid HostGUID = new Guid(GUID_DEVINTERFACE_HUBCONTROLLER);
IntPtr h = SetupDiGetClassDevs(ref HostGUID, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
bool Success;
int i = 0;
do
{
USBController host = new USBController();
host.ControllerIndex = i;
SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
dia.cbSize = Marshal.SizeOf(dia);
Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref HostGUID, i, ref dia);
if (Success)
{
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
da.cbSize = Marshal.SizeOf(da);
SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
didd.cbSize = 4 + Marshal.SystemDefaultCharSize;
int nRequiredSize = 0;
int nBytes = BUFFER_SIZE;
if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
{
host.ControllerDevicePath = didd.DevicePath;
int RequiredSize = 0;
int RegType = REG_SZ;
if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
{
host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf);
}
if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
{
host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf);
}
}
HostList.Add(host);
}
i++;
} while (Success);
Marshal.FreeHGlobal(ptrBuf);
SetupDiDestroyDeviceInfoList(h);
}
return new System.Collections.ObjectModel.ReadOnlyCollection<USBController>(HostList);
}
public class USBController
{
internal int ControllerIndex;
internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc;
public USBController()
{
ControllerIndex = 0;
ControllerDevicePath = "";
ControllerDeviceDesc = "";
ControllerDriverKeyName = "";
}
public int Index
{
get { return ControllerIndex; }
}
public string DevicePath
{
get { return ControllerDevicePath; }
}
public string DriverKeyName
{
get { return ControllerDriverKeyName; }
}
public string Name
{
get { return ControllerDeviceDesc; }
}
public USBHub GetRootHub()
{
IntPtr h, h2;
USBHub Root = new USBHub();
Root.HubIsRootHub = true;
Root.HubDeviceDesc = "Root Hub";
h = CreateFile(ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytesReturned;
USB_ROOT_HUB_NAME HubName = new USB_ROOT_HUB_NAME();
int nBytes = Marshal.SizeOf(HubName);
IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
if (DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes, out nBytesReturned, IntPtr.Zero))
{
HubName = (USB_ROOT_HUB_NAME)Marshal.PtrToStructure(ptrHubName, typeof(USB_ROOT_HUB_NAME));
Root.HubDevicePath = #"\\.\" + HubName.RootHubName;
}
h2 = CreateFile(Root.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h2.ToInt32() != INVALID_HANDLE_VALUE)
{
USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
NodeInfo.NodeType = (int)USB_HUB_NODE.UsbHub;
nBytes = Marshal.SizeOf(NodeInfo);
IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(NodeInfo, ptrNodeInfo, true);
if (DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo, typeof(USB_NODE_INFORMATION));
Root.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
Root.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
}
Marshal.FreeHGlobal(ptrNodeInfo);
CloseHandle(h2);
}
Marshal.FreeHGlobal(ptrHubName);
CloseHandle(h);
}
return Root;
}
}
public class USBHub
{
internal int HubPortCount;
internal string HubDriverKey, HubDevicePath, HubDeviceDesc;
internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceID;
internal bool HubIsBusPowered, HubIsRootHub;
public USBHub()
{
HubPortCount = 0;
HubDevicePath = "";
HubDeviceDesc = "";
HubDriverKey = "";
HubIsBusPowered = false;
HubIsRootHub = false;
HubManufacturer = "";
HubProduct = "";
HubSerialNumber = "";
HubInstanceID = "";
}
public int PortCount
{
get { return HubPortCount; }
}
public string DevicePath
{
get { return HubDevicePath; }
}
public string DriverKey
{
get { return HubDriverKey; }
}
public string Name
{
get { return HubDeviceDesc; }
}
public string InstanceID
{
get { return HubInstanceID; }
}
public bool IsBusPowered
{
get { return HubIsBusPowered; }
}
public bool IsRootHub
{
get { return HubIsRootHub; }
}
public string Manufacturer
{
get { return HubManufacturer; }
}
public string Product
{
get { return HubProduct; }
}
public string SerialNumber
{
get { return HubSerialNumber; }
}
public System.Collections.ObjectModel.ReadOnlyCollection<USBPort> GetPorts()
{
List<USBPort> PortList = new List<USBPort>();
IntPtr h = CreateFile(HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX));
IntPtr ptrNodeConnection = Marshal.AllocHGlobal(nBytes);
for (int i = 1; i <= HubPortCount; i++)
{
int nBytesReturned;
USB_NODE_CONNECTION_INFORMATION_EX NodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX();
NodeConnection.ConnectionIndex = i;
Marshal.StructureToPtr(NodeConnection, ptrNodeConnection, true);
if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes, ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeConnection = (USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(ptrNodeConnection, typeof(USB_NODE_CONNECTION_INFORMATION_EX));
USBPort port = new USBPort();
port.PortPortNumber = i;
port.PortHubDevicePath = HubDevicePath;
USB_CONNECTION_STATUS Status = (USB_CONNECTION_STATUS)NodeConnection.ConnectionStatus;
port.PortStatus = Status.ToString();
USB_DEVICE_SPEED Speed = (USB_DEVICE_SPEED)NodeConnection.Speed;
port.PortSpeed = Speed.ToString();
port.PortIsDeviceConnected = (NodeConnection.ConnectionStatus == (int)USB_CONNECTION_STATUS.DeviceConnected);
port.PortIsHub = Convert.ToBoolean(NodeConnection.DeviceIsHub);
port.PortDeviceDescriptor = NodeConnection.DeviceDescriptor;
PortList.Add(port);
}
}
Marshal.FreeHGlobal(ptrNodeConnection);
CloseHandle(h);
}
return new System.Collections.ObjectModel.ReadOnlyCollection<USBPort>(PortList);
}
}
public class USBPort
{
internal int PortPortNumber;
internal string PortStatus, PortHubDevicePath, PortSpeed;
internal bool PortIsHub, PortIsDeviceConnected;
internal USB_DEVICE_DESCRIPTOR PortDeviceDescriptor;
public USBPort()
{
PortPortNumber = 0;
PortStatus = "";
PortHubDevicePath = "";
PortSpeed = "";
PortIsHub = false;
PortIsDeviceConnected = false;
}
public int PortNumber
{
get { return PortPortNumber; }
}
public string HubDevicePath
{
get { return PortHubDevicePath; }
}
public string Status
{
get { return PortStatus; }
}
public string Speed
{
get { return PortSpeed; }
}
public bool IsHub
{
get { return PortIsHub; }
}
public bool IsDeviceConnected
{
get { return PortIsDeviceConnected; }
}
public USBDevice GetDevice()
{
if (!PortIsDeviceConnected)
{
return null;
}
USBDevice Device = new USBDevice();
Device.DevicePortNumber = PortPortNumber;
Device.DeviceHubDevicePath = PortHubDevicePath;
Device.DeviceDescriptor = PortDeviceDescriptor;
IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytesReturned;
int nBytes = BUFFER_SIZE;
string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);
if (PortDeviceDescriptor.iManufacturer > 0)
{
USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
Request.ConnectionIndex = PortPortNumber;
Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer);
Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
Request.SetupPacket.wIndex = 0x409;
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
Marshal.StructureToPtr(Request, ptrRequest, true);
if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
{
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
Device.DeviceManufacturer = StringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
if (PortDeviceDescriptor.iProduct > 0)
{
USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
Request.ConnectionIndex = PortPortNumber;
Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct);
Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
Request.SetupPacket.wIndex = 0x409;
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
Marshal.StructureToPtr(Request, ptrRequest, true);
if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
{
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
Device.DeviceProduct = StringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
if (PortDeviceDescriptor.iSerialNumber > 0)
{
USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
Request.ConnectionIndex = PortPortNumber;
Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iSerialNumber);
Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
Request.SetupPacket.wIndex = 0x409;
IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
Marshal.StructureToPtr(Request, ptrRequest, true);
if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
{
IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
Device.DeviceSerialNumber = StringDesc.bString;
}
Marshal.FreeHGlobal(ptrRequest);
}
USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKey = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
DriverKey.ConnectionIndex = PortPortNumber;
nBytes = Marshal.SizeOf(DriverKey);
IntPtr ptrDriverKey = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(DriverKey, ptrDriverKey, true);
if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
{
DriverKey = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(ptrDriverKey, typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
Device.DeviceDriverKey = DriverKey.DriverKeyName;
Device.DeviceName = GetDescriptionByKeyName(Device.DeviceDriverKey);
Device.DeviceInstanceID = GetInstanceIDByKeyName(Device.DeviceDriverKey);
}
Marshal.FreeHGlobal(ptrDriverKey);
CloseHandle(h);
}
return Device;
}
public USBHub GetHub()
{
if (!PortIsHub)
{
return null;
}
USBHub Hub = new USBHub();
IntPtr h, h2;
Hub.HubIsRootHub = false;
Hub.HubDeviceDesc = "External Hub";
h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
int nBytesReturned;
USB_NODE_CONNECTION_NAME NodeName = new USB_NODE_CONNECTION_NAME();
NodeName.ConnectionIndex = PortPortNumber;
int nBytes = Marshal.SizeOf(NodeName);
IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(NodeName, ptrNodeName, true);
if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeName = (USB_NODE_CONNECTION_NAME)Marshal.PtrToStructure(ptrNodeName, typeof(USB_NODE_CONNECTION_NAME));
Hub.HubDevicePath = #"\\.\" + NodeName.NodeName;
}
h2 = CreateFile(Hub.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (h2.ToInt32() != INVALID_HANDLE_VALUE)
{
USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
NodeInfo.NodeType = (int)USB_HUB_NODE.UsbHub;
nBytes = Marshal.SizeOf(NodeInfo);
IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
Marshal.StructureToPtr(NodeInfo, ptrNodeInfo, true);
if (DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out nBytesReturned, IntPtr.Zero))
{
NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo, typeof(USB_NODE_INFORMATION));
Hub.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
Hub.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
}
Marshal.FreeHGlobal(ptrNodeInfo);
CloseHandle(h2);
}
USBDevice Device = GetDevice();
Hub.HubInstanceID = Device.DeviceInstanceID;
Hub.HubManufacturer = Device.Manufacturer;
Hub.HubProduct = Device.Product;
Hub.HubSerialNumber = Device.SerialNumber;
Hub.HubDriverKey = Device.DriverKey;
Marshal.FreeHGlobal(ptrNodeName);
CloseHandle(h);
}
return Hub;
}
}
public class USBDevice
{
internal int DevicePortNumber;
internal string DeviceDriverKey, DeviceHubDevicePath, DeviceInstanceID, DeviceName;
internal string DeviceManufacturer, DeviceProduct, DeviceSerialNumber;
internal USB_DEVICE_DESCRIPTOR DeviceDescriptor;
public USBDevice()
{
DevicePortNumber = 0;
DeviceHubDevicePath = "";
DeviceDriverKey = "";
DeviceManufacturer = "";
DeviceProduct = "Unknown USB Device";
DeviceSerialNumber = "";
DeviceName = "";
DeviceInstanceID = "";
}
public int PortNumber
{
get { return DevicePortNumber; }
}
public string HubDevicePath
{
get { return DeviceHubDevicePath; }
}
public string DriverKey
{
get { return DeviceDriverKey; }
}
public string InstanceID
{
get { return DeviceInstanceID; }
}
public string Name
{
get { return DeviceName; }
}
public string Manufacturer
{
get { return DeviceManufacturer; }
}
public string Product
{
get { return DeviceProduct; }
}
public string SerialNumber
{
get { return DeviceSerialNumber; }
}
}
static string GetDescriptionByKeyName(string DriverKeyName)
{
string ans = "";
string DevEnum = REGSTR_KEY_USB;
IntPtr h = SetupDiGetClassDevs(0, DevEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
string KeyName;
bool Success;
int i = 0;
do
{
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
da.cbSize = Marshal.SizeOf(da);
Success = SetupDiEnumDeviceInfo(h, i, ref da);
if (Success)
{
int RequiredSize = 0;
int RegType = REG_SZ;
KeyName = "";
if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
{
KeyName = Marshal.PtrToStringAuto(ptrBuf);
}
if (KeyName == DriverKeyName)
{
if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
{
ans = Marshal.PtrToStringAuto(ptrBuf);
}
break;
}
}
i++;
} while (Success);
Marshal.FreeHGlobal(ptrBuf);
SetupDiDestroyDeviceInfoList(h);
}
return ans;
}
static string GetInstanceIDByKeyName(string DriverKeyName)
{
string ans = "";
string DevEnum = REGSTR_KEY_USB;
IntPtr h = SetupDiGetClassDevs(0, DevEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (h.ToInt32() != INVALID_HANDLE_VALUE)
{
IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
string KeyName;
bool Success;
int i = 0;
do
{
SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
da.cbSize = Marshal.SizeOf(da);
Success = SetupDiEnumDeviceInfo(h, i, ref da);
if (Success)
{
int RequiredSize = 0;
int RegType = REG_SZ;
KeyName = "";
if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
{
KeyName = Marshal.PtrToStringAuto(ptrBuf);
}
if (KeyName == DriverKeyName)
{
int nBytes = BUFFER_SIZE;
StringBuilder sb = new StringBuilder(nBytes);
SetupDiGetDeviceInstanceId(h, ref da, sb, nBytes, out RequiredSize);
ans = sb.ToString();
break;
}
}
i++;
} while (Success);
Marshal.FreeHGlobal(ptrBuf);
SetupDiDestroyDeviceInfoList(h);
}
return ans;
}
}

How to create partition on hdd using IOCTL_DISK_SET_DRIVE_LAYOUT on C#

I need to implement an hdd partitioning program using c#.
Below is part of my code.
I think it works because it returns true value from DeviceIOcontrol with no errors, but the problem is my program doesn't show anything.
I got a lot of help from Medo's home page, MSDN, and pinvoke site.
public static bool partitionDisk(string path)
{
var signature = new byte[4];
System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(signature);
using (SafeFileHandle handle = NativeMethods2.CreateFile(path, (NativeMethods2.FILE_SHARE_READ|NativeMethods.GENERIC_READ ) | (NativeMethods.GENERIC_WRITE | NativeMethods2.FILE_SHARE_WRITE), 0, IntPtr.Zero, NativeMethods2.OPEN_EXISTING, 0, IntPtr.Zero))
{
if (handle.IsInvalid) { throw new Win32Exception(); }
var newdi = new NativeMethods2.DRIVE_LAYOUT_INFORMATION_EX();
newdi.PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
newdi.PartitionCount = 4;
newdi.DriveLayoutInformaiton.Mbr.Signature = BitConverter.ToInt32(signature, 0);
newdi.PartitionEntry = new NativeMethods2.PARTITION_INFORMATION_EX[0x16];
newdi.PartitionEntry[0] = new NativeMethods2.PARTITION_INFORMATION_EX();
newdi.PartitionEntry[0].PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
newdi.PartitionEntry[0].StartingOffset = 1048576; // check by diskpart
newdi.PartitionEntry[0].PartitionLength = 0xFFFFFFFFFFfffff; //int64 max
newdi.PartitionEntry[0].PartitionNumber = 1;
newdi.PartitionEntry[0].RewritePartition = true;
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.BootIndicator = false;
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.HiddenSectors = 0; //sector size
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.PartitionType = 0x07;// PARTITION_IFS (NTFS partition or logical drive)
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.RecognizedPartition = true;
for (int k = 2; k < newdi.PartitionCount; k++)
{
newdi.PartitionEntry[k] = new NativeMethods2.PARTITION_INFORMATION_EX();
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.BootIndicator = false;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.HiddenSectors = 0;
newdi.PartitionEntry[k].PartitionLength = 0;
newdi.PartitionEntry[k].PartitionNumber = k;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.PartitionType = 0;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.RecognizedPartition = false;
newdi.PartitionEntry[k].RewritePartition = true;
newdi.PartitionEntry[k].StartingOffset = 0;
}
Int32 bytesOut = 0;
if (NativeMethods2.DeviceIoControl(handle, NativeMethods2.IOCTL_DISK_SET_DRIVE_LAYOUT, ref newdi, Marshal.SizeOf(newdi), IntPtr.Zero, 0, ref bytesOut, IntPtr.Zero) == false) { throw new Win32Exception(); }
}
}
private static class NativeMethods2
{
public const int GENERIC_READ = -2147483648;
public const int GENERIC_WRITE = 1073741824;
public const int OPEN_EXISTING = 3;
public const int FILE_SHARE_READ = 0x0000000001;
public const int FILE_SHARE_WRITE = 0x0000000002;
public const int IOCTL_DISK_UPDATE_PROPERTIES = 0x70140;
public const int IOCTL_DISK_SET_DRIVE_LAYOUT_EX = 0x7C054;
public enum PARTITION_STYLE
{
PARTITION_STYLE_MBR = 0,
PARTITION_STYLE_GPT = 1,
PARTITION_STYLE_RAW = 2,
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_EX
{
public PARTITION_STYLE PartitionStyle;
public int PartitionCount;
public DRIVE_LAYOUT_INFORMATION_UNION DriveLayoutInformaiton;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 0x16)]
public PARTITION_INFORMATION_EX[] PartitionEntry;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_EX
{
public PARTITION_STYLE PartitionStyle;
public long StartingOffset;
public long PartitionLength;
public int PartitionNumber;
public bool RewritePartition;
public PARTITION_INFORMATION_UNION DriveLayoutInformaiton;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_MBR
{
public byte PartitionType;
public bool BootIndicator;
public bool RecognizedPartition;
public Int32 HiddenSectors;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_GPT
{
public Guid PartitionType; //GUID
public Guid PartitionId; //GUID
public Int64 Attributes;
public char[] Name;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION
{
public long StartingOffset;
public long PartitionLength;
public int HiddenSectors;
public int PartitionNumber;
public byte PartitionType;
[MarshalAs(UnmanagedType.I1)]
public bool BootIndicator;
[MarshalAs(UnmanagedType.I1)]
public bool RecognizedPartition;
[MarshalAs(UnmanagedType.I1)]
public bool RewritePartition;
}
[StructLayout(LayoutKind.Explicit)]
public struct DRIVE_LAYOUT_INFORMATION_UNION
{
[FieldOffset(0)]
public DRIVE_LAYOUT_INFORMATION_MBR Mbr;
[FieldOffset(0)]
public DRIVE_LAYOUT_INFORMATION_GPT Gpt;
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_MBR
{
public Int32 Signature;
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_GPT
{
public Guid DiskId;
public Int64 StartingUsableOffset;
public Int64 UsableLength;
public ulong MaxPartitionCount;
}
[StructLayout(LayoutKind.Explicit)]
public struct PARTITION_INFORMATION_UNION
{
[FieldOffset(0)]
public PARTITION_INFORMATION_MBR Mbr;
[FieldOffset(0)]
public PARTITION_INFORMATION_GPT Gpt;
}
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref DRIVE_LAYOUT_INFORMATION_EX lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
}
private static class NativeMethods
{
public const int GENERIC_READ = -2147483648;
public const int GENERIC_WRITE = 1073741824;
public const int OPEN_EXISTING = 3;
public const int IOCTL_DISK_CREATE_DISK = 0x7C058;
public enum PARTITION_STYLE
{
PARTITION_STYLE_MBR = 0,
PARTITION_STYLE_GPT = 1,
PARTITION_STYLE_RAW = 2,
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK
{
public PARTITION_STYLE PartitionStyle;
public CREATE_DISK_UNION_MBR_GPT MbrGpt;
}
[StructLayoutAttribute(LayoutKind.Explicit)]
public struct CREATE_DISK_UNION_MBR_GPT
{
[FieldOffset(0)]
public CREATE_DISK_MBR Mbr;
[FieldOffset(0)]
public CREATE_DISK_GPT Gpt;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK_MBR
{
public Int32 Signature;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK_GPT
{
public Guid DiskId;
public Int32 MaxPartitionCount;
}
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref CREATE_DISK lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
}
...and to call the function:
DiskIO.partitionDisk("//./PHYSICALDRIVE2")

How to get the file type name?

I want to get in my c# app the name of the file type, that is shown in file properties in windows... for example .log file has the type as LOG file (.log) or .bat has Batch file for Windows (.bat)(translated from my lang, so maybe not accurate).
Please, where can i find this info? or how to get to this?
i found Get-Registered-File-Types-and-Their-Associated-Ico article, where the autor shows how to get the icon, but not the type name of file that is showed in OS.
You have to call the respective Shell function SHGetFileInfo, which is a native Win32 API.
class NativeMethods
{
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private const int SHGFI_TYPENAME = 0x400;
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO shinfo,
uint cbfileInfo,
int uFlags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public static string GetShellFileType(string fileName)
{
var shinfo = new SHFILEINFO(true);
const int flags = SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES;
if (SHGetFileInfo(fileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags) == IntPtr.Zero)
{
return "File";
}
return shinfo.szTypeName;
}
}
Then, simply call NativeMethods.GetShellFileType("...").
You can read that info from the registry
use like GetDescription("cpp") or GetDescription(".xml")
public static string ReadDefaultValue(string regKey)
{
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(regKey, false))
{
if (key != null)
{
return key.GetValue("") as string;
}
}
return null;
}
public static string GetDescription(string ext)
{
if (ext.StartsWith(".") && ext.Length > 1) ext = ext.Substring(1);
var retVal = ReadDefaultValue(ext + "file");
if (!String.IsNullOrEmpty(retVal)) return retVal;
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." + ext, false))
{
if (key == null) return "";
using (var subkey = key.OpenSubKey("OpenWithProgids"))
{
if (subkey == null) return "";
var names = subkey.GetValueNames();
if (names == null || names.Length == 0) return "";
foreach (var name in names)
{
retVal = ReadDefaultValue(name);
if (!String.IsNullOrEmpty(retVal)) return retVal;
}
}
}
return "";
}
You can get this information using the SHGetFileInfo.
using System;
using System.Runtime.InteropServices;
namespace GetFileTypeAndDescription
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr i = Win32.SHGetFileInfo(#"d:\temp\test.xls", 0, ref
shinfo,(uint)Marshal.SizeOf(shinfo),Win32.SHGFI_TY PENAME);
string s = Convert.ToString(shinfo.szTypeName.Trim());
Console.WriteLine(s);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
class Win32
{
public const uint SHGFI_DISPLAYNAME = 0x00000200;
public const uint SHGFI_TYPENAME = 0x400;
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint
dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
}
}
you have to use the shgetfileinfo, see below link for some code:
http://www.pinvoke.net/default.aspx/shell32.shgetfileinfo

C# audio recording using winmm.dll native code

Please let me know how could i record and save audio file to my hard drive by using c# code.
I already downloaded code from one of the technical web page.
That may be i don't know enough that it can support recording and saving function as well.
Please let me show you some of my downloaded Code so that you can give me any suggestion how should i do.
[WaveIn.CS]
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace SoundViewer
{
internal class WaveInHelper
{
public static void Try(int err)
{
if (err != WaveNative.MMSYSERR_NOERROR)
throw new Exception(err.ToString());
}
}
public delegate void BufferDoneEventHandler(IntPtr data, int size);
internal class WaveInBuffer : IDisposable
{
public WaveInBuffer NextBuffer;
private AutoResetEvent m_RecordEvent = new AutoResetEvent(false);
private IntPtr m_WaveIn;
private WaveNative.WaveHdr m_Header;
private byte[] m_HeaderData;
private GCHandle m_HeaderHandle;
private GCHandle m_HeaderDataHandle;
private bool m_Recording;
internal static void WaveInProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
{
if (uMsg == WaveNative.MM_WIM_DATA)
{
try
{
GCHandle h = (GCHandle)wavhdr.dwUser;
WaveInBuffer buf = (WaveInBuffer)h.Target;
buf.OnCompleted();
}
catch
{
}
}
}
public WaveInBuffer(IntPtr waveInHandle, int size)
{
m_WaveIn = waveInHandle;
m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
m_HeaderData = new byte[size];
m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
m_Header.dwBufferLength = size;
WaveInHelper.Try(WaveNative.waveInPrepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)));
}
~WaveInBuffer()
{
Dispose();
}
public void Dispose()
{
if (m_Header.lpData != IntPtr.Zero)
{
WaveNative.waveInUnprepareHeader(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header));
m_HeaderHandle.Free();
m_Header.lpData = IntPtr.Zero;
}
m_RecordEvent.Close();
if (m_HeaderDataHandle.IsAllocated)
m_HeaderDataHandle.Free();
GC.SuppressFinalize(this);
}
public int Size
{
get { return m_Header.dwBufferLength; }
}
public IntPtr Data
{
get { return m_Header.lpData; }
}
public bool Record()
{
lock(this)
{
m_RecordEvent.Reset();
m_Recording = WaveNative.waveInAddBuffer(m_WaveIn, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
System.Diagnostics.Debug.Write(string.Format("\n m_WaveIn: {0}, m_Header.dwBytesRecorded: {1}", m_WaveIn, m_Header.dwBytesRecorded));
//m_WaveIn.ToPointer();
return m_Recording;
}
}
public void WaitFor()
{
if (m_Recording)
m_Recording = m_RecordEvent.WaitOne();
else
Thread.Sleep(0);
}
private void OnCompleted()
{
m_RecordEvent.Set();
m_Recording = false;
}
}
public class WaveInRecorder : IDisposable
{
private IntPtr m_WaveIn;
private WaveInBuffer m_Buffers; // linked list
private WaveInBuffer m_CurrentBuffer;
private Thread m_Thread;
private BufferDoneEventHandler m_DoneProc;
private bool m_Finished;
private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveInBuffer.WaveInProc);
public static int DeviceCount
{
get { return WaveNative.waveInGetNumDevs(); }
}
public WaveInRecorder(int device, WaveFormat format, int bufferSize, int bufferCount, BufferDoneEventHandler doneProc)
{
m_DoneProc = doneProc;
WaveInHelper.Try(WaveNative.waveInOpen(out m_WaveIn, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
AllocateBuffers(bufferSize, bufferCount);
for (int i = 0; i < bufferCount; i++)
{
SelectNextBuffer();
m_CurrentBuffer.Record();
}
WaveInHelper.Try(WaveNative.waveInStart(m_WaveIn));
m_Thread = new Thread(new ThreadStart(ThreadProc));
m_Thread.Start();
}
public void Recording()
{
//int rawsize = Marshal.SizeOf(m_WaveIn);
//byte[] rawdata = new byte[256 * 1024];
////Marshal.Copy(m_WaveIn, rawdata, 0, rawsize);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata );
//Marshal.Copy(rawdata, 0, m_WaveIn, rawdata.Length);
////System.IO.File.WriteAllBytes(string.Format("C:\\TempImage\\audio_{0}.wav", Guid.NewGuid()), rawdata);
////Marshal.FreeHGlobal(m_WaveIn);
//System.IO.MemoryStream ms = new System.IO.MemoryStream(
//int elementSize = Marshal.SizeOf(typeof(IntPtr));
//System.Diagnostics.Debug.Print("Reading unmanaged memory:");
//// Print the 10 elements of the C-style unmanagedArray
//for (int i = 0; i < 10; i++)
//{
// System.Diagnostics.Debug.Print(Marshal.ReadIntPtr(m_WaveIn, i * elementSize));
//}
}
~WaveInRecorder()
{
Dispose();
}
public void Dispose()
{
if (m_Thread != null)
try
{
m_Finished = true;
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInReset(m_WaveIn);
WaitForAllBuffers();
m_Thread.Join();
m_DoneProc = null;
FreeBuffers();
if (m_WaveIn != IntPtr.Zero)
WaveNative.waveInClose(m_WaveIn);
}
finally
{
m_Thread = null;
m_WaveIn = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
private void ThreadProc()
{
while (!m_Finished)
{
Advance();
if (m_DoneProc != null && !m_Finished)
m_DoneProc(m_CurrentBuffer.Data, m_CurrentBuffer.Size);
m_CurrentBuffer.Record();
}
}
private void AllocateBuffers(int bufferSize, int bufferCount)
{
FreeBuffers();
if (bufferCount > 0)
{
m_Buffers = new WaveInBuffer(m_WaveIn, bufferSize);
WaveInBuffer Prev = m_Buffers;
try
{
for (int i = 1; i < bufferCount; i++)
{
WaveInBuffer Buf = new WaveInBuffer(m_WaveIn, bufferSize);
Prev.NextBuffer = Buf;
Prev = Buf;
}
}
finally
{
Prev.NextBuffer = m_Buffers;
}
}
}
private void FreeBuffers()
{
m_CurrentBuffer = null;
if (m_Buffers != null)
{
WaveInBuffer First = m_Buffers;
m_Buffers = null;
WaveInBuffer Current = First;
do
{
WaveInBuffer Next = Current.NextBuffer;
Current.Dispose();
Current = Next;
} while(Current != First);
}
}
private void Advance()
{
SelectNextBuffer();
m_CurrentBuffer.WaitFor();
}
private void SelectNextBuffer()
{
m_CurrentBuffer = m_CurrentBuffer == null ? m_Buffers : m_CurrentBuffer.NextBuffer;
}
private void WaitForAllBuffers()
{
WaveInBuffer Buf = m_Buffers;
while (Buf.NextBuffer != m_Buffers)
{
Buf.WaitFor();
Buf = Buf.NextBuffer;
}
}
}
}
[WaveNative.cs]
internal class WaveNative
{
// consts
public const int MMSYSERR_NOERROR = 0; // no error
public const int MM_WOM_OPEN = 0x3BB;
public const int MM_WOM_CLOSE = 0x3BC;
public const int MM_WOM_DONE = 0x3BD;
public const int MM_WIM_OPEN = 0x3BE;
public const int MM_WIM_CLOSE = 0x3BF;
public const int MM_WIM_DATA = 0x3C0;
public const int CALLBACK_FUNCTION = 0x00030000; // dwCallback is a FARPROC
public const int TIME_MS = 0x0001; // time in milliseconds
public const int TIME_SAMPLES = 0x0002; // number of wave samples
public const int TIME_BYTES = 0x0004; // current byte offset
// callbacks
public delegate void WaveDelegate(IntPtr hdrvr, int uMsg, int dwUser, ref WaveHdr wavhdr, int dwParam2);
// structs
[StructLayout(LayoutKind.Sequential)] public struct WaveHdr
{
public IntPtr lpData; // pointer to locked data buffer
public int dwBufferLength; // length of data buffer
public int dwBytesRecorded; // used for input only
public IntPtr dwUser; // for client's use
public int dwFlags; // assorted flags (see defines)
public int dwLoops; // loop control counter
public IntPtr lpNext; // PWaveHdr, reserved for driver
public int reserved; // reserved for driver
}
private const string mmdll = "winmm.dll";
// WaveOut calls
[DllImport(mmdll)]
public static extern int waveOutGetNumDevs();
[DllImport(mmdll)]
public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveOutReset(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutClose(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutPause(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutRestart(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
[DllImport(mmdll)]
public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
[DllImport(mmdll)]
public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);
// WaveIn calls
[DllImport(mmdll)]
public static extern int waveInGetNumDevs();
[DllImport(mmdll)]
public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, int cbwh);
[DllImport(mmdll)]
public static extern int waveInClose(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveInReset(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStart(IntPtr hwi);
[DllImport(mmdll)]
public static extern int waveInStop(IntPtr hwi);
}

Categories

Resources