RAPI (remote API)

Share your advanced PureBasic knowledge/code with the community.
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

RAPI (remote API)

Post by Num3 »

This code is incomplete since i did not import the major functions of RAPI.
It requires the RAPI.dll in the same directory of the executable / source code to work, and activesync installed!

At this time it just connects to the remote device, get's the windows version of the device and reports the power status.

The file IO function where not converted yet :oops:

It was tested using activesync 4.1 and a HP PDA with windows CE 2.1.

Code: Select all

#ONE_SECOND = 1000
#E_FAIL = $80004005
#E_SUCESS = 0

#FILE_ATTRIBUTE_NORMAL = $80

#INVALID_HANDLE_VALUE = -1

#GENERIC_READ = $80000000
#GENERIC_WRITE = $40000000

#CREATE_NEW = 1
#CREATE_ALWAYS = 2
#OPEN_EXISTING = 3

#ERROR_FILE_EXISTS = 80
#ERROR_INVALID_PARAMETER = 87
#ERROR_DISK_FULL = 112

#FAF_ATTRIBUTES = $00000001;
#FAF_CREATION_TIME = $00000002   ;
#FAF_LASTACCESS_TIME = $00000004     ;
#FAF_LASTWRITE_TIME = $00000008    ;
#FAF_SIZE_HIGH = $00000010;
#FAF_SIZE_LOW = $00000020;
#FAF_OID = $00000040;
#FAF_NAME = $00000080;
#FAF_FLAG_COUNT = 8        ;
#FAF_ATTRIB_CHILDREN = $00001000     ;
#FAF_ATTRIB_NO_HIDDEN = $00002000    ;
#FAF_FOLDERS_ONLY = $00004000  ;
#FAF_NO_HIDDEN_SYS_ROMMODULES = $00008000;

#FAD_OID = $1 ;
#FAD_FLAGS = $2   ;
#FAD_NAME = $4  ;
#FAD_TYPE = $8  ;
#FAD_NUM_RECORDS = $10        ;
#FAD_NUM_SORT_ORDER = $20           ;
#FAD_SIZE = $40 ;
#FAD_LAST_MODIFIED = $80          ;
#FAD_SORT_SPECS = $100      ;
#FAD_FLAG_COUNT = $9        ;

#CeDB_SORT_DESCENDING = $00000001;
#CeDB_SORT_CASEINSENSITIVE = $00000002;
#CeDB_SORT_UNKNOWNFIRST = $00000004;
#CeDB_SORT_GENERICORDER = $00000008;

#CeDB_MAXDBASENAMELEN = 32          ;
#CeDB_MAXSORTORDER = 4        ;

#CeDB_VALIDNAME = $0001       ;
#CeDB_VALIDTYPE = $0002       ;
#CeDB_VALIDSORTSPEC = $0004           ;
#CeDB_VALIDMODTIME = $0008
;
#OBJTYPE_INVALID = 0          ;
#OBJTYPE_FILE = 1       ;
#OBJTYPE_DIRECTORY = 2            ;
#OBJTYPE_DATABASE = 3           ;
#OBJTYPE_RECORD = 4         ;

#CeDB_AUTOINCREMENT = $00000001;

#CeDB_SEEK_CeOID = $00000001;
#CeDB_SEEK_BEGINNING = $00000002 ;
#CeDB_SEEK_END = $00000004;
#CeDB_SEEK_CURRENT = $00000008;
#CeDB_SEEK_VALUESMALLER = $00000010;
#CeDB_SEEK_VALUEFIRSTEQUAL = $00000020;
#CeDB_SEEK_VALUEGREATER = $00000040;
#CeDB_SEEK_VALUENEXTEQUAL = $00000080;
#CeVT_I2 = 2              ;
#CeVT_UI2 = 18              ;
#CeVT_I4 = 3              ;
#CeVT_UI4 = 19              ;
#CeVT_FILETIME = 64                   ;
#CeVT_LPWSTR = 31                 ;
#CeVT_BLOB = 65               ;
#CeDB_PROPNOTFOUND = $0100            ;
#CeDB_PROPDELETE = $0200          ;
#CeDB_MAXDATABLOCKSIZE = 4092       ;
#CeDB_MAXPROPDATASIZE = #CeDB_MAXDATABLOCKSIZE*16;
#CeDB_MAXRECORDSIZE = (128*1024);

#CeDB_ALLOWREALLOC = $00000001      ;

#SYSMEM_CHANGED = 0                  ;
#SYSMEM_MUSTREBOOT = 1                ;
#SYSMEM_REBOOTPENDING = 2             ;
#SYSMEM_FAILED = 3                    ;

Structure SYSTEM_POWER_STATUS_EX
  ACLineStatus.b                     ;
  BatteryFlag.b                      ;
  BatteryLifePercent.b               ;
  Reserved1.b                        ;
  BatteryLifeTime.d                  ;
  BatteryFullLifeTime.d              ;
  Reserved2.b                        ;
  BackupBatteryFlag.b                ;
  BackupBatteryLifePercent.b         ;
  Reserved3.b                        ;
  BackupBatteryLifeTime.d            ;
  BackupBatteryFullLifeTime.d        ;
EndStructure

#AC_LINE_OFFLINE = $00               ;
#AC_LINE_ONLINE = $01                ;
#AC_LINE_BACKUP_POWER = $02          ;
#AC_LINE_UNKNOWN = $FF               ;

#BATTERY_FLAG_HIGH = $01               ;
#BATTERY_FLAG_LOW = $02                ;
#BATTERY_FLAG_CRITICAL = $04           ;
#BATTERY_FLAG_CHARGING = $08           ;
#BATTERY_FLAG_NO_BATTERY = $80         ;
#BATTERY_FLAG_UNKNOWN = $FF            ;
#BATTERY_PERCENTAGE_UNKNOWN = $FF      ;

Structure CEOSVERSIONINFO
  dwOSVersionInfoSize.l
  dwMajorVersion.l
  dwMinorVersion.l
  dwBuildNumber.l
  dwPlatformId.l
  szCSDVersion.s[128]
EndStructure

Structure RAPIINIT
  cbSize.l
  heRapiInit.l
  hrRapiInit.l
EndStructure

Procedure Device_Connect()
  
  If OpenLibrary(0, "rapi.dll")
    
    Protected pRapiInit.RAPIINIT
    
    pRapiInit\cbSize = SizeOf(pRapiInit)
    pRapiInit\heRapiInit = 0
    pRapiInit\hrRapiInit = 0
    
    CallFunction(0, "CeRapiInitEx", @pRapiInit)
    
    Debug pRapiInit\hrRapiInit
    
  EndIf
  
EndProcedure

Procedure RapiGetCEOSVersionString()
  ; Returns the Major, Minor, and Build number of the OS In a string.
  ceosver.CEOSVERSIONINFO
  
  ceosver\dwOSVersionInfoSize = SizeOf(ceosver)
  
  CallFunction(0, "CeGetVersionEx", @ceosver)
  Debug ceosver\dwMajorVersion
  Debug ceosver\dwBuildNumber
  Debug ceosver\szCSDVersion
  
EndProcedure

Procedure Remote_GetPowerStatus()
  
  Protected pStatus.SYSTEM_POWER_STATUS_EX
  
  CallFunction(0, "CeGetSystemPowerStatusEx", @pStatus, #True)
  Debug pStatus\ACLineStatus
  Debug pStatus\BatteryLifePercent
  Debug pStatus\BatteryFlag
  
EndProcedure

Device_Connect()

RapiGetCEOSVersionString()

Remote_GetPowerStatus()
Here's is the VB source i had for guidence:

Code: Select all

Option Explicit
Private Declare Function WaitForSingleObject Lib "kernel32" (
  ByVal _ hHandle As Long
  ByVal dwMilliseconds As Long) As Long

Public Const ONE_SECOND = 1000
Public Const E_FAIL = &H80004005

Public Const FILE_ATTRIBUTE_NORMAL = &H80

Public Const INVALID_HANDLE_VALUE = -1

Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000

Public Const CREATE_NEW = 1
Public Const CREATE_ALWAYS = 2
Public Const OPEN_EXISTING = 3

Public Const ERROR_FILE_EXISTS = 80
Public Const ERROR_INVALID_PARAMETER = 87
Public Const ERROR_DISK_FULL = 112

Public Type CEOSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type

Public Type RAPIINIT
    cbSize As Long
    heRapiInit As Long
    hrRapiInit As Long
End Type

Public Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Boolean
End Type

Public Type MyType
    value As Integer
End Type

Public Declare Function CeCloseHandle Lib "rapi.dll" ( _
    ByVal hObject As Long) As Boolean

Public Declare Function CeCreateFile Lib "rapi.dll" ( _
    ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    lpSecurityAttributes As SECURITY_ATTRIBUTES, _
    ByVal dwCreationDistribution As Long, _
    ByVal dwFlagsAndAttributes As Long, _
    ByVal hTemplateFile As Long) As Long

Public Declare Function CeGetVersionEx Lib "rapi.dll" ( _
    lpVersionInformation As CEOSVERSIONINFO) As Boolean

Public Declare Function CeRapiInitEx Lib "rapi.dll" ( _
    pRapiInit As RAPIINIT) As Long

Public Declare Function CeRapiUninit Lib "rapi.dll" () As Long

Public Declare Function CeReadFile Lib "rapi.dll" ( _
    ByVal hFile As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToRead As Long, _
    lpNumberOfBytesRead As Long, _
    ByVal lpOverlapped As Long) As Boolean

Public Declare Function CeWriteFile Lib "rapi.dll" ( _
    ByVal hFile As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToWrite As Long, _
    lpNumberOfBytesWritten As Long, _
    ByVal lpOverlapped As Long) As Boolean

Public Declare Function CeGetLastError Lib "rapi.dll" () As Long

'Wrapper functions for above API calls

Private Function GetSub(Addr As Long) As Long
    'Used for the init call.
    GetSub = Addr
End Function

Public Sub ConnectedRapi()
    'Used for the init call. Do not remove.
End Sub

Public Function RapiConnect() As Boolean
    'Initiates a connection and returns true
    ' if it connected, false if it did not.

    'Modified to match suggestion of Microsoft KB article 831883
    'http://support.microsoft.com/default.aspx?scid=kb;en-us;831883

    Dim pRapiInit As RAPIINIT
    Dim dwWaitRet, dwTimeout As Long
    Dim hr As Long

    On Error GoTo RapiConnect_Err

    pRapiInit.cbSize = Len(pRapiInit)
    pRapiInit.heRapiInit = 0
    pRapiInit.hrRapiInit = 0

    hr = E_FAIL
    dwWaitRet = 0
    dwTimeout = 10 * ONE_SECOND 'However long you want to wait

    'Call CeRapiInitEx one time.
     hr = CeRapiInitEx(pRapiInit)

    If hr < 0 Then 'FAILED
      GoTo Failed
    End If

   'Wait for the RAPI event until timeout.

   'Use the WaitForSingleObject function for the worker thread
   'Use the WaitForMultipleObjects function if you are also waiting for other events.

   dwWaitRet = WaitForSingleObject(pRapiInit.heRapiInit, dwTimeout)

   If dwWaitRet = 0 Then 'WAIT_OBJECT_0
      'If the RAPI init is returned, check result

      If pRapiInit.hrRapiInit >= 0 Then 'SUCCEEDED
        GoTo Succeeded
      Else
        GoTo Failed
      End If
   Else
      'Timeout or failed.
      GoTo Failed

   End If

   'success
   Succeeded:
     'Now you can make RAPI calls.
     RapiConnect = True
     Exit Function
   Failed:
     'Uninitialize RAPI if you ever called CeRapiInitEx.
     If hr >= 0 Then 'SUCCEEDED
       Call CeRapiUninit
     End If

   RapiConnect = False
   Exit Function

RapiConnect_Err:
    RapiConnect = False
End Function

Public Sub RAPICopyCEFileToPC(ByVal CESourceFile As String, _
        ByVal PCDestFile As String)

    Dim lCeFileHandle   As Long
    Dim iFile           As Integer
    Dim BytePos         As Long
    Dim lBufferLen      As Long
    Dim lBytesRead      As Long
    Dim bytFile(2048)   As Byte
    Dim lResult         As Long
    Dim I               As Integer

    ' Open the CE file.
    lCeFileHandle = RapiOpenFile(CESourceFile, 1, False, _
            FILE_ATTRIBUTE_NORMAL)

    If lCeFileHandle <> INVALID_HANDLE_VALUE Then
        'Create a file on the PC and write
        ' the bytes from the CE file to it.
        iFile = FreeFile
        Open PCDestFile For Binary Access Write As iFile
        BytePos = 1
        lBufferLen = 2048
        Do
            lResult = CeReadFile(lCeFileHandle, bytFile(0), _
                    lBufferLen, lBytesRead, 0&)

            If (lResult And (lBytesRead = 0)) Then
                lResult = CeCloseHandle(lCeFileHandle)
                Close iFile
                Exit Do
            Else
                For I = 0 To lBytesRead - 1
                    Put iFile, BytePos + I, bytFile(I)
                Next I
                BytePos = BytePos + lBytesRead
            End If
            Form1.Label6.Caption = "Bytes Copied:" & _
                    (BytePos - 1) & " Up."

            Form1.Label6.Refresh
        Loop
        Form1.Label6.Caption = Form1.Label6.Caption & _
                " Transfer Completed."

    Else
        lResult = CeCloseHandle(lCeFileHandle)
        MsgBox "Device File Does Not Exist Or Is Empty (0 Bytes)!"
    End If
End Sub

Public Sub RAPICopyPCFileToCE(ByVal PCSourceFile As String, _
        ByVal CEDestFile As String)

    Dim iFile As Integer
    Dim bytFile() As MyType
    Dim lCeFileHandle As Long
    Dim BytePos As Long
    Dim lBufferLen As Long
    Dim TotalCopied As Long
    Dim lBytesWritten As Long
    Dim lResult As Long

    'Get bytes from PC file.
    iFile = FreeFile
    Open PCSourceFile For Binary Access Read As iFile
        ReDim bytFile(LOF(iFile))
        Get iFile, , bytFile
    Close iFile

    'Create a file on the CE Device and write
    ' the bytes from the PC file to it.
    lCeFileHandle = RapiOpenFile(CEDestFile, 2, _
            True, FILE_ATTRIBUTE_NORMAL)

    If lCeFileHandle <> INVALID_HANDLE_VALUE Then
        BytePos = 0

        'Copy this many bytes at a time (MUST BE EVEN #).
        lBufferLen = 2048
        Do
            If UBound(bytFile) - TotalCopied > lBufferLen Then
                ' Copy the next set of bytes
                lResult = CeWriteFile(lCeFileHandle, bytFile(BytePos), _
                        lBufferLen, lBytesWritten, 0&)

                TotalCopied = TotalCopied + lBytesWritten
                ' Unicode compensation.
                BytePos = BytePos + (lBufferLen \ 2)
                Form1.Label6.Caption = "Bytes Copied: " & _
                        TotalCopied & " Down."

                Form1.Label6.Refresh
            Else
                ' Copy the remaining bytes if greater than 0
                lBufferLen = UBound(bytFile) - TotalCopied
                If lBufferLen > 0 Then
                    ' Copy remaining bytes at one time.
                    lResult = CeWriteFile(lCeFileHandle, _
                           bytFile(BytePos), lBufferLen, lBytesWritten, 0&)

                End If
                TotalCopied = TotalCopied + lBytesWritten
                Form1.Label6.Caption = "Bytes Copied: " & _
                        TotalCopied & " Down."

                Form1.Label6.Refresh
                Exit Do
            End If
        Loop
    Else
        'CeCreateFile failed.  Why?
        Select Case CeGetLastError
            Case ERROR_FILE_EXISTS
                MsgBox "A file already exists with the specified name."
            Case ERROR_INVALID_PARAMETER
                MsgBox "A parameter was invalid."
            Case ERROR_DISK_FULL
                MsgBox "Disk if Full."
            Case Else
                MsgBox "An unknown error occurred."
        End Select
    End If
    Form1.Label6.Caption = Form1.Label6.Caption & " Transfer Completed."
    lResult = CeCloseHandle(lCeFileHandle)
End Sub

Public Sub RapiDisconnect()
    Call CeRapiUninit
End Sub

Public Function RapiGetCEOSVersionString() As String
    ' Returns the Major, Minor, and Build number of the OS In a string.
    Dim ceosver As CEOSVERSIONINFO

    ceosver.dwOSVersionInfoSize = Len(ceosver)

    If CeGetVersionEx(ceosver) Then
        RapiGetCEOSVersionString = ceosver.dwMajorVersion & "." & _
            ceosver.dwMinorVersion & "." & _
            ceosver.dwBuildNumber & " " & _
            Left$(ceosver.szCSDVersion, _
            InStr(ceosver.szCSDVersion, Chr$(0)) - 1)
    Else
        RapiGetCEOSVersionString = ""
    End If
End Function

Public Function RapiIsConnected() As Boolean
    ' Returns whether there is a RAPI connection. If the Version
    'string is returned then we know we have a valid connection.
    RapiIsConnected = RapiGetCEOSVersionString <> ""
End Function

Public Function RapiOpenFile(ByVal FileName As String, _
        ByVal mode As Integer, _
        ByVal CreateNew As Boolean, _
        ByVal flags As Long) As Long

    Dim lReturn As Long
    Dim lFileMode As Long
    Dim Security As SECURITY_ATTRIBUTES
    Dim CreateDist As Long

    Select Case mode
        Case 1: lFileMode = GENERIC_READ
        Case 2: lFileMode = GENERIC_WRITE
        Case 3: lFileMode = GENERIC_READ Or GENERIC_WRITE
    End Select

    If CreateNew Then
        CreateDist = CREATE_NEW
    Else
        CreateDist = OPEN_EXISTING
    End If

    lReturn = CeCreateFile(StrConv(FileName, vbUnicode), lFileMode, _
            0, Security, CreateDist, flags, 0&)

    RapiOpenFile = lReturn
End Function

Function FileExists(ByVal sFilename As String) As Boolean
'This function will check to make sure that a file exists. It will
'return True if the file was found and False if it was not found.
'Example: If Not FileExists("autoexec.bat") Then...

    Dim I As Integer

    On Error Resume Next

    I = Len(Dir$(sFilename))
    If Err Or I = 0 Or Trim(sFilename) = "" Then
        FileExists = False
    Else
        FileExists = True
    End If
End Function
Last edited by Num3 on Sat Sep 06, 2008 9:07 am, edited 2 times in total.
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

Post by Heathen »

Thanks! :)
I love Purebasic.
User avatar
gally
User
User
Posts: 41
Joined: Thu May 28, 2009 9:07 pm
Location: France
Contact:

Post by gally »

Hello,

http://www.purebasic.fr/french/viewtopic.php?t=9468, It's my version of convert VB code to Rapi DLL.

GallyHC
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Very Nice! Thank You.

(Didn't someone else do a complete RAPI PB library somewhere? I seem to remember something like that somewhere.)
User avatar
gally
User
User
Posts: 41
Joined: Thu May 28, 2009 9:07 pm
Location: France
Contact:

Re: RAPI (remote API)

Post by gally »

Hello All,

Here is my source code when using the Rapi.dll 100% functional. http://www.koakdesign.info/php/page_source.php?num=1 and i use my pb source paser for view.

best regards
GallyHC
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: RAPI (remote API)

Post by djes »

Thank you Gally, I'll try with my GPS! Why don't you talk about your nice sources management site? http://www.koakdesign.info/?url=04
Post Reply