public static void SetCommandText(IntPtr pCmdTextInt, string text) { if (text != null) { OLECMDTEXT olecmdtext = (OLECMDTEXT)Marshal.PtrToStructure(pCmdTextInt, typeof(OLECMDTEXT)); if ((olecmdtext.cmdtextf & (uint)OLECMDTEXTF.OLECMDTEXTF_NAME) == 0) { return; } char[] source = text.ToCharArray(); IntPtr bufferOffset = Marshal.OffsetOf(typeof(OLECMDTEXT), "rgwz"); IntPtr lengthOffset = Marshal.OffsetOf(typeof(OLECMDTEXT), "cwActual"); int length = Math.Min(((int)olecmdtext.cwBuf) - 1, source.Length); // copy the new text long bufferAddress = (long)pCmdTextInt + (long)bufferOffset; Marshal.Copy(source, 0, (IntPtr)bufferAddress, length); // null terminator Marshal.WriteInt16(pCmdTextInt, (int)bufferOffset + (length * 2), 0); // length including null terminator Marshal.WriteInt32(pCmdTextInt, (int)lengthOffset, length + 1); } }
/// <summary>버퍼에 내용을 작성합니다.</summary> /// <param name="Position">작성할 내용의 위치입니다.</param> /// <param name="Buffer">작성할 내용의 버퍼입니다.</param> /// <param name="Offset">버퍼의 위치입니다.</param> /// <param name="Count">작성할 내용의 크기입니다.</param> public void Write(int Position, byte[] Buffer, int Offset, int Count) { if (Length < Position + Count) { SetLength(Position + Count); } int IdxS = Position / BlockSize; int IdxE = GetIndex(Position + Count) - 1; int PosS = Position % BlockSize; if (IdxS == IdxE) { Marshal.Copy(Buffer, Offset, Blocks[IdxS] + PosS, Count); } else { int Size = BlockSize - PosS; Marshal.Copy(Buffer, Offset, Blocks[IdxS] + PosS, Size); Offset += Size; for (int i = IdxS + 1; i < IdxE; i++) { Marshal.Copy(Buffer, Offset, Blocks[i], BlockSize); Offset += BlockSize; } Marshal.Copy(Buffer, Offset, Blocks[IdxE], GetLast(Position + Count)); } }
public override ResourceData GetResourceData(ResourceLang lang) { if (lang.Name.Type.Source != this) { throw new ArgumentException("The specified ResourceLang does not exist in this ResourceSource"); } // TODO: Check that ResourceLang refers to a Resource that actually does exist in this resource and is not a pending add operation // use FindResourceEx and LoadResource to get a handle to the resource // use SizeOfResource to get the length of the byte array // then LockResource to get a pointer to it. Use Marshal to get a byte array and take it from there IntPtr resInfo = NativeMethods.FindResourceEx(_moduleHandle, lang.Name.Type.Identifier.NativeId, lang.Name.Identifier.NativeId, lang.LanguageId); IntPtr resData = NativeMethods.LoadResource(_moduleHandle, resInfo); Int32 size = NativeMethods.SizeOfResource(_moduleHandle, resInfo); if (resData == IntPtr.Zero) { return(null); } IntPtr resPtr = NativeMethods.LockResource(resData); // there is no method to unlock resources, but they should be freed anyway Byte[] data = new Byte[size]; Marshal.Copy(resPtr, data, 0, size); NativeMethods.FreeResource(resData); ResourceData retval = ResourceData.FromResource(lang, data); return(retval); }
/// <summary>버퍼의 내용을 읽습니다.</summary> /// <param name="Position">읽어들일 내용의 위치입니다.</param> /// <param name="Buffer">내용을 읽어들일 버퍼입니다.</param> /// <param name="Offset">버퍼의 위치입니다.</param> /// <param name="Count">읽어들일 내용의 크기입니다.</param> /// <returns>읽어들인 내용의 크기입니다.</returns> public int Read(int Position, byte[] Buffer, int Offset, int Count) { if (Length < Position + Count) { Count = Length - Position; } int IdxS = Position / BlockSize; int IdxE = GetIndex(Position + Count) - 1; int PosS = Position % BlockSize; if (IdxS == IdxE) { Marshal.Copy(Blocks[IdxS] + PosS, Buffer, Offset, Count); } else { int Size = BlockSize - PosS; Marshal.Copy(Blocks[IdxS] + PosS, Buffer, Offset, Size); Offset += Size; for (int i = IdxS + 1; i < IdxE; i++) { Marshal.Copy(Blocks[i], Buffer, Offset, BlockSize); Offset += BlockSize; } Marshal.Copy(Blocks[IdxE], Buffer, Offset, GetLast(Position + Count)); } return(Count); }
public override void CommitChanges() { if (IsReadOnly) { throw new InvalidOperationException("Changes cannot be commited because the current ResourceSource is read-only"); } // Unload self if (LoadMode > 0) { Unload(); } IntPtr updateHandle = NativeMethods.BeginUpdateResource(_path, false); foreach (ResourceLang lang in AllActiveLangs) { IntPtr pData; Int32 length; if (lang.Action == ResourceDataAction.Delete) { // pData must be NULL to delete resource pData = IntPtr.Zero; length = 0; } else { if (!lang.DataIsLoaded) { throw new AnolisException("Cannot perform action when ResourceData is not loaded"); } length = lang.Data.RawData.Length; pData = Marshal.AllocHGlobal(length); Marshal.Copy(lang.Data.RawData, 0, pData, length); } IntPtr typeId = lang.Name.Type.Identifier.NativeId; IntPtr nameId = lang.Name.Identifier.NativeId; ushort langId = lang.LanguageId; NativeMethods.UpdateResource(updateHandle, typeId, nameId, langId, pData, length); Marshal.FreeHGlobal(pData); lang.Action = ResourceDataAction.None; } NativeMethods.EndUpdateResource(updateHandle, false); if (LoadMode > 0) { Reload(); } }
/// <summary> /// 構造体を Stream に書き込みます。動作確認済み。 /// </summary> /// <param name="structure">書き込む構造体を指定します。</param> /// <param name="strlen">構造体の長さを指定します。</param> /// <param name="copylen">書き込む長さを指定します。</param> private void WriteStructure(System.ValueType structure, int strlen, int copylen) { System.IntPtr buff = Marshal.AllocHGlobal(strlen); try{ byte[] data = new byte[copylen]; Marshal.StructureToPtr(structure, buff, false); Marshal.Copy(buff, data, 0, strlen); str.Write(data, 0, copylen); }finally{ Marshal.FreeHGlobal(buff); } }
public Vector4 GetPoint(IntPtr pointCloudHandle, int index) { IntPtr pointCloudNativeHandle = IntPtr.Zero; ExternApi.ArPointCloud_getData(m_NativeSession.SessionHandle, pointCloudHandle, ref pointCloudNativeHandle); IntPtr pointHandle = new IntPtr(pointCloudNativeHandle.ToInt64() + (Marshal.SizeOf(typeof(Vector4)) * index)); Marshal.Copy(pointHandle, m_CachedVector, 0, 4); // Negate z axis because points are returned in OpenGl space. return(new Vector4(m_CachedVector[0], m_CachedVector[1], -m_CachedVector[2], m_CachedVector[3])); }
private static void MarshalAndCopy(IntPtr matPtr, ref Matrix4x4 mat) { float[] matMarshalled = new float[16]; Marshal.Copy(matPtr, matMarshalled, 0, 16); // fill matrix for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { mat[j, i] = matMarshalled[i * 4 + j]; } } }
/// <summary>스트림에 버퍼의 내용을 작성합니다.</summary> /// <param name="Stream">버퍼의 내용을 작성할 스트림입니다.</param> public void WriteTo(Stream Stream) { var Buffer = new byte[BlockSize]; int Size = GetLast(BufferLength); int Last = Blocks.Count - 1; for (int i = 0; i < Last; i++) { Marshal.Copy(Blocks[i], Buffer, 0, BlockSize); Stream.Write(Buffer, 0, BlockSize); } Marshal.Copy(Blocks[Last], Buffer, 0, Size); Stream.Write(Buffer, 0, Size); }
/// <summary> /// Read an array of bytes verbatim /// </summary> /// <param name="count">Number of bytes to read</param> /// <exception cref="EndOfStreamException"/> public ArraySegment <byte> ReadBytes(int count) { if (position > end - count) { EndOfStream(count); } byte[] result = new byte[count]; RMarshal.Copy((IntPtr)(buffer + position), result, 0, count); position += count; return(new ArraySegment <byte>(result)); }
private void CommitChangesImpl() { IntPtr updateHandle = NativeMethods.BeginUpdateResource(FileInfo.FullName, false); foreach (ResourceLang lang in AllActiveLangs) { IntPtr pData; Int32 length; if (lang.Action == ResourceDataAction.Delete) { // pData must be NULL to delete resource pData = IntPtr.Zero; length = 0; } else { if (!lang.DataIsLoaded) { throw new AnolisException("Cannot perform action when ResourceData is not loaded"); } length = lang.Data.RawData.Length; pData = Marshal.AllocHGlobal(length); Marshal.Copy(lang.Data.RawData, 0, pData, length); } IntPtr typeId = lang.Name.Type.Identifier.NativeId; IntPtr nameId = lang.Name.Identifier.NativeId; ushort langId = lang.LanguageId; Boolean uSuccess = NativeMethods.UpdateResource(updateHandle, typeId, nameId, langId, pData, length); if (!uSuccess) { throw new AnolisException("UpdatedResource failed: " + NativeMethods.GetLastErrorString()); } Marshal.FreeHGlobal(pData); lang.Action = ResourceDataAction.None; } Boolean success = NativeMethods.EndUpdateResource(updateHandle, false); if (!success) { throw new AnolisException("EndUpdateResource failed: " + NativeMethods.GetLastErrorString()); } }
public PointCloudPoint GetPoint(IntPtr pointCloudHandle, int index) { // Get a reference to the pointcloud data to extract position and condfidence of point at index. IntPtr pointCloudDataHandle = IntPtr.Zero; ExternApi.ArPointCloud_getData(m_NativeSession.SessionHandle, pointCloudHandle, ref pointCloudDataHandle); IntPtr pointDataHandle = new IntPtr(pointCloudDataHandle.ToInt64() + (Marshal.SizeOf(typeof(Vector4)) * index)); Marshal.Copy(pointDataHandle, m_CachedVector, 0, 4); // Negate z axis because points are returned in OpenGl space. Vector3 position = new Vector3(m_CachedVector[0], m_CachedVector[1], -m_CachedVector[2]); float confidence = m_CachedVector[3]; return(new PointCloudPoint(_GetPointId(pointCloudHandle, index), position, confidence)); }
/// <summary> /// Provides a callback method for the EnumerateMetafile method. /// </summary> /// <param name="recordType">Member of the EmfPlusRecordType enumeration that specifies the type of metafile record.</param> /// <param name="flags">Set of flags that specify attributes of the record.</param> /// <param name="dataSize">Number of bytes in the record data.</param> /// <param name="data">Pointer to a buffer that contains the record data.</param> /// <param name="callbackData">Not used.</param> /// <returns></returns> private bool MetafileCallback(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData) { byte[] dataArray = null; if (data != IntPtr.Zero) { // 将 data 所对应的内存指针所对应的数据从内存中复制出来 // Copy the unmanaged record to a managed byte buffer // that can be used by PlayRecord. dataArray = new byte[dataSize]; // Copies data from a managed array to an unmanaged memory pointer, or from an unmanaged memory pointer to a managed array. SysMarshal.Copy(data, dataArray, 0, dataSize); } // 将 矢量图中的这一个小图元显示在 pictureBox1 的绘图面板 Graphics 中 metafile1.PlayRecord(recordType, flags, dataSize, dataArray); // Plays an individual metafile record. return(true); }
/// <summary> /// Invoked when the GameScreen should be rendered. When called, the AGI screen data in /// the Pixels is rendered within the PictureBox. /// </summary> public void Render() { if (Monitor.TryEnter(screenBitmap)) { try { // Copy the pixel data in to the screen Bitmap. var bitmapData = screenBitmap.LockBits(new Rectangle(0, 0, screenBitmap.Width, screenBitmap.Height), ImageLockMode.ReadWrite, screenBitmap.PixelFormat); Marshal.Copy(Pixels, 0, bitmapData.Scan0, Pixels.Length); screenBitmap.UnlockBits(bitmapData); } finally { Monitor.Exit(screenBitmap); } } // Request the PictureBox to be redrawn. this.Invalidate(); }
/// <summary>스트림으로부터 새 버퍼를 생성합니다.</summary> /// <param name="Stream">버퍼를 생성할 스트림입니다.</param> /// <param name="Length">스트림으로부터 읽어들일 크기입니다.</param> /// <param name="Size">버퍼의 블록 크기입니다.</param> public SBuffer(Stream Stream, int Length, int Block = DefaultSize) : this(Block) { var Buffer = new byte[BlockSize]; int Read = BlockSize; do { if (Length < BlockSize) { Read = Length; } if ((Read = Stream.Read(Buffer, 0, Read)) == 0) { return; } var Ptr = Alloc(); Marshal.Copy(Buffer, 0, Ptr, Read); Blocks.Add(Ptr); BufferLength += Read; } while(Read == BlockSize); }
private void DrawScreen() { this.Text = string.Format("{0}/{1}", curFrame, frameCount); var bitmapData = bitmap.LockBits(new Rectangle(0, 0, 320, 200), ImageLockMode.ReadOnly, bitmap.PixelFormat); Marshal.Copy(screen, 0, bitmapData.Scan0, 320 * 200); bitmap.UnlockBits(bitmapData); this.Invalidate(); //skip saving first frame, it'd be black. if (curFrame == 0) { return; } if (!string.IsNullOrEmpty(outputFile)) { bitmap.SaveEx(outputFile); outputFile = outputFile.IncreaseSequence(); } }
public void GetPixels(Bitmap from) { if (data == null) { data = new byte[320 * 200]; //We *could* allow different sizes now... } if (palette == null) { palette = new byte[256 * 3]; } var victim = from; if (victim.PixelFormat != PixelFormat.Format8bppIndexed) { throw new FormatException("Input images can only be in 256 color format."); } if (victim.Width != 320 || victim.Height != 200) { throw new FormatException("Input images can only be 320 by 200 pixels in size."); } if (palette != null) { for (var i = 0; i < victim.Palette.Entries.Length; i++) { var color = victim.Palette.Entries[i]; palette[i * 3 + 0] = color.R; palette[i * 3 + 1] = color.G; palette[i * 3 + 2] = color.B; } } var bitmapData = victim.LockBits(new Rectangle(0, 0, victim.Width, victim.Height), ImageLockMode.ReadOnly, victim.PixelFormat); Marshal.Copy(bitmapData.Scan0, data, 0, 320 * 200); victim.UnlockBits(bitmapData); }
public void Draw() { var lockData = backBuffer.LockBits(new System.Drawing.Rectangle(0, 0, backBuffer.Width, backBuffer.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); var size = lockData.Stride * lockData.Height; var scan0 = new byte[size]; Marshal.Copy(lockData.Scan0, scan0, 0, size); for (int row = 0; row < Program.Rows; row++) { for (int col = 0; col < Program.Cols; col++) { var here = image[col, row]; if (here != previousImage[col, row]) { DrawCell(scan0, lockData.Stride, row, col, here); previousImage[col, row].CopyFrom(here); } } } Marshal.Copy(scan0, 0, lockData.Scan0, size); backBuffer.UnlockBits(lockData); Frames++; this.Refresh(); }
internal static DeviceInfo[] GetList() { List <string> deviceIDs = new List <string>(); try { var mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); ManagementObjectCollection objCol = mgmtObjSearcher.Get(); deviceIDs.AddRange(from ManagementObject drive in objCol select(string) drive["DeviceID"]); mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_TapeDrive"); objCol = mgmtObjSearcher.Get(); deviceIDs.AddRange(from ManagementObject drive in objCol select(string) drive["DeviceID"]); mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive"); objCol = mgmtObjSearcher.Get(); deviceIDs.AddRange(from ManagementObject drive in objCol select(string) drive["Drive"]); } catch (Exception) { #if DEBUG throw; #else return(null); #endif } List <DeviceInfo> devList = new List <DeviceInfo>(); foreach (string devId in deviceIDs) { if (devId is null) { continue; } string physId = devId; // TODO: This can be done better if (devId.Length == 2 && devId[1] == ':') { physId = "\\\\?\\" + devId; } SafeFileHandle fd = Extern.CreateFile(physId, 0, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.OpenExisting, 0, IntPtr.Zero); if (fd.IsInvalid) { continue; } var query = new StoragePropertyQuery { PropertyId = StoragePropertyId.Device, QueryType = StorageQueryType.Standard, AdditionalParameters = new byte[1] }; //StorageDeviceDescriptor descriptor = new StorageDeviceDescriptor(); //descriptor.RawDeviceProperties = new byte[16384]; IntPtr descriptorPtr = Marshal.AllocHGlobal(1000); byte[] descriptorB = new byte[1000]; uint returned = 0; int error = 0; bool hasError = !Extern.DeviceIoControlStorageQuery(fd, WindowsIoctl.IoctlStorageQueryProperty, ref query, (uint)Marshal.SizeOf(query), descriptorPtr, 1000, ref returned, IntPtr.Zero); if (hasError) { error = Marshal.GetLastWin32Error(); } Marshal.Copy(descriptorPtr, descriptorB, 0, 1000); if (hasError && error != 0) { continue; } var descriptor = new StorageDeviceDescriptor { Version = BitConverter.ToUInt32(descriptorB, 0), Size = BitConverter.ToUInt32(descriptorB, 4), DeviceType = descriptorB[8], DeviceTypeModifier = descriptorB[9], RemovableMedia = BitConverter.ToBoolean(descriptorB, 10), CommandQueueing = BitConverter.ToBoolean(descriptorB, 11), VendorIdOffset = BitConverter.ToInt32(descriptorB, 12), ProductIdOffset = BitConverter.ToInt32(descriptorB, 16), ProductRevisionOffset = BitConverter.ToInt32(descriptorB, 20), SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24), BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28), RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32) }; var info = new DeviceInfo { Path = physId, Bus = descriptor.BusType.ToString() }; if (descriptor.VendorIdOffset > 0) { info.Vendor = StringHandlers.CToString(descriptorB, Encoding.ASCII, start: descriptor.VendorIdOffset); } if (descriptor.ProductIdOffset > 0) { info.Model = StringHandlers.CToString(descriptorB, Encoding.ASCII, start: descriptor.ProductIdOffset); } // TODO: Get serial number of SCSI and USB devices, probably also FireWire (untested) if (descriptor.SerialNumberOffset > 0) { info.Serial = StringHandlers.CToString(descriptorB, Encoding.ASCII, start: descriptor.SerialNumberOffset); // fix any serial numbers that are returned as hex-strings if (Array.TrueForAll(info.Serial.ToCharArray(), c => "0123456789abcdef".IndexOf(c) >= 0) && info.Serial.Length == 40) { info.Serial = HexStringToString(info.Serial).Trim(); } } if (string.IsNullOrEmpty(info.Vendor) || info.Vendor == "ATA") { string[] pieces = info.Model?.Split(' '); if (pieces?.Length > 1) { info.Vendor = pieces[0]; info.Model = info.Model.Substring(pieces[0].Length + 1); } } switch (descriptor.BusType) { case StorageBusType.SCSI: case StorageBusType.ATAPI: case StorageBusType.ATA: case StorageBusType.FireWire: case StorageBusType.SSA: case StorageBusType.Fibre: case StorageBusType.USB: case StorageBusType.iSCSI: case StorageBusType.SAS: case StorageBusType.SATA: case StorageBusType.SecureDigital: case StorageBusType.MultiMediaCard: info.Supported = true; break; } Marshal.FreeHGlobal(descriptorPtr); devList.Add(info); } DeviceInfo[] devices = devList.ToArray(); return(devices); }
/// <summary>Opens the device for sending direct commands</summary> /// <param name="devicePath">Device path</param> public Device(string devicePath) { PlatformId = DetectOS.GetRealPlatformID(); Timeout = 15; Error = false; IsRemovable = false; if (devicePath.StartsWith("dic://", StringComparison.OrdinalIgnoreCase) || devicePath.StartsWith("aaru://", StringComparison.OrdinalIgnoreCase)) { devicePath = devicePath.Substring(devicePath.StartsWith("dic://", StringComparison.OrdinalIgnoreCase) ? 6 : 7); string[] pieces = devicePath.Split('/'); string host = pieces[0]; devicePath = devicePath.Substring(host.Length); _remote = new Remote.Remote(host); Error = !_remote.Open(devicePath, out int errno); LastError = errno; } else { switch (PlatformId) { case PlatformID.Win32NT: { FileHandle = Extern.CreateFile(devicePath, FileAccess.GenericRead | FileAccess.GenericWrite, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.OpenExisting, FileAttributes.Normal, IntPtr.Zero); if (((SafeFileHandle)FileHandle).IsInvalid) { Error = true; LastError = Marshal.GetLastWin32Error(); } break; } case PlatformID.Linux: { FileHandle = Linux.Extern.open(devicePath, FileFlags.ReadWrite | FileFlags.NonBlocking | FileFlags.CreateNew); if ((int)FileHandle < 0) { LastError = Marshal.GetLastWin32Error(); if (LastError == 13 || LastError == 30) // EACCES or EROFS { FileHandle = Linux.Extern.open(devicePath, FileFlags.Readonly | FileFlags.NonBlocking); if ((int)FileHandle < 0) { Error = true; LastError = Marshal.GetLastWin32Error(); } } else { Error = true; } LastError = Marshal.GetLastWin32Error(); } break; } case PlatformID.FreeBSD: { FileHandle = FreeBSD.Extern.cam_open_device(devicePath, FreeBSD.FileFlags.ReadWrite); if (((IntPtr)FileHandle).ToInt64() == 0) { Error = true; LastError = Marshal.GetLastWin32Error(); } var camDevice = (CamDevice)Marshal.PtrToStructure((IntPtr)FileHandle, typeof(CamDevice)); if (StringHandlers.CToString(camDevice.SimName) == "ata") { throw new DeviceException("Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250."); } break; } default: throw new DeviceException($"Platform {PlatformId} not yet supported."); } } if (Error) { throw new DeviceException(LastError); } Type = DeviceType.Unknown; ScsiType = PeripheralDeviceTypes.UnknownDevice; byte[] ataBuf; byte[] inqBuf = null; if (Error) { throw new DeviceException(LastError); } bool scsiSense = true; if (_remote is null) { // Windows is answering SCSI INQUIRY for all device types so it needs to be detected first switch (PlatformId) { case PlatformID.Win32NT: var query = new StoragePropertyQuery(); query.PropertyId = StoragePropertyId.Device; query.QueryType = StorageQueryType.Standard; query.AdditionalParameters = new byte[1]; IntPtr descriptorPtr = Marshal.AllocHGlobal(1000); byte[] descriptorB = new byte[1000]; uint returned = 0; int error = 0; bool hasError = !Extern.DeviceIoControlStorageQuery((SafeFileHandle)FileHandle, WindowsIoctl.IoctlStorageQueryProperty, ref query, (uint)Marshal.SizeOf(query), descriptorPtr, 1000, ref returned, IntPtr.Zero); if (hasError) { error = Marshal.GetLastWin32Error(); } Marshal.Copy(descriptorPtr, descriptorB, 0, 1000); if (!hasError && error == 0) { var descriptor = new StorageDeviceDescriptor { Version = BitConverter.ToUInt32(descriptorB, 0), Size = BitConverter.ToUInt32(descriptorB, 4), DeviceType = descriptorB[8], DeviceTypeModifier = descriptorB[9], RemovableMedia = descriptorB[10] > 0, CommandQueueing = descriptorB[11] > 0, VendorIdOffset = BitConverter.ToInt32(descriptorB, 12), ProductIdOffset = BitConverter.ToInt32(descriptorB, 16), ProductRevisionOffset = BitConverter.ToInt32(descriptorB, 20), SerialNumberOffset = BitConverter.ToInt32(descriptorB, 24), BusType = (StorageBusType)BitConverter.ToUInt32(descriptorB, 28), RawPropertiesLength = BitConverter.ToUInt32(descriptorB, 32) }; descriptor.RawDeviceProperties = new byte[descriptor.RawPropertiesLength]; Array.Copy(descriptorB, 36, descriptor.RawDeviceProperties, 0, descriptor.RawPropertiesLength); switch (descriptor.BusType) { case StorageBusType.SCSI: case StorageBusType.SSA: case StorageBusType.Fibre: case StorageBusType.iSCSI: case StorageBusType.SAS: Type = DeviceType.SCSI; break; case StorageBusType.FireWire: IsFireWire = true; Type = DeviceType.SCSI; break; case StorageBusType.USB: IsUsb = true; Type = DeviceType.SCSI; break; case StorageBusType.ATAPI: Type = DeviceType.ATAPI; break; case StorageBusType.ATA: case StorageBusType.SATA: Type = DeviceType.ATA; break; case StorageBusType.MultiMediaCard: Type = DeviceType.MMC; break; case StorageBusType.SecureDigital: Type = DeviceType.SecureDigital; break; case StorageBusType.NVMe: Type = DeviceType.NVMe; break; } switch (Type) { case DeviceType.SCSI: case DeviceType.ATAPI: scsiSense = ScsiInquiry(out inqBuf, out _); break; case DeviceType.ATA: bool atapiSense = AtapiIdentify(out ataBuf, out _); if (!atapiSense) { Type = DeviceType.ATAPI; Identify.IdentifyDevice?ataid = Identify.Decode(ataBuf); if (ataid.HasValue) { scsiSense = ScsiInquiry(out inqBuf, out _); } } else { Manufacturer = "ATA"; } break; } } Marshal.FreeHGlobal(descriptorPtr); if (Windows.Command.IsSdhci((SafeFileHandle)FileHandle)) { byte[] sdBuffer = new byte[16]; LastError = Windows.Command.SendMmcCommand((SafeFileHandle)FileHandle, MmcCommands.SendCsd, false, false, MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0, 16, 1, ref sdBuffer, out _, out _, out bool sense); if (!sense) { _cachedCsd = new byte[16]; Array.Copy(sdBuffer, 0, _cachedCsd, 0, 16); } sdBuffer = new byte[16]; LastError = Windows.Command.SendMmcCommand((SafeFileHandle)FileHandle, MmcCommands.SendCid, false, false, MmcFlags.ResponseSpiR2 | MmcFlags.ResponseR2 | MmcFlags.CommandAc, 0, 16, 1, ref sdBuffer, out _, out _, out sense); if (!sense) { _cachedCid = new byte[16]; Array.Copy(sdBuffer, 0, _cachedCid, 0, 16); } sdBuffer = new byte[8]; LastError = Windows.Command.SendMmcCommand((SafeFileHandle)FileHandle, (MmcCommands)SecureDigitalCommands.SendScr, false, true, MmcFlags.ResponseSpiR1 | MmcFlags.ResponseR1 | MmcFlags.CommandAdtc, 0, 8, 1, ref sdBuffer, out _, out _, out sense); if (!sense) { _cachedScr = new byte[8]; Array.Copy(sdBuffer, 0, _cachedScr, 0, 8); } sdBuffer = new byte[4]; LastError = Windows.Command.SendMmcCommand((SafeFileHandle)FileHandle, _cachedScr != null ? (MmcCommands)SecureDigitalCommands. SendOperatingCondition : MmcCommands.SendOpCond, false, true, MmcFlags.ResponseSpiR3 | MmcFlags.ResponseR3 | MmcFlags.CommandBcr, 0, 4, 1, ref sdBuffer, out _, out _, out sense); if (!sense) { _cachedScr = new byte[4]; Array.Copy(sdBuffer, 0, _cachedScr, 0, 4); } } break; case PlatformID.Linux: if (devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sg", StringComparison.Ordinal)) { scsiSense = ScsiInquiry(out inqBuf, out _); } // MultiMediaCard and SecureDigital go here else if (devicePath.StartsWith("/dev/mmcblk", StringComparison.Ordinal)) { string devPath = devicePath.Substring(5); if (File.Exists("/sys/block/" + devPath + "/device/csd")) { int len = ConvertFromHexAscii("/sys/block/" + devPath + "/device/csd", out _cachedCsd); if (len == 0) { _cachedCsd = null; } } if (File.Exists("/sys/block/" + devPath + "/device/cid")) { int len = ConvertFromHexAscii("/sys/block/" + devPath + "/device/cid", out _cachedCid); if (len == 0) { _cachedCid = null; } } if (File.Exists("/sys/block/" + devPath + "/device/scr")) { int len = ConvertFromHexAscii("/sys/block/" + devPath + "/device/scr", out _cachedScr); if (len == 0) { _cachedScr = null; } } if (File.Exists("/sys/block/" + devPath + "/device/ocr")) { int len = ConvertFromHexAscii("/sys/block/" + devPath + "/device/ocr", out _cachedOcr); if (len == 0) { _cachedOcr = null; } } } break; default: scsiSense = ScsiInquiry(out inqBuf, out _); break; } } else { Type = _remote.GetDeviceType(); switch (Type) { case DeviceType.ATAPI: case DeviceType.SCSI: scsiSense = ScsiInquiry(out inqBuf, out _); break; case DeviceType.SecureDigital: case DeviceType.MMC: if (!_remote.GetSdhciRegisters(out _cachedCsd, out _cachedCid, out _cachedOcr, out _cachedScr)) { Type = DeviceType.SCSI; ScsiType = PeripheralDeviceTypes.DirectAccess; } break; } } #region SecureDigital / MultiMediaCard if (_cachedCid != null) { ScsiType = PeripheralDeviceTypes.DirectAccess; IsRemovable = false; if (_cachedScr != null) { Type = DeviceType.SecureDigital; CID decoded = Decoders.SecureDigital.Decoders.DecodeCID(_cachedCid); Manufacturer = VendorString.Prettify(decoded.Manufacturer); Model = decoded.ProductName; FirmwareRevision = $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; Serial = $"{decoded.ProductSerialNumber}"; } else { Type = DeviceType.MMC; Decoders.MMC.CID decoded = Decoders.MMC.Decoders.DecodeCID(_cachedCid); Manufacturer = Decoders.MMC.VendorString.Prettify(decoded.Manufacturer); Model = decoded.ProductName; FirmwareRevision = $"{(decoded.ProductRevision & 0xF0) >> 4:X2}.{decoded.ProductRevision & 0x0F:X2}"; Serial = $"{decoded.ProductSerialNumber}"; } return; } #endregion SecureDigital / MultiMediaCard #region USB if (_remote is null) { switch (PlatformId) { case PlatformID.Linux: if (devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal)) { string devPath = devicePath.Substring(5); if (Directory.Exists("/sys/block/" + devPath)) { string resolvedLink = Linux.Command.ReadLink("/sys/block/" + devPath); if (!string.IsNullOrEmpty(resolvedLink)) { resolvedLink = "/sys" + resolvedLink.Substring(2); while (resolvedLink.Contains("usb")) { resolvedLink = Path.GetDirectoryName(resolvedLink); if (!File.Exists(resolvedLink + "/descriptors") || !File.Exists(resolvedLink + "/idProduct") || !File.Exists(resolvedLink + "/idVendor")) { continue; } var usbFs = new FileStream(resolvedLink + "/descriptors", System.IO.FileMode.Open, System.IO.FileAccess.Read); byte[] usbBuf = new byte[65536]; int usbCount = usbFs.Read(usbBuf, 0, 65536); UsbDescriptors = new byte[usbCount]; Array.Copy(usbBuf, 0, UsbDescriptors, 0, usbCount); usbFs.Close(); var usbSr = new StreamReader(resolvedLink + "/idProduct"); string usbTemp = usbSr.ReadToEnd(); ushort.TryParse(usbTemp, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _usbProduct); usbSr.Close(); usbSr = new StreamReader(resolvedLink + "/idVendor"); usbTemp = usbSr.ReadToEnd(); ushort.TryParse(usbTemp, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _usbVendor); usbSr.Close(); if (File.Exists(resolvedLink + "/manufacturer")) { usbSr = new StreamReader(resolvedLink + "/manufacturer"); UsbManufacturerString = usbSr.ReadToEnd().Trim(); usbSr.Close(); } if (File.Exists(resolvedLink + "/product")) { usbSr = new StreamReader(resolvedLink + "/product"); UsbProductString = usbSr.ReadToEnd().Trim(); usbSr.Close(); } if (File.Exists(resolvedLink + "/serial")) { usbSr = new StreamReader(resolvedLink + "/serial"); UsbSerialString = usbSr.ReadToEnd().Trim(); usbSr.Close(); } IsUsb = true; break; } } } } break; case PlatformID.Win32NT: Usb.UsbDevice usbDevice = null; // I have to search for USB disks, floppies and CD-ROMs as separate device types foreach (string devGuid in new[] { Usb.GuidDevinterfaceFloppy, Usb.GuidDevinterfaceCdrom, Usb.GuidDevinterfaceDisk, Usb.GuidDevinterfaceTape }) { usbDevice = Usb.FindDrivePath(devicePath, devGuid); if (usbDevice != null) { break; } } if (usbDevice != null) { UsbDescriptors = usbDevice.BinaryDescriptors; _usbVendor = (ushort)usbDevice.DeviceDescriptor.idVendor; _usbProduct = (ushort)usbDevice.DeviceDescriptor.idProduct; UsbManufacturerString = usbDevice.Manufacturer; UsbProductString = usbDevice.Product; UsbSerialString = usbDevice. SerialNumber; // This is incorrect filled by Windows with SCSI/ATA serial number } break; default: IsUsb = false; break; } } else { if (_remote.GetUsbData(out byte[] remoteUsbDescriptors, out ushort remoteUsbVendor, out ushort remoteUsbProduct, out string remoteUsbManufacturer, out string remoteUsbProductString, out string remoteUsbSerial)) { IsUsb = true; UsbDescriptors = remoteUsbDescriptors; _usbVendor = remoteUsbVendor; _usbProduct = remoteUsbProduct; UsbManufacturerString = remoteUsbManufacturer; UsbProductString = remoteUsbProductString; UsbSerialString = remoteUsbSerial; } } #endregion USB #region FireWire if (!(_remote is null)) { if (_remote.GetFireWireData(out _firewireVendor, out _firewireModel, out _firewireGuid, out string remoteFireWireVendorName, out string remoteFireWireModelName)) { IsFireWire = true; FireWireVendorName = remoteFireWireVendorName; FireWireModelName = remoteFireWireModelName; } }
static void Main(string[] args) { if (args.Length == 0) { return; } if (!File.Exists(args[0])) { Console.WriteLine("Input file {0} does not exist.", args[0]); return; } var file = new BinaryReader(File.OpenRead(args[0])); var magic = new string(file.ReadChars(4)); if (magic != "AIMG") { MessageBox.Show("Input file is not a valid Asspull IIIx image."); return; } //TODO: more checks? var depth = file.ReadByte(); var compressed = file.ReadByte() == 1; var width = file.ReadMotoUInt16(); var height = file.ReadMotoUInt16(); var stride = file.ReadMotoUInt16(); var palSize = (depth == 8) ? 256 : 16; var dataSize = file.ReadMotoUInt32(); var palOffset = file.ReadMotoUInt32(); var dataOffset = file.ReadMotoUInt32(); var bitmap = new Bitmap(width, height, (depth == 8) ? PixelFormat.Format8bppIndexed : PixelFormat.Format4bppIndexed); var palette = bitmap.Palette; file.BaseStream.Seek(palOffset, SeekOrigin.Begin); for (var i = 0; i < palSize; i++) { var snes = file.ReadMotoUInt16(); var r = (snes >> 0) & 0x1F; var g = (snes >> 5) & 0x1F; var b = (snes >> 10) & 0x1F; palette.Entries[i] = Color.FromArgb((r << 3) + (r >> 2), (g << 3) + (g >> 2), (b << 3) + (b >> 2)); } bitmap.Palette = palette; file.BaseStream.Seek(dataOffset, SeekOrigin.Begin); var screen = new byte[width * height]; var pos = 0; if (compressed) { while (file.BaseStream.Position < file.BaseStream.Length) { var data = file.ReadByte(); if ((data & 0xC0) == 0xC0) { var rle = data & 0x3F; var original = data; var from = file.BaseStream.Position - 1; data = file.ReadByte(); if (data == 0xC0 && rle == 0) { break; } for (; rle > 0; rle--) { screen[pos++] = data; } } else { screen[pos++] = data; } } } else { //TODO: check this, I only have compressed images right now. screen = file.ReadBytes((int)dataSize); } if (depth == 4) { for (var i = 0; i < width * height; i++) { var a = (screen[i] >> 0) & 0x0F; var b = (screen[i] >> 4) & 0x0F; screen[i] = (byte)(b | (a << 4)); } } var bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); Marshal.Copy(screen, 0, bitmapData.Scan0, (width * height) / ((depth == 8) ? 1 : 2)); var form = new Form() { ClientSize = new Size(width, height), BackgroundImage = bitmap, Text = Path.GetFileNameWithoutExtension(args[0]) }; Application.Run(form); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Use: img2ass <input.png> [<output.api>] [-raw]"); Console.WriteLine("Specify -raw to skip compression."); return; } var inFile = args[0]; var outFile = Path.ChangeExtension(inFile, ".api"); var compress = true; if (args.Length > 1) { if (args[1] == "-raw") { compress = false; } else { outFile = args[1]; if (args.Length > 2 && args[2] == "-raw") { compress = false; } } } if (inFile.EndsWith(".api", StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("You must've accidentally passed the wrong file. Kawa shares your pain."); inFile = Path.ChangeExtension(inFile, ".png"); } if (!File.Exists(inFile)) { Console.WriteLine("Input file {0} does not exist.", inFile); return; } var inBitmap = new Bitmap(inFile); if (inBitmap.PixelFormat != PixelFormat.Format8bppIndexed && inBitmap.PixelFormat != PixelFormat.Format4bppIndexed) { Console.WriteLine("Image is not indexed."); return; } var inPal = inBitmap.Palette.Entries; var outPal = new short[inPal.Length]; for (var i = 0; i < inPal.Length; i++) { var r = inPal[i].R; var g = inPal[i].G; var b = inPal[i].B; var snes = ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3); outPal[i] = (short)snes; } var size = inBitmap.Width * inBitmap.Height; if (inBitmap.PixelFormat == PixelFormat.Format4bppIndexed) { size /= 2; } var outData = new byte[size]; var bitmapData = inBitmap.LockBits(new Rectangle(0, 0, inBitmap.Width, inBitmap.Height), ImageLockMode.ReadOnly, inBitmap.PixelFormat); var stride = bitmapData.Stride; Marshal.Copy(bitmapData.Scan0, outData, 0, size); inBitmap.UnlockBits(bitmapData); if (inBitmap.PixelFormat == PixelFormat.Format4bppIndexed) { for (var i = 0; i < size; i++) { var a = (outData[i] >> 0) & 0x0F; var b = (outData[i] >> 4) & 0x0F; outData[i] = (byte)(b | (a << 4)); } } if (compress) { var compressed = outData.RleCompress(); if (compressed.Length < outData.Length) { outData = compressed; } else { compress = false; } } using (var f = new BinaryWriter(File.Open(outFile, FileMode.Create))) { f.Write("AIMG".ToCharArray()); f.Write((byte)(inBitmap.PixelFormat == PixelFormat.Format8bppIndexed ? 8 : 4)); f.Write((byte)(compress ? 1 : 0)); f.WriteMoto((ushort)inBitmap.Width); f.WriteMoto((ushort)inBitmap.Height); f.WriteMoto((ushort)stride); f.WriteMoto((uint)outData.Length); //size); f.WriteMoto((uint)0x18); f.WriteMoto((uint)(0x18 + (outPal.Length * 2))); for (var i = 0; i < outPal.Length; i++) { f.WriteMoto(outPal[i]); } f.Write(outData, 0, outData.Length); } }