Driver development using PureBasic

Developed or developing a new product in PureBasic? Tell the world about it.
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Driver development using PureBasic

Post by User_Russian »

A small addition to PureBasic, allowing you to create kernel-mode drivers for Windows. http://pure-basic.narod.ru/forum_files/ ... Plugin.zip
Addition is intended to PureBasic 5.10.

Installation guide.
Install, PureBasic 5.10 (demo or full version) to any folder.
Open a folder "Compilers" and rename the file "Fasm.exe" in "Fasm_.exe", and the file "Polink.exe" in "Polink_.exe".
Extract the archive to a folder with PureBasic.
Example of a simple driver.

Code: Select all

Declare DriverEntry(*DriverObject, *RegistryPath)

*A=@DriverEntry()
!jmp [p_A]

ImportC "ntoskrnl.lib"
  DbgPrint(String.s)
EndImport

Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
    
  DbgPrint("LoadDriver")
    
  ; Reports an error, for system to unload driver.
  ProcedureReturn #STATUS_DEVICE_CONFIGURATION_ERROR
EndProcedure
Create the driver of the code (Compiler -> Create Executable ...), with the name "Simple_driver.sys".
Run the program "Dbgview.exe" and "KmdManager.exe", which are in a folder "Tools".
Open the program "KmdManager.exe", driver "Simple_driver.sys".

Warning, this is further actions can lead to BSoD!

Click on the buttons in sequence "Register", "Run", "Stop" and "Unregister".
If done correctly, the debugger "Dbgview.exe" appears "LoadDriver".

Image

---------------------

In folder with examples have these examples, a simple driver, how to work with kernel memory and example drivers direct access to ports, similar Inpout32.dll.

--------------------

New version 2.2. http://www.purebasic.fr/english/viewtop ... 34#p458334
Last edited by User_Russian on Mon Dec 22, 2014 10:48 pm, edited 3 times in total.
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Driver development using PureBasic

Post by jassing »

Nice! So same stuff will work in x64 and x86? Very slick.
Last edited by jassing on Thu Feb 14, 2013 4:53 pm, edited 1 time in total.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Re: Driver development using PureBasic

Post by Inf0Byt3 »

Interesting :). This might come in handy sometime. Thanks for sharing.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Driver development using PureBasic

Post by User_Russian »

jassing wrote:Nice! So same stuff will work in x64 and x86? Very slick.
To create the x64 drivers to compile programs and libraries for this platform (see the folder "src").
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Driver development using PureBasic

Post by User_Russian »

Consider another example, buyout shows how to work with the kernel memory and how to get a list of loaded modules.

Code: Select all

Declare DriverEntry(*DriverObject, *RegistryPath)

ImportC "ntoskrnl.lib"
	DbgPrint(*String)
	memset(*mem, Byte, Size)
EndImport

Import "ntoskrnl.lib"
  ZwQuerySystemInformation(SysInfoClass, *SysInfo, SysInfoLength.l, *ReturnLength)
  ExAllocatePool(PoolType, NumBytes)
  ExFreePool(*Point)
EndImport

!extrn _memset

 *A=@DriverEntry()
!jmp [p_A]

XIncludeFile "StringDr.pbi"

EnableExplicit

Structure DrArray_SMI
  Arrays.SYSTEM_MODULE_INFORMATION[1]
EndStructure

Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
  Protected cb.l, *p, *pArray.DrArray_SMI
  Protected dwNumModules.l
  Protected Buffer.s{128}, Temp
  
  DbgPrint(@"LoadDriver")
  
  cb=0
  ZwQuerySystemInformation(#SystemModuleInformation, @*p, 0, @cb)
  If cb <> 0 ;
    cb + 32
    *p = ExAllocatePool(#PagedPool, cb)
    If *p<>#Null
      If ZwQuerySystemInformation(#SystemModuleInformation, *p, cb, @cb)= #STATUS_SUCCESS

        
        PokeS(@Buffer, "Bytes:  ") : Temp=8
        Temp+StrDr(@Buffer+Temp, 128-Temp, cb)
        PokeS(@Buffer+Temp, ";  Address: 0x") : Temp+14
        Temp+HexDr(@Buffer+Temp, 128-Temp, *p)
        PokeS(@Buffer+Temp, ";  Modules: ") : Temp+12
        Temp+StrDr(@Buffer+Temp, 128-Temp, dwNumModules)
        
        DbgPrint(@Buffer)
        memset(@Buffer, 0, 128)
        
        
        *pArray = *p
        dwNumModules = PeekL(*pArray)
        *pArray + 4
        
        Temp=0
        While Temp < dwNumModules

          DbgPrint(@*pArray\Arrays[Temp]\ImageName[0])
          
          Temp+1
        Wend
          
      EndIf
      
      ExFreePool(*p)
    EndIf
  EndIf
  
	ProcedureReturn #STATUS_DEVICE_CONFIGURATION_ERROR  ;#STATUS_SUCCESS
EndProcedure
Run the program "Dbgview.exe" and "KmdManager.exe"
Click on the buttons in sequence "Register", "Run", "Stop" and "Unregister".

In the debugger, you will see the current list of loaded modules.

Image
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Re: Driver development using PureBasic

Post by Rings »

thx alot, amazing stuff !!!
SPAMINATOR NR.1
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 448
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Driver development using PureBasic

Post by Didelphodon »

finally! can't wait to give it a try :-)
Go, tell it on the mountains.
sec
Enthusiast
Enthusiast
Posts: 789
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: Driver development using PureBasic

Post by sec »

Wy do we need replace fasm, polink?
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Driver development using PureBasic

Post by User_Russian »

Do not need to be replaced.
Need rename.
Install, PureBasic 5.10 (demo or full version) to any folder.
Open a folder "Compilers" and rename the file "Fasm.exe" in "Fasm_.exe", and the file "Polink.exe" in "Polink_.exe".
Extract the archive to a folder with PureBasic.
To create a driver, you need a preprocessor between "pbcompiler.exe" and "Fasm.exe" and "Polink.exe".
This is most easily done by renaming the original file and used in place of their own, and that was done.
In folder "src" you can find the source code for the preprocessor "Fasm.exe" and "Polink.exe".
Thorium
Addict
Addict
Posts: 1271
Joined: Sat Aug 15, 2009 6:59 pm

Re: Driver development using PureBasic

Post by Thorium »

Awesome!
Thanks for sharing.
Nituvious
Addict
Addict
Posts: 998
Joined: Sat Jul 11, 2009 4:57 am
Location: United States

Re: Driver development using PureBasic

Post by Nituvious »

Wow, very cool! I thought driver creation was assumed to be impossible with PureBasic?
▓▓▓▓▓▒▒▒▒▒░░░░░
Thorium
Addict
Addict
Posts: 1271
Joined: Sat Aug 15, 2009 6:59 pm

Re: Driver development using PureBasic

Post by Thorium »

Nituvious wrote:Wow, very cool! I thought driver creation was assumed to be impossible with PureBasic?
It was... until now!
User_Russian
Addict
Addict
Posts: 1441
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Driver development using PureBasic

Post by User_Russian »

The previous examples were more theoretical.
Consider one more example driver. This is a complete driver, which can be used not only by example, but also be used in your program. If someone had to work with the ports of the computer, then perhaps you know that modern operating systems Windows, based on the core NT, do not allow direct access to the ports of the user application. In other words, a user-mode prohibited assembly instructions "IN" and "OUT". But these instructions are allowed in kernel mode, if you create a driver, which on command, the user program will work with a given port, the program will be able to using driver to read or write data to the required port. :D
But as we know, everything is invented before us, and there is such a project, as a library Inpout32.dll. http://logix4u.net/
Let's create using PureBasic its analogue. :)

First we create a kernel mode driver.

Code: Select all

Declare DriverEntry(*DriverObject, *RegistryPath)

; Import kernel function of "ntoskrnl.exe".
Import "ntoskrnl.lib"
  IoCompleteRequest(*IRP, PriorityBoost)
  RtlInitUnicodeString(*UString, *String)
  IoCreateDevice(*DriverObject, DeviceExtensionSize, 
                 *UDeviceName, DeviceType,
                 DeviceCharacteristics, Exclusive, *DeviceObject)
  IoDeleteDevice(*DeviceObject)
  IoCreateSymbolicLink(*SymbolicLinkName, *DeviceName)
  IoDeleteSymbolicLink(*SymbolicLinkName)
EndImport


#IOCTL_READ_PORT_UCHAR	 = $200 
#IOCTL_WRITE_PORT_UCHAR	 = $400

; Entry point in main function the driver.
*EntryPoint = @DriverEntry()
!jmp [p_EntryPoint]

EnableExplicit

; Direct write in port.
Procedure.a InPort(Port.u)
  Protected Result.a=0
  EnableASM
  MOV DX, Port
  IN  al,DX
  MOV Result, al
  DisableASM
  ProcedureReturn Result
EndProcedure

; Direct reading from port.
Procedure OutPort(Port.u, Byte.a)
  EnableASM
  MOV al, Byte
  MOV DX, Port
  OUT DX, al
  DisableASM
EndProcedure

; This procedure, called kernel manager,
; calling WinAPI functions DeviceIoControl_().
Procedure DeviceIoControl(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
  Protected ntStatus, *Point, *Stack.IO_STACK_LOCATION
  Protected InBuffersize, OutBuffersize, CtrlBuff
  Protected Port.u, Byte.a, InByte.a, Code
  
  *Stack = *pIrp\Tail\Overlay\CurrentStackLocation
  
  ; This is the "dwIoControlCode", sent messages of WinAPI functions DeviceIoControl_().
  Code = *Stack\Parameters\DeviceIoControl\IoControlCode
  
  ; This is the "nInBufferSize", sent messages of WinAPI functions DeviceIoControl_().
  InBuffersize = *Stack\Parameters\DeviceIoControl\InputBufferLength
  
  ; This is the "nOutBufferSize", sent messages of WinAPI functions DeviceIoControl_().
  OutBuffersize = *Stack\Parameters\DeviceIoControl\OutputBufferLength
  
  ; This is the "lpInBuffer", sent messages of WinAPI functions DeviceIoControl_().
  CtrlBuff   = PeekI(*pIrp\SystemBuffer)
  Port = CtrlBuff & $FFFF
  
  ntStatus = #STATUS_SUCCESS ; This value returns WinAPI functions DeviceIoControl_().
  
  Select Code
    Case #IOCTL_READ_PORT_UCHAR ; Reading from a port.
      InByte=InPort(Port)  ; 
      PokeA(*pIrp\SystemBuffer, InByte) ; Read a byte from the port is placed in a buffer.
      *pIrp\IoStatus\Information = 1    ; In buffer, write 1 byte.
      
    Case #IOCTL_WRITE_PORT_UCHAR ; Writing in Port.
      Byte = (CtrlBuff>>16)&255
      OutPort(Port, Byte)
      *pIrp\IoStatus\Information = 0  ; In buffer, write 0 byte.
      
    Default                          ; The command is not supported.
      ntStatus = #STATUS_UNSUCCESSFUL
      *pIrp\IoStatus\Information = 0  ; In buffer, write 0 byte.
  EndSelect
  
  ; Message processed.
  ; More information. http://msdn.microsoft.com/en-us/library/windows/hardware/ff548343(v=vs.85).aspx
  *pIrp\IoStatus\Status = ntStatus
  IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
  
  ProcedureReturn ntStatus
EndProcedure


Procedure CreateDispatch(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
  
  *pIrp\IoStatus\Information = 0
  *pIrp\IoStatus\Status = #STATUS_SUCCESS
  IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
  
  ProcedureReturn #STATUS_SUCCESS
EndProcedure

; Procedure for unloading driver.
Procedure UnloadDriver(*DriverObject.DRIVER_OBJECT)
  Protected uniDOSString.UNICODE_STRING
  
  RtlInitUnicodeString(@uniDOSString, ?DosDevices)
  IoDeleteSymbolicLink (@uniDOSString)
  IoDeleteDevice(*DriverObject\DeviceObject)
  
EndProcedure

; Procedure initialize driver.
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
  Protected deviceObject.DEVICE_OBJECT
  Protected uniNameString.UNICODE_STRING
  Protected uniDOSString.UNICODE_STRING
  Protected status
  
  RtlInitUnicodeString(@uniNameString, ?Device)
  RtlInitUnicodeString(@uniDOSString, ?DosDevices)
  
  status = IoCreateDevice(*DriverObject, 0, @uniNameString, #FILE_DEVICE_UNKNOWN, 0, #False, @deviceObject)
  If status <> #STATUS_SUCCESS
    ProcedureReturn status
  EndIf
  
  status = IoCreateSymbolicLink(@uniDOSString, @uniNameString)
  If status <> #STATUS_SUCCESS
    IoDeleteDevice(@deviceObject) ; We need to remove an object!
                                  ; In mode kernel, of system will
                                  ; not do it even after unloading the driver!
    ProcedureReturn status
  EndIf
  
  
  ; Registration procedures.
  *DriverObject\DriverUnload = @UnloadDriver() ; Procedure for unloading drivers
  *DriverObject\MajorFunction[#IRP_MJ_CREATE] = @CreateDispatch() ; Called when WinAPI, CreateFile_().
  *DriverObject\MajorFunction[#IRP_MJ_CLOSE] = @CreateDispatch() ; Called when WinAPI, CloseHandle_().
  *DriverObject\MajorFunction[#IRP_MJ_DEVICE_CONTROL] = @DeviceIoControl() ; ; Called when WinAPI, DeviceIoControl_().
  
  ProcedureReturn #STATUS_SUCCESS
EndProcedure



; Name of the driver in system.
DataSection
  Device:
  !du '\Device\pbdriverio', 0, 0
  
  DosDevices:
  !du '\DosDevices\pbdriverio', 0, 0
EndDataSection
When you load the driver, will be performed the procedure code DriverEntry(), in which the driver, register (to him will be assigned symbolic names that can be used in CreateFile_()) and will be assigned to unload the driver procedure and call processing WinAPI functions CreateFile_(), CloseHandle_() and DeviceIoControl_().
In procedure of DeviceIoControl() driver that handles the request of the same name WinAPI function, with which the data transmitted to the driver and received from him.
Procedure processes the two queries:
#IOCTL_READ_PORT_UCHAR ; Reading from a port.
#IOCTL_WRITE_PORT_UCHAR ; Writing in Port.
Upon receipt of the first request, the called is procedure InPort (), which performed read data from the port.
Upon receipt of the second request, it calls the procedure OutPort (), writes the data to the port.

----------

Now for a code library (DLL), is being called from the driver. This is just an example. Not necessarily that the driver was in a DLL. It may invoke a directly of the program's.

Code: Select all

#IOCTL_READ_PORT_UCHAR	 = $200 
#IOCTL_WRITE_PORT_UCHAR	 = $400

CompilerIf Defined(PBIO_OK, #PB_Constant)=0
  Enumeration
    #PBIO_OK
    #PBIO_ErrCopyDriver
    #PBIO_ErrInstallDriver
    #PBIO_ErrAccess
  EndEnumeration
CompilerEndIf

Structure Param_Info
  hDriverID.i
  ErrStatus.i
  DrFileName.s
  DriverName.s
  *Point
  Len.i
EndStructure


Declare OpenDriver()
Declare Driver_UnInstall(Drivers_Name.s)

EnableExplicit


ProcedureDLL AttachProcess(Instance)
  
  Global ParamInfo.Param_Info
  
  
  ParamInfo\ErrStatus=#PBIO_OK
  ParamInfo\DrFileName = GetTemporaryDirectory()+"pbdriverio.sys"
  ParamInfo\DriverName = "pbdriverio"
  
  ParamInfo\Point = ?Driver
  ParamInfo\Len   = ?DriverEnd-?Driver
  
  ParamInfo\hDriverID = OpenDriver()
EndProcedure


ProcedureDLL DetachProcess(Instance)
  If ParamInfo\hDriverID
    CloseHandle_(ParamInfo\hDriverID)
    ParamInfo\hDriverID=0
  EndIf
  
  ; Unloading drivers
;  Driver_UnInstall(ParamInfo\DriverName)
;   If FileSize(ParamInfo\DrFileName)>0
;     DeleteFile(ParamInfo\DrFileName)
;   EndIf
EndProcedure


Procedure Driver_Start(Drivers_Name.s)
  Protected hSCManager.i, hServ.i
  Protected ErrorCode, Result
  
  Result=#False
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  If hSCManager = 0
    If GetLastError_() = #ERROR_ACCESS_DENIED
      hSCManager  = OpenSCManager_(#Null, #Null, #GENERIC_READ)
      hServ       = OpenService_(hSCManager, Drivers_Name, #GENERIC_EXECUTE)
      If StartService_(hServ, 0, #Null)
        Result=#True
      EndIf
    EndIf
    
  Else
    hServ       = OpenService_(hSCManager, Drivers_Name, #GENERIC_EXECUTE)
    If StartService_(hServ, 0, #Null)
      Result=#True  
    Else
      ErrorCode=GetLastError_()
      If ErrorCode=1056
        Result=#True
      EndIf
    EndIf
  EndIf
  
  If hServ : CloseServiceHandle_(hServ) : EndIf
  If hSCManager : CloseServiceHandle_(hSCManager) : EndIf
  
  ProcedureReturn Result
EndProcedure


Procedure Driver_UnInstall(Drivers_Name.s)
  Protected hSCManager.i, hServ.i
  Protected ServiceStatus.SERVICE_STATUS
  
  hSCManager  = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
  hServ       = OpenService_(hSCManager, Drivers_Name, #SERVICE_ALL_ACCESS)
  
  If hServ<>#Null
     ControlService_(hServ, #SERVICE_CONTROL_STOP, @ServiceStatus)
     DeleteService_(hServ)
  EndIf
  
  If hServ : CloseServiceHandle_(hServ) : EndIf
  If hSCManager : CloseServiceHandle_(hSCManager) : EndIf
EndProcedure


Procedure Driver_Install(Drivers_Name.s)
  Protected Result, FileID, File.s, Mgr
  Protected ErrorCode, Ser, Count
  Result=#False
  Count=0 : FileID=0 : Mgr=0 : Ser=0

  File=ParamInfo\DrFileName
  
  
  If FileSize(File) <> ParamInfo\Len Or CRC32FileFingerprint(File) <> CRC32Fingerprint(ParamInfo\Point, ParamInfo\Len)
    
    FileID=CreateFile(#PB_Any, File)
    If FileID
      WriteData(FileID, ParamInfo\Point, ParamInfo\Len)
      CloseFile(FileID)
    ElseIf ParamInfo\ErrStatus = #PBIO_OK
      ParamInfo\ErrStatus = #PBIO_ErrCopyDriver
    EndIf
    
  Else
    FileID=2
  EndIf
  
  If FileID
    
    Driver_Install_M1:
    Mgr = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
    If Mgr
      Ser = CreateService_(Mgr, Drivers_Name, Drivers_Name, #SERVICE_ALL_ACCESS, #SERVICE_KERNEL_DRIVER, #SERVICE_DEMAND_START, #SERVICE_ERROR_NORMAL, File, #Null, 0, 0, 0, 0)
      ErrorCode=GetLastError_()
      If Ser 
        Result=#True 
      ElseIf ErrorCode=1073
        Result=#True 
      ElseIf ErrorCode=1072
        If Count=0
          
          If Ser : CloseServiceHandle_(Ser) : EndIf
          If Mgr : CloseServiceHandle_(Mgr) : EndIf
          Driver_UnInstall(Drivers_Name)
          Count+1
          Goto Driver_Install_M1
        EndIf
      EndIf
    EndIf
    
  EndIf
  
  If Ser : CloseServiceHandle_(Ser) : EndIf
  If Mgr : CloseServiceHandle_(Mgr) : EndIf
  
  If Result=#False And ParamInfo\ErrStatus = #PBIO_OK
    ParamInfo\ErrStatus = #PBIO_ErrInstallDriver
  EndIf
  
  ProcedureReturn Result
EndProcedure

Procedure OpenDriver()
  Protected Result, hDriver
  Result=0
  
  hDriver = CreateFile_("\\.\"+ParamInfo\DriverName, #GENERIC_READ | #GENERIC_WRITE, 0, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
  If hDriver=#INVALID_HANDLE_VALUE
    If Driver_Install(ParamInfo\DriverName)
      If Driver_Start(ParamInfo\DriverName)
        hDriver = CreateFile_("\\.\"+ParamInfo\DriverName, #GENERIC_READ | #GENERIC_WRITE, 0, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
        If hDriver <> #INVALID_HANDLE_VALUE
          Result=hDriver
        EndIf
      EndIf
    EndIf
  Else
    Result=hDriver
  EndIf
  
  If Result=0 And ParamInfo\ErrStatus = #PBIO_OK
    ParamInfo\ErrStatus = #PBIO_ErrAccess
  EndIf
  
  ProcedureReturn Result
EndProcedure


ProcedureDLL Inp(PortAddress.u) ; Read a byte from the port, address given in 'PortAddress'.
  Protected Result, Buffer.i, BytesReturned.i, OutBuff.i
  Result=0 : Buffer=0 : OutBuff=0
  
  If ParamInfo\hDriverID
    Buffer=PortAddress
     DeviceIoControl_(ParamInfo\hDriverID, #IOCTL_READ_PORT_UCHAR, @Buffer, 2, @OutBuff, 1, @BytesReturned, 0)
    Result=OutBuff
  EndIf
  
  ProcedureReturn Result
EndProcedure

ProcedureDLL Out(PortAddress.u, Byte.a) ; Writing a byte to the port, address given in 'PortAddress'.
  Protected Result, Buffer.i, BytesReturned.i
  Result=0
  
  If ParamInfo\hDriverID
    Buffer=PortAddress
    PokeA(@Buffer+2, Byte)
   DeviceIoControl_(ParamInfo\hDriverID, #IOCTL_WRITE_PORT_UCHAR, @Buffer, 3, 0, 0, @BytesReturned, 0)
  EndIf
  
  ProcedureReturn Result
EndProcedure


ProcedureDLL Status() ; Status of the driver. If there are no errors, then 0.
  ProcedureReturn ParamInfo\ErrStatus
EndProcedure


ProcedureDLL.f Version()
  ProcedureReturn 1.4
EndProcedure


DataSection
  Driver:
  IncludeBinary "Driver\pbdriverio.sys"
  DriverEnd::
EndDataSection
The library in the first place trying to call the driver on his symbolic name "\\.\pbdriverio".
If she fails, then checks to see if the driver on the disk and, if necessary, the driver is extracted from the library to the disk, and then registers in the system. Then, again, tries to call the driver on his name symbols.

From the library exports several functions.
Inp(PortAddress.u) ; Read a byte from the port, address given in 'PortAddress'.

Out(PortAddress.u, Byte.a) ; Writing a byte to the port, address given in 'PortAddress'.

Status() ; Status of the driver. If there are no errors, then 0.

Version()
Files: http://pure-basic.narod.ru/forum_files/ ... PortIO.zip
Last edited by User_Russian on Fri Apr 12, 2013 1:26 pm, edited 1 time in total.
Blankname
Enthusiast
Enthusiast
Posts: 120
Joined: Sun Oct 14, 2012 9:11 am

Re: Driver development using PureBasic

Post by Blankname »

Very nice, maybe some sort of functionality Fred can add native capabilities to PB. Would be insane to be able to compile at least Windows drivers with PB!

P.S. Is there, and if so what are the limitations?
marroh
User
User
Posts: 72
Joined: Wed Aug 06, 2008 8:21 am

Re: Driver development using PureBasic

Post by marroh »

Great performance, this opens up many possibilities... :)

Thanks and 10 stars from me!
PureBASIC v5.41 LTS , Windows v8.1 x64
Forget UNICODE - Keep it BASIC !
Post Reply