<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Патч файла]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=3207</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=3207&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Патч файла».]]></description>
		<lastBuildDate>Mon, 25 May 2009 03:42:51 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[AHK: Патч файла]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=23640#p23640</link>
			<description><![CDATA[<p>Функция FilePatch в примере ниже пишет данные в указанное место уже существующего файла (патчит его). Она принимает три аргумента: полный путь к файлу, смещение от начала файла (в байтах), по которому нужно произвести запись, и сами данные — в виде строки из шестнадцатеричных цифр. Каждый байт данных должен быть обозначен двумя цифрами — т.е. если он имеет значение 0, нужно писать его как 00, и т.д. Байты в строке можно разделять пробелами для удобства восприятия, а также строка может состоять из нескольких строчек. Возвращает функция количество реально записанных байтов.<br /></p><div class="codebox"><pre><code>FilePath = C:\Temp\temp.bin  ; Путь к файлу.

Offset = 0x1000      ; Смещение в файле, по которому писать.

Data =               ; Данные для записи. Пробелы необязательны.
(
FF FF FF FE 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 EF FF FF FF
)

Result := FilePatch(FilePath, Offset, Data)

MsgBox, Записано байтов: %Result%


; ===================== Функция записи в файл. ======================

FilePatch(SrcFile, Offset, HexString) 
{
  If not FileExist(SrcFile) {
    MsgBox, 16, %A_ThisFunc%, Не найден файл:`n%SrcFile%
    Return 0
  }

  FileGetSize, FileSize, %SrcFile%

  If(Offset &gt;= FileSize) {
    MsgBox, 16, %A_ThisFunc%, Смещение за пределами файла.
    Return 0
  }

  If RegExMatch(HexString, &quot;i)0x&quot;) {
    MsgBox, 16, %A_ThisFunc%,
    (LTrim
      Неверный формат данных: префикс &quot;0x&quot;.
      Функция не предназначена для записи чисел,
      только последовательностей байтов.
    )
    Return 0
  }

  HexString := RegExReplace(HexString, &quot;\s&quot;)

  If HexString is not xDigit
  {
    MsgBox, 16, %A_ThisFunc%,
    (LTrim
      Строка данных содержит недопустимые символы.
      Допустимы только 0123456789ABCDEF.
    )
    Return 0
  }

  Len := StrLen(HexString)

  If Mod(Len, 2)
  {
    MsgBox, 16, %A_ThisFunc%,
    (LTrim
      В строке данных нечётное количество символов.
      Каждый байт нужно обозначать двумя цифрами.
    )
    Return 0
  }

  cBytes := Len / 2

  VarSetCapacity(Buf, cBytes, 0)

  Pos = 1

  Loop, % cBytes
  {
    Byte := &quot;0x&quot; . SubStr(HexString, Pos, 2)
    Pos += 2
    NumPut(Byte, Buf, A_Index - 1, &quot;Char&quot;)
  }

  OPEN_EXISTING = 3
  FILE_WRITE_DATA = 2
  FILE_BEGIN = 0

  VarSetCapacity(BytesWritten, 4, 0)

  hFile := DllCall( &quot;CreateFile&quot;, &quot;Str&quot;,  SrcFile
                                , &quot;UInt&quot;, FILE_WRITE_DATA
                                , &quot;UInt&quot;, 0
                                , &quot;UInt&quot;, 0
                                , &quot;UInt&quot;, OPEN_EXISTING
                                , &quot;UInt&quot;, 0
                                , &quot;UInt&quot;, 0 )

  If(hFile = -1) {
    MsgBox, 16, %A_ThisFunc%, Не удалось открыть файл.
    Return 0
  }

  DllCall( &quot;SetFilePointer&quot;, &quot;UInt&quot;,  hFile
                           , &quot;UInt&quot;, Offset
                           , &quot;UInt&quot;, 0
                           , &quot;UInt&quot;, FILE_BEGIN )

  If(A_LastError) {
    DllCall( &quot;CloseHandle&quot;, &quot;UInt&quot;, hFile )
    MsgBox, 16, %A_ThisFunc%
              , Ошибка при установке указателя файла: %A_LastError%
    Return 0
  }

  Ret := DllCall( &quot;WriteFile&quot;, &quot;UInt&quot;, hFile
                             , &quot;UInt&quot;, &amp;Buf
                             , &quot;UInt&quot;, cBytes
                             , &quot;UInt&quot;, &amp;BytesWritten
                             , &quot;UInt&quot;, 0 )

  If(Ret = 0) {
    DllCall( &quot;CloseHandle&quot;, &quot;UInt&quot;, hFile )
    MsgBox, 16, %A_ThisFunc%, Не удалось записать в файл.
    Return 0
  }

  DllCall( &quot;CloseHandle&quot;, &quot;UInt&quot;, hFile )

  Return NumGet(BytesWritten, 0, &quot;UInt&quot;)
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Mon, 25 May 2009 03:42:51 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=23640#p23640</guid>
		</item>
	</channel>
</rss>
