Портирование NotesAPI и WinAPI под x64

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Коллеги, подскажите пожалуйста, как заставить заработать NSFItemInfoNext под Win64?

Код:
'Рабочий код под Win32
Declare Function W32_NSFItemInfoNext Lib "nnotes" Alias {NSFItemInfoNext} (ByVal hNote As Long, ByVal prev_item_blockid_pool As Long, ByVal prev_item_blockid_block As Long, ByVal item_name As String, ByVal name_len As Integer, item_blockid As BLOCKID, value_datatype As Long, value_blockid As BLOCKID, value_len As Long) As Integer

'Под Win64 естественно изменил хендл документа на Double и в стуруктуре BLOCKID Integer, а также все числовые параметры функции заменял на Long - не помогает:
Public Type BLOCKID
    pool As Long                     'address of memory
    block As Long                    'offset within this pool        было Integer, но под Win32 работает и Long
End Type
Declare Function W64_NSFItemInfoNext Lib "nnotes" Alias {NSFItemInfoNext} (ByVal hNote As Double, ByVal prev_item_blockid_pool As Long, ByVal prev_item_blockid_block As Long, ByVal item_name As String, ByVal name_len As Integer, item_blockid As BLOCKID, value_datatype As Long, value_blockid As BLOCKID, value_len As Long) As Integer
Что только не перепробовал, а сервак всё равно крешится ((

Есть , но тоже не помогает.

P.S. .
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
Если я правильно читаю ...
No workaround available.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Интересно, что они имели в виду под "because of the different data alignment between 64-bi APIs and 32-bit Lotusscript"? Несовпадение разрядности? Тогда где может быть это несовпадение, если винда 64-bit и Domino тоже?
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
Спешу вас расстроить.

Domino 9.0.1 FP10 Win7 64
Всё работает

Код:
%REM
    Agent 1-1
    Created Feb 28, 2018 by Administrator
    Description: Comments for Agent
%END REM
Option Public
Option Declare



Type BLOCKID64
Pool As Double
Block As Integer
End Type

Declare Function W64_NSFItemInfo Lib "nnotes.dll" Alias "NSFItemInfo" (ByVal noteHandle As Long,_
ByVal itemName As String, ByVal nameLength As Integer, itemBlockID As BLOCKID64, valueDataType As Integer, valueBlockID As BLOCKID64, valueLength As Long) As Integer

Declare Function W64_NSFItemInfoNext Lib "nnotes.dll" Alias "NSFItemInfoNext" (ByVal noteHandle As Long,_
ByVal prevItemBlockIDDbl As Double, ByVal itemName As String, ByVal nameLength As Integer, itemBlockID As BLOCKID64, valueDatatype As Integer, valueBlockID As BLOCKID64, valueLength As Long) As Integer


Sub Initialize
    Dim dbHandle As Long
    Dim noteHandle As Long
    Dim RTItemName As String
    Dim ItemBlockID As BLOCKID64
    Dim ItemDataType As Integer
    Dim ValueBlockID As BLOCKID64
    Dim ValueLength As Long
    Dim NextItemBlockID As BLOCKID64
    Dim NextItemDataType As Integer
    Dim NextValueBlockID As BLOCKID64
    Dim NextValueLength As Long
    Dim StatusResult As Integer

    RTItemName = "Body"

    Dim session As New NotesSession
    Dim db As NotesDatabase
    Set db = session.currentdatabase
    Dim doc As NotesDocument
    Set doc = db.createdocument
    Dim rti As NotesRichTextItem
   
    Set rti = New NotesRichTextItem( doc, RTItemName)
   
   
    StatusResult = W64_NSFItemInfo(doc.handle, RTItemName, Len(RTItemName), ItemBlockID, ItemDataType, ValueBlockID, ValueLength)
   
    Print "StatusResult1", StatusResult

    StatusResult = W64_NSFItemInfoNext(doc.handle, ItemBlockID.Pool, RTItemName,_
    Len(RTItemName), NextItemBlockID, NextItemDataType, NextValueBlockID, NextValueLength)
   
    Print "StatusResult2", StatusResult
End Sub


[3240:0002-1130] 28.02.2018 18:38:30 AMgr: Agent ('1-1' in 'AgentCra.nsf') pri
nting: StatusResult1 0
[3240:0002-1130] 28.02.2018 18:38:30 AMgr: Agent ('1-1' in 'AgentCra.nsf') pri
nting: StatusResult2 546
>

PS: ща доберусь до сервера

---- Добавлено позже ----

01.03.2018 18:51:29 AMgr: Agent '1-1' in database 'delit\AgentCra.nsf' signed by 'Administrator' is running in Full Administrator mode
01.03.2018 18:51:29 AMgr: Agent ('1-1' in 'delit\AgentCra.nsf') printing: StatusResult1 0
01.03.2018 18:51:29 AMgr: Agent ('1-1' in 'delit\AgentCra.nsf') printing: StatusResult2 546


Win2012R2
Dom901FP10
 
Последнее редактирование:
  • Нравится
Реакции: VladSh

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Наоборот обрадовали!)

Дело наверное в том, что у Вас Pool в BLOCKID64 описан как Double.
А вот что хендлы БД и доков описаны как Long на Win64 - это плохо. У меня на этом сервак, далеко не всегда, но сыпался. В мануале по портированию тоже об этом говорится.

У меня война продолжается - под 8.5.3 FP6 HF1840 64-бит одно работает, а это же под 9.0.1 FP2 64-бит - нет, и наоборот; капец какой-то! Видимо где-то всё же есть "different data alignment between 64-bi APIs and 32-bit Lotusscript".

Короче, спасибо огромное! Напишу чем всё закончилось. Или следующие вопросы)

Добавлено:
Понял, Вы используете короткий хендл doc.handle без полной инициализации дока в API, у нас такое не всегда проходит, иногда нужна полная инициализация с помощью NSFNoteOpen, потому и хендлы описаны как Double, иначе при обратном преобразовании в Long хендл обнуляется со всеми вытекающими...
 
Последнее редактирование:

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
С какого чертополоха хэнделы должны стать __не__ Long ?
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Видел на IBM'овском форуме, что при портировании так делают, а потом увидел это:
Domino handles are 32bit on domino 32 and 64 platforms. However, windows handles are 64bit on 64bit windows. So please use DHANDLE instead of system HANDLE which is 32bit on all 32 and 64 bit platforms. Use HANDLE only when we need to use windows API but all Domino API calls should be passed with DHANDLE.
Я неправильно понял? Не нужно переводить их в Double? У Вас весь API-код работает с Long?

Ваш код заработал у меня на 8.5.3. Т.е. дело и в коротком хендле тоже. Также этот код работает и на Win32!
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
Хэндлер в Лотус не может стать д... ну вы теперь всё правильно поняли :)

Документ, на который вы ссылаетесь, походу, вообще к LotusScript не имеет особого отношения.
... пойду документацию скачаю, невозможно интернет-фантазии читать
 
Последнее редактирование:

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Все вызовы с хендлами As Long вроде как работают и под Win64...

Double, который есть BLOCKID64 и в параметре prevItemBlockIDDbl функции NSFItemInfoNext, затребовал повышения Long -> Double в параметрах функций NSFDbReadObject, OSLockObject, OSUnlockObject, оно стало рушить клиента при передаче в Advapy-функции вычисления хеша: CryptAcquireContext, CryptCreateHash, CryptHashData, CryptGetHashParam, CryptReleaseContext, CryptDestroyHash. Заменил хендл в этих функциях на Double и код перестал рушить и клиент, и сервер, но хеши рассчитываются неверно, причём каждый раз выдаётся разный результат, видимо из-за увеличения размера переменной неверно вычитываются данные из памяти.

Если нужно, могу подготовить пример, как это всё сейчас выглядит.

Захотелось, написать такие декларации, чтобы они работали и под Win32, и под Win64 (большие неудобства с разными структурами BLOCKID и BLOCKID64). Это возможно?
У кого-то есть есть рабочие декларации этих функций, хотя бы под Win64? (отдельно под Win32 всё работает).
Взял идею из кода Кости Червоненко по работе со стабами, т.е. пишу это на классах. Поделюсь с общественностью, когда всё получится. Что касается NSF...-функций, после небольшой обработки напильником код готов и будет работать, а вот все остальные вышеперечисленные функции - пока печаль ((
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
Коротенькие примерчики всегда полезны, ато всякие Д_Д будут разрушать картину мира :)

Вот жалоба идентична вашей?

А помоему перепутал типы в декларациях.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Я по второй ссылке как раз делал декларации, т.к. первую не нашёл. Отличие в декларации CryptHashData.

Они подписывают строки:
Код:
Private Declare Function CryptHashData Lib "advapi32.dll" _
        (ByVal hHash As LongPtr, _
         ByVal pbData As String, _
         ByVal dwDataLen As Long, _
         ByVal dwFlags As Long) As Long

а у нас нет строк, - работа идёт с памятью, т.к. NSFItemInfo и NSFItemInfoNext возвращают структуру BLOCKID/BLOCKID64, которую мы передаём дальше в OSLockBlock и CryptHashData, которая задекларирована так:
Код:
Private Declare Function W32CryptHashData Lib "Advapi32" Alias "CryptHashData" _
         (Byval hHash As Long, _
         Byval addr_data As Long, _
         Byval dwSize As Long, _
         Byval dwFlag As Long) As Long
Это прекрасно работает под Win32 с "32-битной" структурой BLOCKID.

Ушёл готовить пример...
 

Domino-Designer

Людям надо поморгать!
Lotus Team
06.12.2011
617
223
BIT
26
Ну а я попробую поиграть в телепата.

У вас я увижу следующую модель:
[NSF_Memory] => [W64_Crypt]

Предполагаю, что внеся изменение
[NSF_Memory] => [W64_OS_CopyMemory] => [W64_Crypt]
мы решим проблему, покуда для их Long я адекватного типа данных в LS не вижу.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Domino-Designer

Прошу прощения, что так долго. Думал сделать маленький пример, но делать на 32 и 64 разные примеры было слишком, потому сделал автопереключение между 32 и 64. Структуры BLOCKID и BLOCKID64 создаю внутри методов, в которых они используются. Данные в эти методы передаю с помощью объектов класса LNMemStruct, а в классы для работы с памятью LNMemHandle.

Код как мог вычистил от всего лишнего. Хоть пример получился и не маленький, но места, где могут быть проблемы, свёл до минимума.

Основной код в Initialize, далее AddItemValue2Hash; проблемы, по моему, где-то здесь:
- класс LNMemBlock, метод Lock() - какой-то стрёмный " + TYPE_WORD";
- там же метод OSLockBlock - стремноватый " + (block_id.getBlock() And 65535) 'make unsigned value if block_id.block < 0";
- во 2-й строке AddItemValue2Hash - стрёмное " - 2".
Стрёмное всё это потому, что не знаю, можно ли это в чистом виде использовать для Win64.
Также, возможно, проблемы в некоторых декларациях...
Код не мой, изначально был взят где-то в инете, и мне достался по наследству. Приходится поддерживать, а знаний, к сожалению, не хватает(

> Предполагаю, что внеся изменение
> [NSF_Memory] => [W64_OS_CopyMemory] => [W64_Crypt]
> мы решим проблему, покуда для их Long я адекватного типа данных в LS не вижу.

Я переводил в примере в Double, может быть в этом проблема. А куда переводить ещё, не в Currency же...
CopyMemory - это скопировать в строку и потом передать её в CryptHashData, работающую со строкой? У меня нет опыта работы с этом.
Не поделитесь примером, как работает эта связка?
 

Вложения

  • w3264_example.txt
    27,9 КБ · Просмотры: 781
Последнее редактирование:
  • Нравится
Реакции: Domino-Designer

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Они разные - с точки зрения поддержки архитектуры 64 bit
Если есть подробности по вызовам API, то это было бы полезно.
Сейчас задача сделать так, чтобы проверка/вычисление хешей, которые уже есть заработали и на сервере 8.5.3 64-bit.

Но вообще, в идеале, хотелось бы по максимуму отказаться от некроссплатформенного API. Если бы можно было с помощью NotesAPI вытащить подписываемые данные и передать, к примеру, в аналогичный функционал на Java, то это было бы просто бомба! Главное, чтобы результат (хеш) был точно такой же, как сейчас вычисляется с помощью Advapi (используется SHA1).

Когда-то давно я вычислял хеш, разбирая dxl, но здесь почему-то стали использовать такое геморройное решение с API, где реально непонятно, в каком виде подписываемые данные, т.к. оперируют тут указателями на блоки памяти, а не строками.
 
Последнее редактирование:

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Предыдущую проблему к сожалению не решил. Просто продолжаю "заметки на полях".

При конфигурации 8.5.3 FP6 на Win64 при использовании 64-битной декларации:
Код:
Declare Private Function W64NSGetServerClusterMates Lib "nnotes" Alias "NSGetServerClusterMates" (ByVal server_name As LMBCS String, ByVal dwFlags As Long, retHandle As Double) As Integer

и передаче полученного хендла в OSLockObject происходит падение сервера. Причём только при запуске агента по расписанию; при запуске этого же агента из консоли всё нормально! 9-ка на Win64 тоже работает нормально с 64-битными структурами.

Для работоспособности на данной конфигурации нужно использовать 32-битную декларацию:
Код:
Declare Private Function W32NSGetServerClusterMates Lib "nnotes" Alias "NSGetServerClusterMates" (ByVal server_name As LMBCS String, ByVal dwFlags As Long, retHandle As Long) As Integer

но из-за того, что это очень неудобно (нужно в LS-классах для некоторых цепочек функций предусмотреть возможность работы на 64 битах 32-битных структур), просто переписал этот код (получение списка серверов кластера переданного сервера) на LS, благо, что это возможно, не знаю, зачем он вообще был написан с использованием api.
 

VladSh

начинающий
Lotus Team
11.12.2009
1 797
158
BIT
233
Может кто знает, инфа о декларациях API для Mac появилась?
 

duchan

Green Team
20.09.2006
128
11
BIT
250
День добрый.

Столкнулся с такой проблемой:
Для определенных нужд пришлось поднять старую задачу, где использовалось WinApi. Раньше она работала на WinXP и Notes 7.
Попробовал запустить на win7(64)+notes9.0.1 и оно не работает. Полез разбираться и увидел что все функции декларированные из winApi не работают (или работают не корректно возвращая 0 ) - notes ошибок не выдает, но и корректной работы функций не наблюдаю.

Функции которые декларировались:
Код:
Declare Function RegCloseKey Lib "advapi32.dll" (Byval hKey As Long) As Long
Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (Byval hKey As Long, Byval lpSubKey As String, phkResult As Long) As Long
Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" (Byval hKey As Long, Byval lpSubKey As String, Byval ulOptions As Long, Byval samDesired As Long, phkResult As Long) As Long
Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" (Byval hKey As Long, Byval lpValueName As String, Byval lpReserved As Long, lpType As Long, Byval lpData As String, lpcbData As Long) As Long

Declare Function WaitForSingleObject Lib "kernel32" (Byval hHandle As Long, Byval dwMilliseconds As Long) As Long
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (Byval hwnd As Long, Byval lpOperation As String, Byval lpFile As String, Byval lpParameters As String, Byval lpDirectory As String, Byval nShowCmd As Long) As Long
Declare Function CreateProcessA Lib "kernel32" (Byval lpApplicationName As Long, Byval lpCommandLine As String, Byval lpProcessAttributes As Long, Byval lpThreadAttributes As Long, Byval bInheritHandles As Long, Byval dwCreationFlags As Long, _
Byval lpEnvironment As Long, Byval lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function CloseHandle Lib "kernel32" (Byval hObject As Long) As Long
Declare Function OpenProcess Lib "kernel32" (Byval dwDesiredAccess As Long, Byval bInheritHandle As Long,Byval dwProcessId As Long) As Long


Declare Function apiGetClassName Lib "user32" Alias "GetClassNameA" (Byval Hwnd As Long, Byval lpClassname As String, Byval nMaxCount As Long) As Long
Declare Function apiGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Long
Declare Function apiGetWindow Lib "user32" Alias "GetWindow" (Byval Hwnd As Long, Byval wCmd As Long) As Long
Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (Byval Hwnd As Long, Byval nIndex As Long) As Long
Declare Function apiGetWindowText Lib "user32" Alias "GetWindowTextA" (Byval Hwnd As Long, Byval lpString As String, Byval aint As Long) As Long
Declare Function ShowWindow Lib "user32" (Byval hwnd As Long,  Byval nCmdShow As Long) As Long
Declare Function BringWindowToTop Lib "user32" (Byval hwnd As Long) As Long

Может кто подскажет, что произошло и как с этим бороться (и возможно ли)?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!