Home arrow Articles arrow Paradox Programming arrow Using Win32 API Functions with Structures: A Real Example
30 July 2010
 
 
Using Win32 API Functions with Structures: A Real Example PDF Print E-mail
Contributed by Pascal Hutton   
21 June 2001
Using Win32 API Functions with Structures
A Real Example
© 2001 Pascal Hutton

Using Win32 API Functions with Structures

Introduction

This sample uses the function EnumPorts from winspool.drv to enumerate ports installed on your system.
EnumPorts(pName cptr,
          Level clong,
          pPorts clong,
          cbBuf clong,
          pcbNeeded cptr,
          pcReturned cptr) clong [stdcall "EnumPortsA"]

Parameters

pName
Pointer to a null-terminated string that specifies the name of the server whose printer ports you wish to enumerate.

If pName is NULL, the function enumerates the local machine's printer ports.

Level
[in] Specifies the type of information returned in the pPorts buffer. If Level is 1, pPorts receives an array of PORT_INFO_1 structures. If Level is 2, pPorts receives an array of PORT_INFO_2 structures.

pPorts
[out] Pointer to a buffer that receives an array of PORT_INFO_1 or PORT_INFO_2 structures. Each structure contains data that describes an available printer port. The buffer must be large enough to store the strings pointed to by the structure members.

To determine the required buffer size, call EnumPorts with cbBuf set to zero. EnumPorts fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and the pcbNeeded parameter returns the size, in bytes, of the buffer required to hold the array of structures and their data.

cbBuf
[in] Specifies the size, in bytes, of the buffer pointed to by pPorts.

pcbNeeded
[out] Pointer to a variable that receives the number of bytes copied to the pPorts buffer. If the the buffer is too small, the function fails and the variable receives the number of bytes required.

pcReturned
[out] Pointer to a variable that receives the number of PORT_INFO_1 or PORT_INFO_2 structures returned in the pPorts buffer. This is the number of printer ports that are available on the specified server.
NOTE:
[in]: we send a value to the dll
[out]: the dll sends data to the buffer (fills the buffer)


Return Values

If the function succeeds, the return value is a nonzero value.


The Code

PORT_INFO_1 is a structure composed of a string containing the name of the port (for example "LPT1:")
uses "winspool.drv"
EnumPorts(pName cptr,
          Level cLong,
          lpbPorts cLong,
          cbBuf cLong,
          pcbNeeded cptr,
          pcReturned cptr) cLong [stdcall "EnumPortsA"]
Enduses

uses "kernel32.dll"
GetLastError()clong [stdcall "GetLastError"]
GlobalAlloc(wFlags cLong,
            dwBytes cLong) cLong [stdcall]
RtlMoveMemory(hpvDest cptr,
              hpvSource clong,
              cbCopy cLong) cLong [stdcall]
GlobalFree(hMem cLong) cLong [stdcall]
Enduses


method pushButton(var eventInfo Event)

var
  x, rep, arpinfo, ret, ned, buf longint
  pName, buffer, ports string
  hmem, hmem2, adr longint
endvar

ports = ""
pName.blank()
ret = 0
ned = 0
hmem.blank()
buf = 0

;// here we call the function with a level 1
;// structure and all others parameters set to
;// 0 or blank, so we'll have an error and the
;// size of the buffer needed will be known.
rep = EnumPorts(pName,1,hmem,buf,ned,ret)
ports = ""

;// we assign the value of the buffer needed
;// to the size of the buffer to receive data
buf = ned

;// we allocate memory, 4 bytes will be needed
;// because the structure contains only one record
;// which is a pointer to a string (a longint value)
hmem = GlobalAlloc(fromhex("0x40"),4)

;// and now we can call the function again
rep = EnumPorts(pName,1,hmem,buf,ned,ret)

;// adr is a temporary variable which is
;// used to go through the array
adr = hmem

;// ret is the number of ports returned
;// by the function
for x from 1 to ret
  ;// buffer is the string containing the port name
  buffer = space(32)

  ;// we move the pointer contained in adr
  ;// in another pointer
  rep = RtlMoveMemory(hmem2,adr,4)

  ;// then move the data pointed by hmem2 in the
  ;// buffer 32 bytes are moved to the buffer
  rep = RtlMoveMemory(buffer,hmem2,32)

  ;// and add the result to a string
  ports = ports + buffer.rtrim()+ " "

  ;// move 4 bytes ahead to get the next port
  adr = adr + 4
endfor

;// free the memory block
rep = GlobalFree(hmem)

;// display information
msginfo("Ports on your System",ports)

endMethod

Summary

This can be used to "play" with much more complicated structures, for more information or real cases, visit http://paradoxtips.free.fr/.
< Prev   Next >
 
Top! Top!