⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hw_32.pas

📁 关于利用DELPHI来进行企业级方案解决的著作的附书源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                    CtlCode(_DRV_SET_POST_EVENT),
                    @fLocEvent, sizeof(fLocEvent),
		    NIL, 0, nByte, POverlapped(NIL));
    dwIRQ := fIRQNumber;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_SET_INT_VEC),
                    @dwIRQ, sizeof(dwIRQ),
		    NIL, 0, nByte, POverlapped(NIL));

    fMasked   := FALSE;
    DeviceIoControl(hDrv,
	     	        CtlCode(_DRV_UNMASK_INT_VEC),
		            NIL, 0, NIL, 0,
		            nByte, POverlapped(NIL));

    while (TRUE) do
    begin

      WaitForSingleObject(fLocEvent, INFINITE);

      if (not fTerminated) then
      begin
        if (LPT_BASE_PORT<>0) and (L_BUF_LPT>0) then
        begin
          sel := N_SEL_LPT;
          wrd := BUF_LPT[sel];
	  Inc(sel);
	  sel := sel and (MAX_BUF_LPT);
          N_SEL_LPT := sel;
          Dec(L_BUF_LPT);
        end;
	if Assigned(fOnHWInterrupt) then
            OnHwInterrupt(HW32,Drv_IRQ_Counter,Hi(wrd),Lo(wrd),ScanCode);
      end
      else
	 break;
    end;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_STOP_INT_VEC),
		    NIL, 0, NIL, 0,
		    nByte, POverlapped(NIL));

    CurrentProcess := GetCurrentProcess();
    SetPriorityClass(CurrentProcess, NORMAL_PRIORITY_CLASS);
  end;
end;

procedure IRQProc95(HW32 : TVicHw32); stdcall;

var  nByte,Count,fHandled,dwIRQ : DWORD;
     CurrentProcess             : THandle;
     pl                         : PLockedBuffer;
     wrd,sel                    : Word;
begin
  pl  := PLockedBuffer(HW32.fpLockedMemory);
  with HW32,pl^ do
  begin
    wrd := 0;
    fHandled:=0;
    CurrentProcess := GetCurrentProcess();
    SetPriorityClass(CurrentProcess, REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

    DeviceIoControl(hDrv,
                    CtlCode(_DRV_SET_POST_EVENT),
                    @hDrvEvent, sizeof(hDrvEvent),
		    NIL, 0, nByte, POverlapped(NIL));

    dwIRQ := fIRQNumber;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_SET_INT_VEC),
                    @dwIRQ, sizeof(dwIRQ),
		    NIL, 0, nByte, POverlapped(NIL));

    fMasked   := FALSE;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_UNMASK_INT_VEC),
		    NIL, 0, NIL, 0,
		    nByte, POverlapped(NIL));

    while (TRUE) do
    begin

      WaitForSingleObject(fLocEvent, INFINITE);
      ResetEvent(fLocEvent);

      if (not fTerminated) then
      begin

        Count := Drv_IRQ_Counter;

        while (fHandled<Count) do
        begin
          Inc(fHandled);
          if (fIRQNumber = 7) and (L_BUF_LPT>0) then
          begin
            sel := N_SEL_LPT;
            wrd := BUF_LPT[sel];
	    Inc(sel);
	    sel := sel and (MAX_BUF_LPT);
            N_SEL_LPT := sel;
            Dec(L_BUF_LPT);
          end;
	  if Assigned(fOnHWInterrupt) then
               OnHwInterrupt(HW32,Drv_IRQ_Counter,Hi(wrd),Lo(wrd),ScanCode);
        end;
      end
      else
        break;
    end;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_STOP_INT_VEC),
		    NIL, 0, NIL, 0,
		    nByte, POverlapped(NIL));

    CurrentProcess := GetCurrentProcess();
    SetPriorityClass(CurrentProcess, NORMAL_PRIORITY_CLASS);

  end;
end;

procedure TVicHW32.ClearFields;
begin
  hDrv            := INVALID_HANDLE_VALUE;
  fRegistry       := TRUE;
  fStarted        := TRUE;
  fTerminated     := FALSE;

  fInterface      := 0;
  fBus 		  := 0;
  fPhysLoPart     := 0;
  fPhysHiPart     := 0;
  fTypeMem        := 0;
  fMemorySize     := 0;

  fDebugCode      := 0;

  FillChar(fMappedPointers,4*MaxMappedAreas,0);
  FillChar(fMappedSizes,4*MaxMappedAreas,0);
  FillChar(fMappedAddresses,4*MaxMappedAreas,0);
  fMappedAreas    := 0;

  fHardAccess     := TRUE;

  fIsIRQSet       := (fIRQNumber>0) and (fIRQNumber<16);
  fMasked         := TRUE;
  fOpenDrive      := FALSE;

end;

constructor TVicHW32.Create(Owner:TComponent); {==}
begin
  inherited Create(Owner);
  fWin95:= (GetVersion() and $80000000)<>0;
  ClearFields();
  fDriverName := {$ifdef DEMOVERSION} 'VICHW00' {$else} 'VICHW11' {$endif};
  fSDriverName := StrPas(fDriverName);
  if fWin95 then
  begin
    StrPCopy(fPathToDriver,'\\.\'+fSDriverName+'.VXD');
    hDll          := GetModuleHandle('kernel32');
    OpenVxdHandle := TOpenVxdHandle(GetProcAddress(hDll,'OpenVxDHandle'));
    fLocEvent     := CreateEvent(NIL, TRUE, FALSE, NIL);
    hDrvEvent     := OpenVxDHandle(fLocEvent);
  end
  else
  begin
    GetWindowsDirectory(fPathToDriver,128);
    StrCat(fPathToDriver,'\SYSTEM32\DRIVERS\');
    StrCat(fPathToDriver,fDriverName);
    StrCat(fPathToDriver,'.SYS');
    StrPCopy(fShortPathToDriver,'\\.\'+fSDriverName);
    fLocEvent := CreateSemaphore(NIL, 0, 1000, NIL);
  end;
end;

destructor TVicHW32.Destroy;                   {==}
begin
  CloseDriver();
  ClearFields();
  if fWin95 then
  begin
    CloseHandle(hDrvEvent);
    CloseHandle(hDll);
  end;
  CloseHandle(fLocEvent);
  inherited Destroy;
end;

procedure  TVicHW32.SetIRQMasked(bNewValue  : Boolean);
var nByte : DWORD;
begin
  if (fOpenDrive and fIsIRQSet) then
  begin
    if (bNewValue) then
    begin
      if (not fMasked) then
      begin
        fMasked := TRUE;
        DeviceIoControl(hDrv,
                        CtlCode(_DRV_MASK_INT_VEC),
			NIL, 0, NIL, 0,
			nByte, POverlapped(NIL));
        fTerminated := true;

        if  fWin95 then SetEvent(fLocEvent)
	else ReleaseSemaphore(fLocEvent, 1, NIL);

        WaitForSingleObject(fThreadHandle,INFINITE);

        CloseHandle(fThreadHandle);
        
      end;
    end
    else begin
	   if fMasked then
           begin
             with PLockedBuffer(fpLockedMemory)^ do
             begin
               {$ifdef DEB_NOT_LPT}
                  LPT_BASE_PORT := $300;
               {$ELSE}
                  LPT_BASE_PORT := fLPTBasePort;
               {$ENDIF}
               MAX_BUF_LPT   := MAX_RING_BUFFER;
               L_BUF_LPT     := 0;
               N_ADD_LPT     := 0;
	       N_SEL_LPT     := 0;
             end;
             fTerminated := FALSE;

             if (fWin95) then
                fThreadHandle := CreateThread(NIL,
				      	   0,
					   @IRQProc95,
					   self,
					   0,
					   fThreadId)
             else
                fThreadHandle := CreateThread(NIL,
					   0,
					   @IRQProcNT,
					   self,
					   0,
					   fThreadId);
	   end;

         end;

  end;
end;

procedure  TVicHW32.SetIRQNumber(nNewValue  : Byte);
begin
  if (nNewValue>0) and (nNewValue<16) then
  begin
    if (not fMasked) and fOpenDrive then SetIRQMasked(TRUE);
    fIRQNumber := nNewValue;
    fIsIRQSet := TRUE;
  end;
end;

procedure TVicHW32.CloseDriver;
var nByte : DWORD;
    i     : Byte;
begin
  if fOpenDrive then
  begin
    SetHardAccess(TRUE);
    if not fMasked then SetIRQMasked(TRUE);
    fOpenDrive := FALSE;
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_UNMAP_LPT_AREA),
		    @fLPTAddresses,4,
		    @fLPTAddresses,4,
		    nByte,POverlapped(NIL));
    DeviceIoControl(hDrv,
                    CtlCode(_DRV_UNLOCK_MEMORY),
		    @fMdl,4,
		    @fMdl,4,
		    nByte,POverlapped(NIL));
    for i:=1 to fMappedAreas do
       UnmapMemory(fMappedAddresses[i],fMappedSizes[i]);

    CloseStopUnloadDriver();
  end;
end;



function TVicHW32.OpenDriver : Boolean;
type TLocRec = record  pBuf : Pointer; Sz : DWORD; end;
var  Rec     : TLocRec;
     nByte   : DWORD;
     i       : Byte;
begin

  Result:=fOpenDrive;
  if fOpenDrive then Exit;

  ClearFields();
  fLPTBasePort := $378;
  fLPTNumber := 1;

  InstallStartLoadDriver();

  if (hDrv = INVALID_HANDLE_VALUE) then
  begin
    CloseStopUnloadDriver();
    InstallStartLoadDriver();
    if hDrv = INVALID_HANDLE_VALUE then Exit;
  end;
  fOpenDrive  := TRUE;
  Result      := TRUE;
  fPhysLoPart := $408;
  fMemorySize := 6;
  DeviceIoControl(hDrv,
		  CtlCode(_DRV_MAP_MEMORY),//LPT_AREA),
		  @fInterface,24,
		  @fLPTAddresses,4,
		  nByte,POverlapped(NIL));
  if (fLPTAddresses<>NIL) then
  begin
    for  i:=1 to 3 do
       if fLPTAddresses^[i] <> 0  then Inc(fLPTs);

    fLPTBasePort := fLPTAddresses^[1];
  end  
  else begin
         fLPTBasePort :=$378;
       end;

  fLPTNumber   := 1;

  fpLockedMemory := VirtualAlloc(NIL,4096,MEM_COMMIT,PAGE_READWRITE);

  Rec.pBuf := fpLockedMemory;
  Rec.Sz   := 4096;
  DeviceIoControl(hDrv,
                  CtlCode(_DRV_LOCK_MEMORY),
                  @Rec,8,@fMdl,4,
                  nByte,POverlapped(NIL));
  with PLockedBuffer(fpLockedMemory)^ do
  begin
    {$ifdef DEB_NOT_LPT}
       LPT_BASE_PORT := $300;
    {$ELSE}
       LPT_BASE_PORT := fLPTBasePort;
    {$ENDIF}
    MAX_BUF_LPT   := MAX_RING_BUFFER;
    L_BUF_LPT     := 0;
    N_ADD_LPT     := 0;
    N_SEL_LPT     := 0;
  end;
end;


function  TVicHW32.GetPortB(PortAddr:Word):Byte;
var nByte,PortNumber,DataPort : DWORD;
begin
  if not ActiveHW then begin Result:=$ff; Exit; end;
  PortNumber:=PortAddr;
  if HardAccess then
  begin
      DeviceIoControl(hDRV,
                      CtlCode(_DRV_HARD_READ_PORT),
                      @PortNumber,4,@DataPort,4,
                      nByte,pOverlapped(NIL))
  end                    
  else begin
         asm
           mov dx,word ptr PortNumber
           in  al,dx
           mov byte ptr DataPort,al
         end;
       end;
  Result:=Lo(LoWord(DataPort));
end;

function  TVicHW32.GetPortW(PortAddr:Word):Word;
var nByte,PortNumber,DataPort : DWORD;
begin
  if not ActiveHW then begin Result:=$ff; Exit; end;
  PortNumber:=PortAddr;
  if HardAccess then
  begin
    DeviceIoControl(hDRV,
                    CtlCode(_DRV_HARD_READ_PORTW),
                    @PortNumber,4,@DataPort,4,
                    nByte,pOverlapped(NIL));
  end
  else begin
         asm
            mov dx,word ptr PortNumber
            in  ax,dx
            mov word ptr DataPort,ax
         end;
       end;
  Result:=LoWord(DataPort);
end;

function  TVicHW32.GetPortL(PortAddr:Word):DWORD;
var nByte,PortNumber,DataPort : DWORD;
begin
  if not ActiveHW then begin Result:=$ff; Exit; end;
  PortNumber:=PortAddr; DataPort:=0;
  if HardAccess then
  begin
    DeviceIoControl(hDRV,
                    CtlCode(_DRV_HARD_READ_PORTL),
                    @PortNumber,4,@DataPort,4,
                    nByte,pOverlapped(NIL));
  end
  else begin
         asm
            mov dx,word ptr PortNumber
            in  eax,dx
            mov DataPort,eax
         end;
       end;
  Result:=DataPort;
end;

procedure   TVicHW32.SetPortB(PortAddr : Word; nNewValue: Byte);
var nByte : DWORD;
    Rec   : record
     PortNumber:DWORD;
     DataPort  :DWORD;
    end;
begin
  if not ActiveHW then Exit;
  if HardAccess then
  begin
    Rec.PortNumber:=PortAddr; Rec.DataPort:=nNewValue;
    DeviceIoControl(hDRV,
                    CtlCode(_DRV_HARD_WRITE_PORT),
                    @Rec,8,NIL,0,
                    nByte,pOverlapped(NIL));
  end
  else begin
         asm
           mov al,nNewValue
           mov dx,PortAddr
           out dx,al
         end;
       end;
end;

procedure   TVicHW32.SetPortW(PortAddr : Word; nNewValue: Word);
var nByte : DWORD;
    Rec   : record

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -