OberonCore
https://forum.oberoncore.ru/

BlackBox и NetBIOS. Были у кого-нибудь удачные попытки?
https://forum.oberoncore.ru/viewtopic.php?f=2&t=96
Страница 1 из 3

Автор:  Cardinal [ Четверг, 12 Январь, 2006 18:49 ]
Заголовок сообщения:  BlackBox и NetBIOS. Были у кого-нибудь удачные попытки?

Пробовал оборачивать netapi32.dll. Пока неудачно.
Код:
MODULE NBSInterface ["netapi32.dll"];

.....

TYPE
   
      Handle = INTEGER;
      
      TNBName = ARRAY NBNAMESIZE - 1 OF BYTE;
      TNCBPostProc = PROCEDURE(P: PNCB);

      PNCB* = POINTER TO TNCB;
      TNCB* =  RECORD [noalign]
         Command*:  BYTE;
         RetCode*:  BYTE;     
         LSN*:      BYTE;     
         Num*:      BYTE;     
         Buf*:      INTEGER;   
         Length*:   INTEGER;   
         CallName*: TNBName;   
         Name*:     TNBName;   
         RTO*:      BYTE;     
         STO*:      BYTE;     
         PostPrc*:  TNCBPostProc;

         Lana_Num*: BYTE;   
         Cmd_Cplt*: BYTE;     

         Reserved*: ARRAY 10 OF BYTE;
         Event*:    Handle; 

  END;
      
      
      
   PROCEDURE Netbios* (P:PNCB): CHAR;
END NBSInterface.


Код на Delphi:
Код:
  PNCB = ^TNCB;

 { Netbios Control Block }

 {$IFDEF WIN32}
  TNCBPostProc = procedure(P: PNCB);
 {$ENDIF}

  TNCB = packed record        { Netbios Control Block }
    Command:  byte;      { command code                       }
    RetCode:  byte;      { return code                        }
    LSN:      byte;      { local session number               }
    Num:      byte;      { name number                        }
    Buf:      ^byte;     { data buffer                        }
    Length:   word;      { data length                        }
    CallName: TNBName;   { name to call                       }
    Name:     TNBName;   { our own name                       }
    RTO:      byte;      { receive time-out                   }
    STO:      byte;      { send time-out                      }
  {$IFNDEF WIN32}
    Post_Offs:word;      { asynch notification routine offset }
    Post_Seg: word;      { asynch notification routine segment}
  {$ELSE}
    PostPrc:  TNCBPostProc;{ asynch notification routine (nb30) }
  {$ENDIF}
    Lana_Num: byte;     { adapter number                     }
    Cmd_Cplt: byte;     { command completion flag            }
  {$IFDEF WIN32}
    Reserved: array[0..9] of byte;  { Reserverd for Bios use }
    Event:    THandle;  { WIN32 event handle to be signalled }
                        { for asynch cmd completion          }
  {$ELSE}
    Reserved: array[0..13] of byte;  { Reserved }
  {$ENDIF}
  end;


Сомневаюсь, что правильно описал Buf.

Автор:  Илья Ермаков [ Четверг, 12 Январь, 2006 21:49 ]
Заголовок сообщения: 

TNBName = ARRAY [untagged] NBNAMESIZE - 1 OF BYTE;
- здесь, строго говоря, тоже надо влепить [untagged]. Хотя память под массив динамически и не выделяется, но тег все равно будет даже у поля записи - например, для работы SIZE() при передаче открытым массивом.
Еще возможно, хотя не уверен, без [noalign] будет 4-байтовое выравнивание на элементы массива. Лучше в данном случае вообще использовать SHORTCHAR.

Buf как раз верен: для системных указателей используется INTEGER.

Автор:  Сергей Оборотов [ Четверг, 12 Январь, 2006 23:31 ]
Заголовок сообщения: 

Сомнение вызывает тип у Length. SHORTINT подходит больше. А нельзя не переводить недостающие типы, а новые добавлять к базовым?
P.S. Жаль только комментарии пропадают куда-то.

Автор:  Илья Ермаков [ Четверг, 12 Январь, 2006 23:52 ]
Заголовок сообщения: 

Цитата:
Сомнение вызывает тип у Length. SHORTINT подходит больше.


Да, кстати! Проглядел - Length действительно должен быть SHORTINT.
Тут никаких "больше-меньше подходит", тут же нарушалась вся структура из-за 32-битного INTEGER вместо 16-битного word. Правда, SHORTINT не полностью соответствует word - он знаковый, но тут уж ничего не попишешь, нет в КП беззнаковых целых...

Reserved*: ARRAY 10 OF BYTE - надо [untagged]

Автор:  Сергей Оборотов [ Пятница, 13 Январь, 2006 06:28 ]
Заголовок сообщения: 

Илья, разница между больше подходит и должен такая же, как между SHORTINT и WORD. Но раз последний отсутствует в языке, то писать придется, увы. Вообще-то заменить ARRAY на запись с байтовыми полями и орудовать на низком уровне. Такая возможность всегда остается.

Автор:  Info21 [ Пятница, 13 Январь, 2006 10:13 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
TNBName = ARRAY [untagged] NBNAMESIZE - 1 OF BYTE;
... Еще возможно, хотя не уверен, без [noalign] будет 4-байтовое выравнивание на элементы массива.


Но не для BYTE и не для SHORTINT|CHAR (конечно же).

Автор:  Сергей Губанов [ Пятница, 13 Январь, 2006 11:10 ]
Заголовок сообщения:  Re: BlackBox и NetBIOS. Были у кого-нибудь удачные попытки?

Cardinal писал(а):
Код:
PROCEDURE Netbios* (P:PNCB): CHAR;

Признаться честно, не понимаю о чём речь, но о чём бы она ни была, мне кажется, что одна ошибка видна невооруженным взглядом. Процедура Netbios не выделяет память под объект (не меняет значения указателя). Значит ей надо передавать не указатель (не POINTER TO), а адрес ранее размещенного объекта (адрес передаётся с помощью ссылочного модификатора IN, VAR или OUT):
Код:
PROCEDURE Netbios* (VAR ncb: TNCB): CHAR;

Код:
  VAR ncb: TNCB;
BEGIN
  ...
  Netbios(ncb);
  ...

Автор:  Trurl [ Пятница, 13 Январь, 2006 14:04 ]
Заголовок сообщения: 

А почему NBNAMESIZE - 1 ?

Автор:  Trurl [ Пятница, 13 Январь, 2006 14:12 ]
Заголовок сообщения: 

Кстати, Вы смотрели WinNet? Кажется, там уже есть интерфейс к netbios.

Автор:  Cardinal [ Пятница, 13 Январь, 2006 15:29 ]
Заголовок сообщения: 

Сейчас посмотрел. То, что надо. Спасибо :wink: . А мой пример после внесения всех изменений, которые здесь мне советовали, выдавал Illegal command.

Автор:  Сергей Оборотов [ Пятница, 13 Январь, 2006 20:39 ]
Заголовок сообщения: 

Признаться честно, я не понял, может ли значение типа указатель отличаться от адреса ранее размещенного объекта...
С чем связано то, что указатели по значению не передаются?

Автор:  Сергей Губанов [ Пятница, 13 Январь, 2006 23:08 ]
Заголовок сообщения: 

GUEST писал(а):
Признаться честно, я не понял,...


Работая с самим объектом ncb: TNCB в отличие от указателя на него ptr: PNCB, не надо заботится о размещении в памяти объекта ptr^ на который он указывает. В случае [untagged] объекта разместить его в памяти с помощью NEW(ptr) нельзя, а это, согласитесь, дополнительные проблемы. Ссылочные модификаторы IN, VAR и OUT позволяют передавать адрес объекта в WinApi-шные процедуры не используя указателей вовсе.

Автор:  Илья Ермаков [ Пятница, 13 Январь, 2006 23:30 ]
Заголовок сообщения: 

Цитата:
С чем связано то, что указатели по значению не передаются?



С тем, что по ссылке можно передать как статическую переменную, так и указатель - он будет разыменован (формально говоря, на самом деле, конечно, парам-р по ссылке - это и есть указатель, и с точки зрения машинного кода операция лишняя возникает как раз в первом случае - взятие адреса).

Так вот, а в ту процедуру, которая требует указателя, статическую переменную вы не передадите никак - в КП отсутствует операция взятия адреса, т.к. она порождает небезопасные (неуправляемые) указатели. Есть, конечно, SYSTEM.ADR - но это низкоуровневая вещь, которой нужно пользоваться как можно меньше.

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

Автор:  Сергей Оборотов [ Пятница, 13 Январь, 2006 23:33 ]
Заголовок сообщения: 

А почему надо заботиться о размещении в памяти объекта, на который указывает ptr. Нет возможности просто указать с каким объектом ему работать?
Можно также спросить на какой вопрос вы отвечали?

Автор:  Илья Ермаков [ Пятница, 13 Январь, 2006 23:43 ]
Заголовок сообщения: 

Цитата:
А почему надо заботиться о размещении в памяти объекта, на который указывает ptr. Нет возможности просто указать с каким объектом ему работать?


Тогда я не понимаю вопроса...

Смотрите:

PROCEDURE Netbios* (P:PNCB): CHAR;

Если процедура объявляется так, то в точке ее вызова мне придется откуда-то брать динамически распределенный NCB. Или брать SYSTEM.ADR от стековой переменной и приводить его тип через SYSTEM.VAL. Но использовать SYSTEM в "нормальном" коде не следует вообще - это и несовместимость, и нарушение безопасности. А откуда мне взять динамически распределенный NCB? NEW с [untagged]-записями не работает, значит, нужно обращаться к WinApi.VirualAlloc или системному менеджеру кучи. А потом прибивать эту память. Целый букет гемора + потеря скорости.

Если я объявляю PROCEDURE Netbios* (VAR ncb: TNCB): CHAR, то
я могу сделать как
VAR ncb: NCB; BEGIN Netbios(ncb),
так и VAR pncd: PNCB; ... Netbios(pncb).
То есть, получаем штатный вариант, работающий с любой памятью, при том безопасно.

Автор:  Сергей Оборотов [ Пятница, 13 Январь, 2006 23:46 ]
Заголовок сообщения: 

Я впрочем, и не хотел передавать в процедуру статическую переменную, а лишь значение указателя. Могу я это сделать?

Автор:  Илья Ермаков [ Пятница, 13 Январь, 2006 23:56 ]
Заголовок сообщения: 

Технически - да, конечно. Практически делается редко, по уже описанным причинам. Потому и процедуры объявляются по второй форме обычно.

Автор:  Сергей Оборотов [ Суббота, 14 Январь, 2006 00:15 ]
Заголовок сообщения: 

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

Автор:  Илья Ермаков [ Суббота, 14 Январь, 2006 00:26 ]
Заголовок сообщения: 

Пардон, мне показалось, что вначале Вы спрашивали именно это, после замечания Губанова по форме процедур... Может быть, перепутал...

Автор:  Сергей Оборотов [ Суббота, 14 Январь, 2006 08:13 ]
Заголовок сообщения:  Re: BlackBox и NetBIOS. Были у кого-нибудь удачные попытки?

Сергей Губанов писал(а):
Cardinal писал(а):
Код:
PROCEDURE Netbios* (P:PNCB): CHAR;
...
, мне кажется, что одна ошибка видна невооруженным взглядом. Процедура Netbios не выделяет память под объект (не меняет значения указателя). Значит ей надо передавать не указатель (не POINTER TO), а адрес ранее размещенного объекта
Цитата:
Признаться честно, я не понял, может ли значение типа указатель отличаться от адреса ранее размещенного объекта...
...?

Страница 1 из 3 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/