private static string GetDeviceInstanceId(SafeCmConnectMachineHandle safeMachineHandle, string hostName, NativeMethods.SP_DEVINFO_DATA diData) { uint ptrPrevious; var lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, diData.DevInst, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize / 8)) // 512 { lastError = NativeMethods.CM_Get_Device_ID_Ex(diData.DevInst, safeBuffer, (uint)safeBuffer.Capacity, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } // Device InstanceID, such as: "USB\VID_8087&PID_0A2B\5&2EDA7E1E&0&7", "SCSI\DISK&VEN_SANDISK&PROD_X400\4&288ED25&0&000200", ... return(safeBuffer.PtrToStringUni()); } }
private static string GetDeviceRegistryProperty(SafeHandle safeHandle, NativeMethods.SP_DEVINFO_DATA infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum property) { var bufferSize = NativeMethods.DefaultFileBufferSize / 8; // 512 while (true) { using (var safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize)) { var success = NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref infoData, property, IntPtr.Zero, safeBuffer, (uint)safeBuffer.Capacity, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (success) { var value = safeBuffer.PtrToStringUni(); return(!Utils.IsNullOrWhiteSpace(value) ? value.Trim() : null); } // MSDN: SetupDiGetDeviceRegistryProperty returns ERROR_INVALID_DATA error code if // the requested property does not exist for a device or if the property data is not valid. if (lastError == Win32Errors.ERROR_INVALID_DATA) { return(null); } bufferSize = GetDoubledBufferSizeOrThrowException(lastError, safeBuffer, bufferSize, property.ToString()); } } }
public BackupStreamInfo ReadStreamInfo() { using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context)) { NativeError.ThrowException(); } if (numberOfBytesRead == 0) { return(null); } if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))) { throw new IOException(Resources.IncompleteHeaderRead); } NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>(); uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity); if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context)) { NativeError.ThrowException(); } string name = hBuf.PtrToStringUni((int)nameLength / 2); return(new BackupStreamInfo(streamID, name)); } }
public BackupStreamInfo ReadStreamInfo() { var sizeOf = Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)); using (var hBuf = new SafeGlobalMemoryBufferHandle(sizeOf)) { uint numberOfBytesRead; var success = NativeMethods.BackupRead(SafeFileHandle, hBuf, (uint)sizeOf, out numberOfBytesRead, false, _processSecurity, ref _context); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } if (numberOfBytesRead == 0) { return(null); } if (numberOfBytesRead < sizeOf) { throw new IOException(Resources.Read_Incomplete_Header); } var streamID = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>(0); var nameLength = (uint)Math.Min(streamID.dwStreamNameSize, hBuf.Capacity); success = NativeMethods.BackupRead(SafeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, _processSecurity, ref _context); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } var name = hBuf.PtrToStringUni(0, (int)nameLength / UnicodeEncoding.CharSize); return(new BackupStreamInfo(streamID, name)); } }
internal static IEnumerable <FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoCore(KernelTransaction transaction, SafeFileHandle safeFileHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message); } var pathLp = path; var callerHandle = null != safeFileHandle; if (!callerHandle) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); safeFileHandle = File.CreateFileCore(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, false, PathFormat.LongFullPath); } try { if (!NativeMethods.IsValidHandle(safeFileHandle, Marshal.GetLastWin32Error(), !continueOnException)) { yield break; } var fileNameOffset = (int)Marshal.OffsetOf(typeof(NativeMethods.FILE_ID_BOTH_DIR_INFO), "FileName"); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { while (true) { var success = NativeMethods.GetFileInformationByHandleEx(safeFileHandle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_ID_BOTH_DIR_INFO, safeBuffer, (uint)safeBuffer.Capacity); var lastError = Marshal.GetLastWin32Error(); if (!success) { switch ((uint)lastError) { case Win32Errors.ERROR_SUCCESS: case Win32Errors.ERROR_NO_MORE_FILES: case Win32Errors.ERROR_HANDLE_EOF: yield break; case Win32Errors.ERROR_MORE_DATA: continue; default: NativeError.ThrowException(lastError, pathLp); // Keep the compiler happy as we never get here. yield break; } } var offset = 0; NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi; do { fibdi = safeBuffer.PtrToStructure <NativeMethods.FILE_ID_BOTH_DIR_INFO>(offset); var fileName = safeBuffer.PtrToStringUni(offset + fileNameOffset, (int)(fibdi.FileNameLength / UnicodeEncoding.CharSize)); offset += fibdi.NextEntryOffset; if (File.IsDirectory(fibdi.FileAttributes) && (fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.Ordinal) || fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.Ordinal))) { continue; } yield return(new FileIdBothDirectoryInfo(fibdi, fileName)); //offset += fibdi.NextEntryOffset; } while (fibdi.NextEntryOffset != 0); } } } finally { // Handle is ours, dispose. if (!callerHandle && null != safeFileHandle) { safeFileHandle.Close(); } } }
internal static IEnumerable <DeviceInfo> EnumerateDevicesCore(SafeHandle safeHandle, string hostName, DeviceGuid deviceInterfaceGuid) { bool callerHandle = safeHandle != null; var deviceGuid = new Guid(Utils.GetEnumDescription(deviceInterfaceGuid)); // CM_Connect_Machine() // MSDN Note: Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed. // You cannot access remote machines when running on these versions of Windows. // http://msdn.microsoft.com/en-us/library/windows/hardware/ff537948%28v=vs.85%29.aspx SafeCmConnectMachineHandle safeMachineHandle; int lastError = NativeMethods.CM_Connect_Machine(Path.LocalToUncCore(Host.GetUncName(hostName), false, false, false), out safeMachineHandle); if (safeMachineHandle.IsInvalid) { safeMachineHandle.Close(); NativeError.ThrowException(lastError, Resources.Handle_Is_Invalid); } using (safeMachineHandle) { // Start at the "Root" of the device tree of the specified machine. if (!callerHandle) { safeHandle = NativeMethods.SetupDiGetClassDevsEx(ref deviceGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.SetupDiGetClassDevsExFlags.Present | NativeMethods.SetupDiGetClassDevsExFlags.DeviceInterface, IntPtr.Zero, hostName, IntPtr.Zero); } if (safeHandle.IsInvalid) { safeHandle.Close(); NativeError.ThrowException(Marshal.GetLastWin32Error(), Resources.Handle_Is_Invalid); } try { uint memberInterfaceIndex = 0; NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = CreateDeviceInterfaceDataInstance(); // Start enumerating Device Interfaces. while (NativeMethods.SetupDiEnumDeviceInterfaces(safeHandle, IntPtr.Zero, ref deviceGuid, memberInterfaceIndex++, ref deviceInterfaceData)) { lastError = Marshal.GetLastWin32Error(); if (lastError != Win32Errors.NO_ERROR) { NativeError.ThrowException(lastError, hostName); } NativeMethods.SP_DEVINFO_DATA deviceInfoData = CreateDeviceInfoDataInstance(); NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = GetDeviceInterfaceDetailDataInstance(safeHandle, deviceInterfaceData, deviceInfoData); // Get device interace details. if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref deviceInterfaceData, ref deviceInterfaceDetailData, NativeMethods.DefaultFileBufferSize, IntPtr.Zero, ref deviceInfoData)) { lastError = Marshal.GetLastWin32Error(); if (lastError != Win32Errors.NO_ERROR) { NativeError.ThrowException(lastError, hostName); } } // Create DeviceInfo instance. // Set DevicePath property of DeviceInfo instance. var deviceInfo = new DeviceInfo(hostName) { DevicePath = deviceInterfaceDetailData.DevicePath }; // Current InstanceId is at the "USBSTOR" level, so we // need up "move up" one level to get to the "USB" level. uint ptrPrevious; // CM_Get_Parent_Ex() // Note: Using this function to access remote machines is not supported // beginning with Windows 8 and Windows Server 2012, as this functionality has been removed. // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538615%28v=vs.85%29.aspx lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, deviceInfoData.DevInst, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } // Now we get the InstanceID of the USB level device. using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { // CM_Get_Device_ID_Ex() // Note: Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012, // as this functionality has been removed. // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538411%28v=vs.85%29.aspx lastError = NativeMethods.CM_Get_Device_ID_Ex(deviceInfoData.DevInst, safeBuffer, (uint)safeBuffer.Capacity, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } // Add to instance. deviceInfo.InstanceId = safeBuffer.PtrToStringUni(); } #region Get Registry Properties using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { uint regType; string dataString; uint safeBufferCapacity = (uint)safeBuffer.Capacity; if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.BaseContainerId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { dataString = safeBuffer.PtrToStringUni(); if (!Utils.IsNullOrWhiteSpace(dataString)) { deviceInfo.BaseContainerId = new Guid(dataString); } } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.ClassGuid, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { dataString = safeBuffer.PtrToStringUni(); if (!Utils.IsNullOrWhiteSpace(dataString)) { deviceInfo.ClassGuid = new Guid(dataString); } } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Class, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.Class = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.CompatibleIds, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.CompatibleIds = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.DeviceDescription, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.DeviceDescription = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Driver, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.Driver = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.EnumeratorName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.EnumeratorName = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.FriendlyName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.FriendlyName = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.HardwareId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.HardwareId = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationInformation, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.LocationInformation = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationPaths, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.LocationPaths = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Manufacturer, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.Manufacturer = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.PhysicalDeviceObjectName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.PhysicalDeviceObjectName = safeBuffer.PtrToStringUni(); } if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Service, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero)) { deviceInfo.Service = safeBuffer.PtrToStringUni(); } } #endregion // Get Registry Properties yield return(deviceInfo); // Get new structure instance. deviceInterfaceData = CreateDeviceInterfaceDataInstance(); } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } } }
internal static IEnumerable <FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoCore(KernelTransaction transaction, SafeFileHandle safeHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); } bool callerHandle = safeHandle != null; if (!callerHandle) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); safeHandle = File.CreateFileCore(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, PathFormat.LongFullPath); } try { if (!NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error(), !continueOnException)) { yield break; } var fileNameOffset = (int)Marshal.OffsetOf(typeof(NativeMethods.FILE_ID_BOTH_DIR_INFO), "FileName"); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { while (true) { if (!NativeMethods.GetFileInformationByHandleEx(safeHandle, NativeMethods.FileInfoByHandleClass.FileIdBothDirectoryInfo, safeBuffer, (uint)safeBuffer.Capacity)) { uint lastError = (uint)Marshal.GetLastWin32Error(); switch (lastError) { case Win32Errors.ERROR_SUCCESS: case Win32Errors.ERROR_NO_MORE_FILES: case Win32Errors.ERROR_HANDLE_EOF: yield break; case Win32Errors.ERROR_MORE_DATA: continue; default: NativeError.ThrowException(lastError, path); yield break; // we should never get to this yield break. } } int offset = 0; NativeMethods.FILE_ID_BOTH_DIR_INFO fibdi; do { fibdi = safeBuffer.PtrToStructure <NativeMethods.FILE_ID_BOTH_DIR_INFO>(offset); string fileName = safeBuffer.PtrToStringUni(offset + fileNameOffset, (int)(fibdi.FileNameLength / 2)); if (!fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) && !fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)) { yield return(new FileIdBothDirectoryInfo(fibdi, fileName)); } offset += fibdi.NextEntryOffset; }while (fibdi.NextEntryOffset != 0); } } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }
public BackupStreamInfo ReadStreamInfo() { using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context)) NativeError.ThrowException(); if (numberOfBytesRead == 0) return null; if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))) throw new IOException(Resources.IncompleteHeaderRead); NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure<NativeMethods.WIN32_STREAM_ID>(); uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity); if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context)) NativeError.ThrowException(); string name = hBuf.PtrToStringUni((int)nameLength / 2); return new BackupStreamInfo(streamID, name); } }