Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Работа с портом с конкретным адресом. Запись и чтение [D7]


Страницы:   1 2 3 4

Velimir ©   (2006-04-24 14:18:00) 

Собсно сабж!
Какими в дельфи есть встроенные функции для работы с портом, если у меня есть адрес этого порта...
Хотелось бы найти аналог outport и inport из С.

Сорри если вопрос очень тупой, но я нигде не нашел этих функций... Действительно, как-то тормозом себя чуствую...
Заранее всем спасибо за помощь!


isasa   (2006-05-19 08:17:00) [1]

Thomas Anders   (18.05.06 14:58) [57]
Снимаю шляпу.
:)
Все-таки, пробивается.
Напоминает забивание кувалдой каждого байта в буфер ...
Ей Богу, легче использовать DDK, и написать как просят.


Игорь Шевченко   (2006-05-18 21:14:00) [2]


> Ну, вобщем то возможно (и наверняка это так и есть), что
> добавление этой привилегии откроет какую-нибудь дополнительную
> дыру в системе.


Не то слово. Размер этой дыры поражает. Поэтому простой народ, например, ASUSTek, пишет универсальные драйверы, которым передается адрес порта и что надо делать, читать или писать.


Thomas Anders   (2006-05-18 20:49:00) [3]

> Сергей М. ©   (18.05.06 17:16) [58]
> Разврат.

Ну почему же... Эта возможность может служить как инструмент разработки для быстрой проверки нового аппаратного обеспечения. Или имеется старая DOS-программа и очень нужно чтобы она работала в NT? На моей работе у некоторых коллег такая ситуация, используют DirectI/0, а это не удобно и кажется из-за HyperThreading ещё проблемы. Можно конечно и драйвер писать... Впрочем, каждый сам кузнец собственного геморроя...

> Игорь Шевченко ©   (18.05.06 17:37) [59]

Насчет смысла, трудно сказать есть он или нет. Всё зависит от задачи. Привилегию нужно назначать аккаунту только один раз. В некоторых случаях это приемлемо. Ну, вобщем то возможно (и наверняка это так и есть), что добавление этой привилегии откроет какую-нибудь дополнительную дыру в системе.


Игорь Шевченко   (2006-05-18 17:37:00) [4]

Thomas Anders   (18.05.06 14:58) [57]

Это конечно все хорошо и даже работает, но вот только эту привилегию не рекомендуют назначать никому...


Сергей М.   (2006-05-18 17:16:00) [5]


> Thomas Anders   (18.05.06 14:58) [57]


Разврат.


Thomas Anders   (2006-05-18 14:58:00) [6]

Доступ к портам ввода/вывода из Ring3 на NT платформах.


typedef DWORD   NTSTATUS;

typedef enum _PROCESSINFOCLASS {
  ProcessBasicInformation,
  ProcessQuotaLimits,
  ProcessIoCounters,
  ProcessVmCounters,
  ProcessTimes,
  ProcessBasePriority,
  ProcessRaisePriority,
  ProcessDebugPort,
  ProcessExceptionPort,
  ProcessAccessToken,
  ProcessLdtInformation,
  ProcessLdtSize,
  ProcessDefaultHardErrorMode,
  ProcessIoPortHandlers,
  ProcessPooledUsageAndLimits,
  ProcessWorkingSetWatch,
  ProcessUserModeIOPL,
  ProcessEnableAlignmentFaultFixup,
  ProcessPriorityClass,
  ProcessWx86Information,
  ProcessHandleCount,
  ProcessAffinityMask,
  ProcessPriorityBoost,
  ProcessDeviceMap,
  ProcessSessionInformation,
  ProcessForegroundInformation,
  ProcessWow64Information
} PROCESSINFOCLASS;

typedef  NTSTATUS
(__stdcall *NTDLL_ZwSetInformationProcess)(
  IN HANDLE ProcessHandle,
  IN PROCESSINFOCLASS ProcessInformationClass,
  IN PVOID ProcessInformation,
  IN ULONG ProcessInformationLength );
int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpCmdLine,
                    int       nCmdShow)
{
// Устанавливаем привелегию на действие от имени системы.
  HANDLE hToken;
  TOKEN_PRIVILEGES tkp;
  if ( !OpenProcessToken(GetCurrentProcess(),
     TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,  &hToken) )
     return -1;
  LookupPrivilegeValue(NULL, SE_TCB_NAME,
          &tkp.Privileges[0].Luid);    
  tkp.PrivilegeCount = 1;    
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  BOOLEAN bret = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
     (PTOKEN_PRIVILEGES)NULL, 0);
  CloseHandle(hToken);
  if ( !bret )
     return -2;
// Загружаем явно ntdll.dll и получаем адрес нужной функции - делаем это
// руками, чтобы не возиться с библиотеками экспорта.
  HINSTANCE NtDll;
  NtDll=LoadLibrary("ntdll.dll");
  if ( !NtDll)
     return -3;
  NTDLL_ZwSetInformationProcess   ZwSetInformationProcess =
     (NTDLL_ZwSetInformationProcess)GetProcAddress(NtDll, "ZwSetInformationProcess");
  if ( !ZwSetInformationProcess )
     return -4;    
  NTSTATUS Status = ZwSetInformationProcess( GetCurrentProcess(), ProcessUserModeIOPL,
     NULL, 0 );
  if ( Status != 0 )
     return -5;
  __try {
// Тут можно использовать инструкции in, out
  }
  __except( EXCEPTION_CONTINUE_EXECUTION )
  {
  }
return 0;
}


1. Данный код будет работать, если для акаунта разрешена привелегия "Act as part of the operating system", она же SeTcbPrivilege. По умолчанию она отключена даже для админского акаунта. Поэтому либо нужно ее разрешить (это можно сделать и программно), либо выполнять код с правами SYSTEM, что можно сделать, если работать как сервис.

2. Не смотря на разрешение инструкций ввода/вывода, все равно будет генерироваться исключение. Его нужно подавить (см. код). В данном случае приведена реализация для VC, для Borland' a тоже должно подойти.

PS: Исключение будет генерироваться каждый раз после переключения задачи и только на ХР. Поскольку Windows не хранит TSS, то при обращении к портам ввода вывода, каждый раз после переключения задачи, in, out оказываются привелегированными интсрукциями, что приводит к возникновению исключения и благополучной обработки его ядром. Для чего ядро XP возобновляет исключение после собственного обработчика, непонятно. Тем не менее, это исключение можно проигнорировать.


Сергей М.   (2006-05-18 10:41:00) [7]


> Не работает на ХР


Что значит "не работает" ?


vodvorezlaya   (2006-05-18 10:35:00) [8]


> procedure DataIn(PortAddress:word);
> var
> ByteValue:byte;
> Addr: Word;
> begin
>  Addr := PortAddress; //параметр PortAddress передается
> через eax, запомним его в лок.переменной
>  for i:=0 to 32767 do
>     begin
>       asm
>        push eax
>        push edx        
>        mov dx, Addr
>        in al,dx
>        mov ByteValue,al
>        pop edx
>        pop eax
>       end;
>       Data[i]:=ByteValue;
>     end;
> end;
>
> procedure DataOut(ByteValue:byte;PortAddress:word);
> asm
> //ByteValue передается в eax
> //PortAddress - в edx
> out dx,al
> end;
>
>
> > массив забивается практически одними и теми же значениями
>
>
> А где написано, что должен разными ?
> Док-ция на дивайс от производителя имеется ?


Не работает на ХР


!Fobos   (2006-05-10 11:26:00) [9]


> Сергей М. ©   (10.05.06 10:08) [51]


В общем, все со мной ясно... :-)


Сергей М.   (2006-05-10 10:42:00) [10]


> Дмитрий Л. ©   (10.05.06 10:14) [52]


Для NT - да.


Дмитрий Л.   (2006-05-10 10:14:00) [11]


> Сергей М. ©   (10.05.06 10:08) [51]


Device\PhysicalMemory ?


Сергей М.   (2006-05-10 10:08:00) [12]

Мда ..
Портом статуса здесь явно не пахнет, ввод организован по прерыванию ..
А фигурировал бы порт статуса - можно было бы выкрутиться.

В принципе можно, конечно, обойтись и без драйвера (прямой доступ к GDT, IDT), но способ этот малонадежен (из разряда трюков) и даже более трудоемок в реализации.


!Fobos   (2006-05-10 09:55:00) [13]


> Anatoly Podgoretsky ©   (10.05.06 09:50) [47]

Обнадеживающе...=((


!Fobos   (2006-05-10 09:54:00) [14]

procedure interupt;
interrupt;
var i:integer;
begin
   PORT[$20]:=0;
   port[$21]:=32;
   portw[start_]:=$0000;
   for i:=0 to 5 do
     DATA[i]:=port[start_];
   for i:=0 to 32761 do
     DATA[i]:=port[start_];
   onoff(0);
   ct:=0;draw(100,tiold);
   {start;}
   PORT[$20]:=32;
   PORT[$21]:=0;
end;

.........
.........
.........

getintvec(Int, Save_vec);        // Int=$0D;   Save_vec:pointer
 setintvec(Int, @Interupt);
 ttt:=port[$20]+32;               // ttt:byte;

 PORT[$20]:=32;
 PORT[$21]:=0;

...........
..........
...........


Сергей М.   (2006-05-10 09:51:00) [15]


> !Fobos ©   (10.05.06 09:49) [46]


Зачем весь ?

Только те фрагменты, где осуществляется собственно ввод-вывод и где выполняется программирование прерываний..


Anatoly Podgoretsky   (2006-05-10 09:50:00) [16]

!Fobos ©   (10.05.06 09:15) [44]
Забудь про диплом, за оставшее время драйвер написать не успеешь.


!Fobos   (2006-05-10 09:49:00) [17]


> Сергей М. ©   (10.05.06 09:40) [45]

Весь? Там что-то около 600-700 строк!!!


Сергей М.   (2006-05-10 09:40:00) [18]

Покажи соотв.код "на паскалевском варианте" ..


!Fobos   (2006-05-10 09:15:00) [19]


> Сергей М. ©   (10.05.06 08:56) [43]


На самом деле никого не волнует, вслепую я буду разбираться или нет. Эксперементировать уже нету времени, диплом надо сдать меньше чем через месяц, а его еще писать надо....плюс госы учить. Препод, который дал задание, в программировании шарит еще меньше меня и объяснять ему мои проблемы, думаю, смысла нету.
Ну если другого выхода нет, то всем большое спасибо за участие! =)


Сергей М.   (2006-05-10 08:56:00) [20]


> !Fobos ©   (10.05.06 08:45) [42]


Ну почему же зря ?
Опыт - он, как известно, сын ошибок трудных ..

Но вряд ли есть смысл разбираться с дивайсом "вслепую", не имея достаточно подробной документации с описанием протокола инф.обмена, назначения портов ввода-вывода, псевдокода алгоритмов ввода-вывода и т.д. и т.п.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо