Что нового

Интеракция Диапазон памяти, выделенный для данной структуры, не может быть прочитан

musicstashall

Знающий
Сообщения
322
Репутация
7
Всем доброго.
Столкнулся с непредвиденной трудностью. Создаю структуру данных для передачи другому процессу и получаю ошибку от функции _WinAPI_DisplayStruct — «the memory range allocated to a given structure could not be read» (собвственно в загаловке темы). Если не использовать эту функцию, то скрипт просто молча падает. Внутри процесса, память и структура читаются, в другом процессе — не может, при обращении к $tText.Text падает. Одна ремарка: процесс-приемник создается с повышенными правами (runas), но это у меня никогда не вызывало проблем в других моих работах.
Код:
Global Const $tagCOPYDATASTRUCT = 'ulong_ptr dwData;dword cbData;ptr lpData'

Процесс-передатчик:
Local $string = _ArrayToString($aList, '|', -1, -1, ':::') ; массив, который нужно передать, конвертируем в строку
Local $MapFile = _WinAPI_CreateFileMapping(-1, 40960, 'MappingArray')
Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
Local $tCOPYDATASTRUCT = DllStructCreate($tagCOPYDATASTRUCT, $PosFile)
Local $iLength = StringLen($string)
Local $tText = DllStructCreate('wchar Text[' & ($iLength + 1) & ']')
$tCOPYDATASTRUCT.dwData = $i
$tText.Text = $string
$tCOPYDATASTRUCT.cbData = DllStructGetSize($tText)
$tCOPYDATASTRUCT.lpData = DllStructGetPtr($tText)

Local $result = ShellExecute(@AutoItExe, '...', '', 'runas')

Процесс-приемник:
Local $PosFile = _WinAPI_MapViewOfFile(_WinAPI_OpenFileMapping('MappingArray'))
Local $tCOPYDATASTRUCT = DllStructCreate($tagCOPYDATASTRUCT, $PosFile)
Local $i = $tCOPYDATASTRUCT.dwData
Local $tText = DllStructCreate('wchar Text[' & ($tCOPYDATASTRUCT.cbData / 2) & ']', $tCOPYDATASTRUCT.lpData)
_WinAPI_DisplayStruct($tText)
Local $string = $tText.Text
Local $data = StringSplit($string, ':::', 1)

For $j = 1 To $data[0]
    _ArrayAdd($fList, $data[$j])
Next

_ArrayDisplay($fList)
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
мои наблюдения.

все работает, если после запуска процесса передатчика прошло некое время и было уже подключение с ошибкой. но при этом, процесс приемник перезапускался.
ошибку вызывает функция
Код:
_WinAPI_IsBadReadPtr

в функции
Код:
_WinAPI_DisplayStruct

https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-isbadreadptr

указанная проблема подходит под ошибку доступа к чтению памяти.
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
указанная проблема подходит под ошибку доступа к чтению памяти.
Все посмотрел, ничего у себя не обнаружил. Но вот, вдруг поведение изменилось, теперь ошибки не вызывает, но и строки я все равно не получаю, размер $tCOPYDATASTRUCT.cbData тоже 0. Какие причины могут быть в доступе к памяти?
Несколько другой вопрос: как правильно создать файл $MapFile в памяти с учетом достаточного его размера, относительно загружаемых в него данных? Я бы хотел сначала создать структуру, потом, получив ее размер, создать файл $MapFile по размеру и потом загрузить в него структуру. Как это сделать?
Сообщение автоматически объединено:

Вот полный скрипт. Не работает. проверьте, что здесь не так
Код:
#Include <RecFileListToArray.au3>
#include <Array.au3>
#include <WinAPIFiles.au3>
#include <WinAPIDiag.au3>

Global Const $tagCOPYDATASTRUCT = 'ulong_ptr dwData;dword cbData;ptr lpData'
If Not IsAdmin() Then
   RequireAdmin()
Else
   Execute($CmdLine[1])
EndIf

Func RequireAdmin()
   Local $aList = _RecFileListToArray('C:\Windows', '*', 0, 0, 0, 2)
   _ArrayColInsert($aList, 1)
   _ArrayColInsert($aList, 1)
   _ArrayColInsert($aList, 1)
   _ArrayDisplay($aList)
    Local $string = _ArrayToString($aList, '|', -1, -1, ':::')
    Local $MapFile = _WinAPI_CreateFileMapping(-1, 40960, 'MappingArray')
    Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
    Local $tCOPYDATASTRUCT = DllStructCreate($tagCOPYDATASTRUCT, $PosFile)
    Local $iLength = StringLen($string)
    Local $tText = DllStructCreate('wchar Text[' & ($iLength + 1) & ']')
    $tCOPYDATASTRUCT.dwData = 1
    $tText.Text = $string
    $tCOPYDATASTRUCT.cbData = DllStructGetSize($tText)
    $tCOPYDATASTRUCT.lpData = DllStructGetPtr($tText)
    ;_WinAPI_UnmapViewOfFile($PosFile)
    Local $result = ShellExecute(@AutoItExe, 'ContinueAdmin()', '', 'runas')
    If Not $result Then Return ContinueAdmin() ; отказываемся предоставлять права и функция приемника отрабатывает в текущем процессе
    Sleep(20000)
EndFunc

Func ContinueAdmin()
    Local $fList[0][4]
    Local $MapFile = _WinAPI_OpenFileMapping('MappingArray')
    If Not $MapFile Then Return MsgBox('','','Файл памяти не может быть открыт'&@CR&_WinAPI_GetLastError())
    Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
    If Not $PosFile Then Return MsgBox('','','Файл памяти не может быть прочитан'& @CR&_WinAPI_GetLastError())
    Local $tCOPYDATASTRUCT = DllStructCreate($tagCOPYDATASTRUCT, $PosFile)
    If _WinAPI_IsBadReadPtr($PosFile, 40960) Then Return MsgBox('','','Диапазон памяти, выделенный для данной структуры, не может быть прочитан')
    If _WinAPI_IsBadReadPtr($tCOPYDATASTRUCT.lpData, $tCOPYDATASTRUCT.cbData) Then Return MsgBox('','', 'Диапазон памяти, выделенный для структуры tText, не может быть прочитан')
    Local $i = $tCOPYDATASTRUCT.dwData
    Local $tText = DllStructCreate('wchar Text[' & ($tCOPYDATASTRUCT.cbData / 2) & ']', $tCOPYDATASTRUCT.lpData)

    ;MsgBox('', '', $i)
    ;_WinAPI_DisplayStruct($tText)
    ;MsgBox('','',$tCOPYDATASTRUCT.cbData)
    Local $string = $tText.Text
    Local $data = StringSplit($string, ':::', 1)
    _WinAPI_UnmapViewOfFile($PosFile)

    For $j = 1 To $data[0]
        _ArrayAdd($fList, $data[$j])
    Next
    _ArrayDisplay($fList)
EndFunc


Файл памяти _WinAPI_OpenFileMapping('MappingArray') не открывается
Сообщение автоматически объединено:

Чуток разобрался, добавил Sleep(20000) (в примере исправил) для процесса-передатчика, тогда файл памяти открывается, но текст по-прежнему не извлекается
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
код передачи
Код:
Local $aList = _FileListToArrayRec('путь', '*', 1, 1, 0, 2)
    Local $string = _ArrayToString($aList, '|')
    Local $iLength = StringLen($string)
    Local $MapFile = _WinAPI_CreateFileMapping(-1, $iLength * 2, 'MappingArray')
    Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
    Local $tText = DllStructCreate('int size[12];wchar txt[' & $iLength + 12 & ']', $PosFile); в первую позицию грузим размер данных
    DllStructSetData($tText, 'size', $iLength)
    DllStructSetData($tText, 'txt', $string)


код приемника
Код:
Local $fList[0]
    Local $MapFile = _WinAPI_OpenFileMapping('MappingArray')
    Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
    Local $tSize = DllStructCreate('int size[12]', $PosFile); получаем размер текстового блока
    Local $tData = DllStructCreate('int size[12];wchar txt[' & DllStructGetData($tSize, 1) + 12 & ']', $PosFile); пересоздаем структуру.
    Local $string = DllStructGetData($tData, 2)
    Local $data = StringSplit($string, '|', 1)
    For $j = 1 To $data[0]
        _ArrayAdd($fList, $data[$j])
    Next
    _ArrayDisplay($fList)

у меня передает из процесса в процесс.
 
Верх