示例#1
0
        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);
            }
        }
示例#2
0
        /// <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));
            }
        }
示例#3
0
        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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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();
            }
        }
示例#6
0
文件: ID3v2.cs 项目: akinomyoga/afh
 /// <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];
                }
            }
        }
示例#9
0
        /// <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);
        }
示例#10
0
        /// <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));
        }
示例#11
0
        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());
            }
        }
示例#12
0
        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));
        }
示例#13
0
 /// <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);
 }
示例#14
0
        /// <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();
        }
示例#15
0
        /// <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);
        }
示例#16
0
        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();
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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();
        }
示例#19
0
        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);
        }
示例#20
0
        /// <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;
                }
            }
示例#21
0
        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);
        }
示例#22
0
        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);
            }
        }