Vous êtes sur la page 1sur 1148



Client Access Express Programming




Client Access Express Programming


© Copyright International Business Machines Corporation 1999, 2000. All rights reserved.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
Part 1. Client Access Express LDAP APIs listing . . . . . . . . . . . 638
Distinguished names format . . . . . . . 696
programming . . . . . . . . . . . . 1 LDAP Data Interchange Format (LDIF) . . . . 697
Express Multimedia APIs . . . . . . . . . 698
Chapter 1. What’s new for V4R5 . . . . 3 Ultimedia System Facilities API capabilities
overview . . . . . . . . . . . . . . 699
Chapter 2. Print this topic . . . . . . . 5 Ultimedia System Facilities API types overview 699
Express AS/400 Objects APIs . . . . . . . . 700
AS/400 objects attributes . . . . . . . . 700
Chapter 3. Express C/C++ APIs . . . . . 7
Express AS/400 Objects API listing . . . . . 730
Express C/C++ APIs overview . . . . . . . . 7
Example: Using Express AS/400 Objects APIs 815
Express API groups, header files, import libraries,
Express Remote Command/Distributed Program
and DLLs . . . . . . . . . . . . . . 7
Call APIs . . . . . . . . . . . . . . . 817
AS/400 system name formats for APIs . . . . 10
Typical use of Express Remote
OEM, ANSI, and Unicode considerations . . . 10
Command/Distributed Program Call APIs . . 818
Obsolete Client Access APIs . . . . . . . . 13
Express Remote Command/Distributed
Express return codes and error messages . . . 15
Program Call APIs listing . . . . . . . . 819
Express Administration APIs . . . . . . . . 30
Example: Using Remote Express
Express Administration APIs listing . . . . . 30
Command/Distributed Program Call APIs . . 839
Example: Express Administration APIs . . . . 37
Express Serviceability APIs . . . . . . . . . 841
Express Communications and Security APIs . . . 40
History log and trace files . . . . . . . . 841
System object attributes . . . . . . . . . 41
Error handles . . . . . . . . . . . . 843
Express Communications and Security system
Typical use of Serviceability APIs. . . . . . 843
object APIs listing . . . . . . . . . . . 45
Express Serviceability APIs listing . . . . . 843
Express Communications system list APIs listing 102
Example: Using Express Serviceability APIs . . 910
Example: Using Express communications APIs 125
Express System Object Access (SOA) APIs . . . . 911
Express database programming . . . . . . . 136
SOA objects . . . . . . . . . . . . . 912
Express OLE DB Provider . . . . . . . . 136
AS/400 object views . . . . . . . . . . 912
Express ODBC . . . . . . . . . . . . 137
Typical use of Express System Object Access
Express database APIs (Optimized SQL) . . . 291
APIs . . . . . . . . . . . . . . . 912
Express Data Queues APIs . . . . . . . . . 469
Express System Object Access programming
Data queues . . . . . . . . . . . . . 470
considerations . . . . . . . . . . . . 919
Ordering data queue messages . . . . . . 470
Express System Object Access APIs listing . . . 920
Working with data queues . . . . . . . . 470
Typical use of data queues . . . . . . . . 471
Express Data Queues APIs listing . . . . . 472 Chapter 4. Developing AS/400
Example: Using Data Queues APIs . . . . . 534 Operations Navigator plug-ins . . . . 977
Express data transformation and national language Operations Navigator plug-ins overview . . . . 977
support (NLS) APIs . . . . . . . . . . . 535 About Operations Navigator plug-ins . . . . 977
Express data transformation APIs . . . . . 535 Plug-in requirements . . . . . . . . . . 980
Express national language support (NLS) APIs 556 Plug-ins samples in the Express Toolkit. . . . 980
Express Directory Update APIs . . . . . . . 588 Displaying installed plug-ins with the
Typical use of Express Directory Update APIs 589 Operations Navigator Plug-ins tab . . . . . 981
Requirements for Directory Update entries . . 589 Server entry point for Operations Navigator
Options for Directory Update entries . . . . 590 plug-ins . . . . . . . . . . . . . . 982
Directory Update package files syntax and The Windows registry for Operations Navigator
format . . . . . . . . . . . . . . . 591 plug-ins . . . . . . . . . . . . . . 982
Directory Update sample program . . . . . 592 Express setup file . . . . . . . . . . . 990
Express Directory Update API listing . . . . 592 Policy template file . . . . . . . . . . 995
Express PC5250 emulation APIs . . . . . . . 615 MRI setup file . . . . . . . . . . . . 996
IBM Lightweight Directory Access Protocol (LDAP) Application Administration support for your
APIs . . . . . . . . . . . . . . . . 615 plug-in . . . . . . . . . . . . . . 996
IBM LDAP client incompatibility . . . . . . 616 C++ plug-ins . . . . . . . . . . . . . 1003
LDAP version support . . . . . . . . . 616 Product architecture for Operations Navigator
LDAP APIs overview. . . . . . . . . . 617 C++ plug-ins . . . . . . . . . . . . 1003
LDAP utilities APIs listing . . . . . . . . 619

© Copyright IBM Corp. 1999, 2000 iii


Operations Navigator structure and flow of Identifying Java plug-ins to Operations
control for C++ plug-ins . . . . . . . . 1003 Navigator . . . . . . . . . . . . . 1121
Developing Operations Navigator C++ Visual Basic plug-ins . . . . . . . . . . 1122
plug-ins . . . . . . . . . . . . . . 1030 Product architecture for Operations Navigator
Installing Operations Navigator C++ plug-ins 1042 Visual Basic plug-ins . . . . . . . . . 1122
Identifying C++ plug-ins to Operations Operations Navigator structure and flow of
Navigator . . . . . . . . . . . . . 1042 control for Visual Basic plug-ins . . . . . . 1122
Operations Navigator API listing . . . . . 1043 Developing Operations Navigator Visual Basic
Return codes unique to Operations Navigator plug-ins . . . . . . . . . . . . . . 1125
APIs . . . . . . . . . . . . . . . 1111 Installing Visual Basic plug-ins . . . . . . 1135
Java plug-ins . . . . . . . . . . . . . 1112 Identifying Visual Basic plug-ins to Operations
Product architecture for Operations Navigator Navigator . . . . . . . . . . . . . 1135
Java plug-ins . . . . . . . . . . . . 1113
Operations Navigator structure and flow of Chapter 5. Java programming . . . . 1137
control for Java plug-ins . . . . . . . . 1117
Developing Operations Navigator Java plug-ins 1118
Chapter 6. ActiveX programming 1139
Installing Java plug-ins . . . . . . . . . 1121

iv Client Access Express Programming


Part 1. Client Access Express programming
Explore the Client Access Express programming topic to learn:
v How to use Express C/C++ application programming interfaces (APIs) to access
the AS/400® from your client-based applications
v How to develop AS/400 Operations Navigator plug-ins
v Where to find information about developing applications and accessing AS/400
resources by using Java® programming and ActiveX programming technologies
v Why the Express Toolkit is your primary information source for developing
applications with Client Access Express
v What’s new for V4R5 in Client Access Express programming
v How to print a PDF version of Client Access Express programming
v Who should read Client Access Express programming
Client Access Express programming includes details, tips, overview and concept
information, illustrations, and programming examples*.

*Express programming examples disclaimer


This documentation contains programming examples that help demonstrate how Client
Access Express application programs interface with the AS/400 system. The examples have
not been submitted to any formal IBM® test, and are provided AS IS. The use of this
information is your responsibility. Any implementation of these techniques depends on
your ability to evaluate and integrate the examples into your particular operational
environment. While IBM may have reviewed each item for accuracy in a specific situation,
this does not guarantee that the same or similar results will be obtained. Customers who
attempt to adapt these techniques to their own environments do so at their own risk.

© Copyright IBM Corp. 1999, 2000 1


2 Client Access Express Programming
Chapter 1. What’s new for V4R5
For V4R5, Client Access Express programming includes new information on ODBC
programming and performance.
Learn how to:
v Code directly to Express ODBC APIs
v Performance-tune Express ODBC
v Improve SQL performance
v Enable tables and files for updating
Find information on:
v “SQL performance” on page 208
v “ODBC blocked insert statement” on page 234
v “Catalog functions” on page 236
v “Exit programs” on page 237
v “Stored procedures” on page 253
View programming examples of:
v Common tool behaviors that degrade ODBC performance
v Blocked insert calls
v User exit programs
v Stored procedures
v Running CL commands by using stored procedures

© Copyright IBM Corp. 1999, 2000 3


4 Client Access Express Programming
Chapter 2. Print this topic
You can view, print, and download a PDF version of Client Access Express
programming. You must have Adobe® Acrobat® Reader installed to view PDF files.
Download a copy of Acrobat from

http://www.adobe.com/prodindex/acrobat/readstep.html .

To view, print, and download the PDF version, select Client Access Express
programming (about 2.95 MB, or 1200 pages). Print the entire document, or select
and print a range of pages.

To save a PDF on your workstation for viewing or printing:


1. Open the PDF in your browser (select the link above).
2. In the menu of your browser, select File.
3. Select Save As...
4. Navigate to the directory in which you would like to save the PDF.
5. Select Save.

© Copyright IBM Corp. 1999, 2000 5


6 Client Access Express Programming
Chapter 3. Express C/C++ APIs
Client Access Express provides C/C++ application programming interfaces (APIs)
for accessing AS/400 resources. These APIs are intended primarily for C/C++
programmers. However, they also may be called from other languages that support
calling C-style APIs.
Express C/C++ APIs overview information:
“Express C/C++ APIs overview”
Express C/C++ APIs topics:
v Administration
v Communications and Security
v Database programming (OLE DB Provider, ODBC and Database APIs)
v AS/400 Data Queues
v Data transformation and national language support (NLS)
v Directory Update
v PC5250 emulation
v IBM Lightweight Directory Access Protocol (LDAP)
v Multimedia
v AS/400 Objects
v Remote Command/Distributed Program Call
v Serviceability
v System Object Access (SOA)

Express C/C++ APIs overview


See the following topics for Express C/C++ APIs overview information:
v “Express API groups, header files, import libraries, and DLLs”
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10
v “Obsolete Client Access APIs” on page 13
v “Express return codes and error messages” on page 15

Express API groups, header files, import libraries, and DLLs


For each Express C/C++ API group, the table below provides:
v Links to the API documentation
v Required interface definition (header) files, where applicable
v Associated import library files, where applicable
v Associated Dynamic Link Library (DLL) files

Access interface definition files for all Client Access Express C/C++ API groups in
the Client Access Express Toolkit.
How to access Express header files in the Toolkit:
1. Find the Express Toolkit icon in your IBM AS400 Client Access Express
program directory and launch it. If it is not displayed in the program
directory, install the Toolkit.
2. In the left navigation panel, select the appropriate API group.
Note: Names of some API categories in the Express Toolkit differ from
the names that are used in Express programming:

© Copyright IBM Corp. 1999, 2000 7


To find this Express programming API Select this Express Toolkit topic:
group header file:
Administration Client Information
Data transformation Data Manipulation
National language support
LDAP Directory
Serviceability Error Handling
AS/400 Object AS/400 Operations
System Object Access

3. Select the C/C++ APIs subtopic in the left navigation panel.


4. In the right display panel, find the header (.h) file and select it.

Note: In addition to interface descriptions and definitions, the Express API


group topics in the Toolkit include links to other information
resources.
About import libraries:
The import libraries that are shipped with the Express Toolkit were built
with the Microsoft Visual C++ compiler. As a result, they are in the
Common Object File Format (COFF). Some compilers, such as Borland’s C
compiler, do not support COFF. To access the Client Access C/C++ APIs
from these compilers, you must create Object Model Format (OMF) import
libraries by using the IMPLIB tool. For example:
implib cwbdq.lib %windir%\system32\cwbdq.dll
Table 1. Express C/C++ API groups, header files, library files, and DLL files
API group Header file Import library DLL
Administration cwbad.h cwbapi.lib cwbad.dll
Communications cwbcosys.h cwbapi.lib cwbco.dll
and Security cwbco.h
cwb.h
AS/400 Data Queues cwbdq.h cwbapi.lib cwbdq.dll
Data transformation cwbdt.h cwbapi.lib cwbdt.dll
Directory Update cwbup.h cwbapi.lib cwbup.dll
Emulation (Standard hapi_c.h pscal32.lib pcshll.dll
HLLAPI interface) pcshll32.dll
Emulation ehlapi32.h ehlapi32.lib ehlapi32.dll
(Enhanced HLLAPI
interface)
Emulation (Windows whllapi.h whllapi.lib whllapi.dll
EHLLAPI interface)
whlapi32.lib whllapi32.dll
Emulation (HACL eclall.hpp pcseclva.lib pcseclva.dll
interface)
pcseclvc.lib pcseclvc.dll
Emulation (PCSAPI pcsapi.h pcscal32.lib pcsapi.dll
interface) pcsapi32.dll
LDAP ldap.h ldap.lib ldap.dll
Multimedia fzzmapi.h fzzmapiw.lib fzzmapiw.dll

8 Client Access Express Programming


Table 1. Express C/C++ API groups, header files, library files, and DLL files (continued)
API group Header file Import library DLL
National language cwbnl.h cwbapi.lib cwbnl.dll
support

(General NLS)
National language cwbnlcnv.h cwbapi.lib cwbnl1.dll
support

(Conversion NLS)
National language cwbnldlg.h cwbapi.lib cwbnldlg.dll
support

(Dialog-box NLS)
AS/400 objects cwbobj.h cwbapi.lib cwbobj.dll
ODBC sql.h odbc32.lib odbc32.dll
sqlext.h
sqltypes.h
sqlucode.h
Database APIs cwbdb.h cwbapi.lib cwbdb.dll
(Optimized SQL)
OLE DB Provider ad400.h oledb.lib oledb32.dll
adoid.h oledbd.lib (for debug)
adoint.h See the OLE DB
da400.h Section of the
oledb.h Microsoft Universal
oledberr.h Data Access Web
transact.h
Site for more
information
Remote cwbrc.h cwbapi.lib cwbrc.dll
Command/Distributed
Program Call
Serviceability cwbsv.h cwbapi.lib cwbsv.dll
System Object cwbsoapi.h cwbapi.lib cwbsoapi.dll
Access

Who should read Client Access Express programming


This information is designed for client/server application developers who have a
basic working knowledge of Client Access Express and its components. For
detailed information, see the Welcome Wizard and the Express User’s Guide,
which are shipped with Client Access Express.

Note: To launch these components from a Windows PC, select Start –> Programs
–> IBM AS400 Client Access Express, and select the component. If you do
not see either of the components in your Client Access Express folder, they
are not installed. Run Selective Setup to install them. See the Client Access
Express for Windows - Setup book for related information.

Client Access Express Toolkit


The Client Access Express Toolkit—an installable component of Client Access
Express—should be used as the primary source of information about Client Access
Express application development. This includes programming with Express

Chapter 3. Express C/C++ APIs 9


ActiveX Automation Objects, ADO/OLE DB, and Java. The Express Toolkit
contains links to header files, sample programs, and complete documentation.

Note: No portion of the Toolkit or the Client Access Express product may be
redistributed with the resulting applications.

The Express Toolkit consists of two parts:


Express Toolkit component of Client Access Express
This includes:
v The Toolkit help file and other Windows help documentation
v C/C++ header files
v C import libraries
v ActiveX automation type libraries
v Visual Basic wizards for the Express OLE DB provider

Client Access Express Toolkit Web site


This includes sample applications and tools that may be useful for
developing Express applications. This site is updated regularly; check it
periodically for new information.

Follow these links for instructions on how to install and launch the Express
Toolkit.

Installing the Express Toolkit: To install the Express Toolkit:


1. If you are installing Client Access Express for the first time, perform a Client
Access Custom Install. If Client Access Express already is installed, select Start
–> Programs –> IBM AS400 Client Access Express –> Selective Setup.
2. Follow the prompts until the Component Selection dialog displays.
3. Select the Express Toolkit option, and follow the prompts to completion.
See also “Launching the Express Toolkit”.

Launching the Express Toolkit: To launch the Express Toolkit, select Start –>
Programs –> IBM AS400 Client Access Express –> Express Toolkit.

Note: The Client Access Express installation program does not create the Toolkit
icon unless you have installed the Client Access Express Toolkit on your
personal computer. See “Installing the Express Toolkit” for instructions.

AS/400 system name formats for APIs


APIs that take an AS/400 system name as a parameter accept names in the
following formats:
v TCP/IP network name (system.network.com)
v System name without a network identifier (SYSTEM)
v IP address (1.2.3.4)

OEM, ANSI, and Unicode considerations


Most of the Express C/C++ APIs that accept string parameters exist in three forms:
v One that expects string parameters to be expressed in the OEM code page (the
default)
v One that expects string parameters to be expressed in the ANSI code page
v One that expects string parameters to be expressed in Unicode

10 Client Access Express Programming


The generic version of the Express C/C++ APIs follows the same form as the
default OEM version. Only a single name for each function appears in this
information, but there are three different system entry points. For example:
cwbNL_GetLang();

compiles to:

cwbNL_GetLang(); //CWB_OEM or undefined

or:

cwbNL_GetLangA(); //CWB_ANSI defined

or:

cwbNL_GetLangW(); //CWB_UNICODE defined

API types, name formats, and pre-processor definitions

API type API name format (if it exists) Pre-processor definition


OEM cwbXX_xxx None (may specify
CWB_OEM explicitly)
ANSI cwbXX_xxxA CWB_ANSI
UNICODE cwbXX_xxxW CWB_UNICODE

Note:
v Data transformation APIs (cwbDT_xxx) do not follow the ″A″ and ″W″
suffix conventions. The generic version of the APIs uses ″String″ as part of
the function name. The ANSI/OEM version uses ″ASCII″ as part of the
function name. The Unicode version uses ″Wide″ as part of the function
name. There is no difference between OEM and ANSI character sets in
cwbDT_xxx APIs, which handle numeric strings. Therefore, ANSI and
OEM versions of the relevant APIs are the same. For example:
cwbDT_HexToString();

compiles to:

cwbDT_HexToASCII(); //CWB_UNICODE not defined

or:

cwbDT_HexToWide(); //CWB_UNICODE defined

See the data transformation cwbdt.h header file for more details.
v For Unicode APIs that take a buffer and a length for passing strings (for
example, cwbCO_GetUserIDExW), the length is treated as the number of
bytes. It is not treated as the number of characters.
Using single and mixed API types:
You can write applications that use a single API type, or that combine
several API types. Link to the following topics for more information:
v “Using a single Client Access Express API type” on page 12
v “Using mixed Client Access Express API types” on page 12
Writing generic applications:
To ensure maximum portability of your applications, consider writing a
generic application. Link to the following topic for more information:
v “Writing a generic Client Access Express application” on page 12

Chapter 3. Express C/C++ APIs 11


Using a single Client Access Express API type
To restrict your application to a particular type of Client Access API, you must
define one—and only one—of the following pre-processor definitions:
CWB_OEM_ONLY
CWB_ANSI_ONLY
CWB_UNICODE_ONLY

For example, when writing a pure ANSI application, you specify both
CWB_ANSI_ONLY and CWB_ANSI. Refer to the individual Client Access Toolkit
header files for details of these pre-processor definitions and API names. See
“Express API groups, header files, import libraries, and DLLs” on page 7 for more
information.

Using mixed Client Access Express API types


You can mix ANSI, OEM, and Unicode APIs by using explicit API names. For
example, you can write an ANSI Client Access application by specifying the
CWB_ANSI pre-processor definition, but still call a Unicode version of an API by
using the ″W″ suffix.

Writing a generic Client Access Express application


Generic applications allow maximum portability because the same source code can
be compiled for OEM, ANSI, and Unicode. Generic applications are built by
specifying different pre-processor definitions, and by using the generic version of
the Client Access APIs (the ones without the ″A″ or ″W″ suffixes). Following is a
short list of guidelines for writing a generic application:
v Instead of including the usual <string.h> for manipulating strings, include
<TCHAR.H>.
v Use generic data types for characters and strings. Use ’TCHAR’ for ’char’ in
your source code.
v Use the _TEXT macro for literal characters and strings. For example,
TCHAR A[]=_TEXT("A Generic String").
v Use generic string manipulation functions. For example, use _tcscpy instead of
strcpy.
v Be especially careful when using the ’sizeof’ operator - always remember that a
Unicode character occupies two bytes. When determining the number of
characters in a generic TCHAR array A, instead of the simple sizeof(A), use
sizeof(A)/sizeof(TCHAR).
v Use proper pre-processor definitions for compilation. When compiling your
source for Unicode in Visual C++, you should also use the pre-processor
definitions UNICODE and _UNICODE. Instead of defining _UNICODE in the MAK file,
you may want to define it at the beginning of your source code as:
#ifdef UNICODE
#define _UNICODE
#endif

For a complete description of these guidelines, see the following resources:


1. Richter, J. Advanced Windows: The Developer’s Guide to the Win32 API for Windows
NT 3.5 and Windows 95, Microsoft Press, Redmond, WA, 1995.
2. Kano, Nadine Developing International Software for Windows 95 and Windows NT:
a handbook for software design, Microsoft Press, Redmond, WA, 1995.

3. Microsoft Knowledge Base articles

4. MSDN Library

12 Client Access Express Programming


Obsolete Client Access APIs
Some of the APIs that were provided by earlier versions of Client Access have
been replaced with new APIs in Client Access Express. While these older, obsolete
Client Access APIs still are supported, it is recommended that you use the newer
Express APIs.

Following is a list, by function, of the obsolete Client Access APIs. For each
obsolete API, a link to the newer Express replacement API is provided, when
available.

Note: All of the APPC and License Management APIs are obsolete, and are not
supported for Client Access Express.
Obsolete Client Access APIs listing:
v “Obsolete Communications APIs”
v “Obsolete Data Queues APIs”
v “Obsolete LDAP APIs” on page 14
v “Obsolete Remote Command/Distributed Program Call APIs” on
page 14
v “Obsolete Security APIs” on page 14
v “Obsolete System Object Access (SOA) API” on page 15

Obsolete Communications APIs


v cwbCO_IsSystemConfigured (not available)
Client Access Express does not require pre-configuration of an AS/400
connection to connect to and use that system. For this reason, programs that
need to connect to an AS/400 system (either explicitly by calling
cwbCO_Connect, or implicitly as the result of a call to a different API such as
cwbRC_RunCmd) do not need to check to see if the connection has been
pre-configured. Therefore, the above API no longer should be necessary.
v cwbCO_IsSystemConnected (use “cwbCO_IsConnected” on page 79)
Most Client Access Express APIs work with AS/400 System Objects, rather than
with AS/400 system names. There can be multiple AS/400 System Objects
created and connected to the same AS/400 system within the same process. The
cwbCO_IsSystemConnected API will return an indication of whether at least one
System Object is connected to the AS/400 system, within the current process.
The cwbCO_IsConnected API is used to determine if a specific AS/400 System
Object is connected.
v cwbCO_GetUserID (use “cwbCO_GetUserIDEx” on page 75)
Most Client Access Express APIs work with AS/400 System Objects, rather than
with AS/400 system names. There can be multiple AS/400 System Objects
created and connected to the same AS/400 system, within the same process, but
using different user IDs. The cwbCO_GetUserID API will return the user ID of
the first AS/400 System Object, in the current process, for the specified AS/400
system. The cwbCO_GetUserIDEx API will return the user ID for a specific
AS/400 System Object.
v cwbCO_GetHostVersion (use “cwbCO_GetHostVersionEx” on page 65)
The behavior of these APIs is the same. However, use of the
cwbCO_GetHostVersionEx API is more efficient.

Obsolete Data Queues APIs


v cwbDQ_Create (use “cwbDQ_CreateEx” on page 481)
v cwbDQ_Delete (use “cwbDQ_DeleteEx” on page 487)
v cwbDQ_Open (use “cwbDQ_OpenEx” on page 515)
v cwbDQ_StartSystem (use “cwbCO_Connect” on page 54)

Chapter 3. Express C/C++ APIs 13


Note: To achieve the same effect as cwbDQ_StartSystem when you use
cwbCO_Connect, you must connect to the data queue’s service. See
“cwbCO_Connect” on page 54 for details.
v cwbDQ_StopSystem (use “cwbCO_Disconnect” on page 60)

Note: To achieve the same effect as cwbDQ_StopSystem when you use


cwbCO_Disconnect, you must disconnect from the data queue’s service.
See “cwbCO_Disconnect” on page 60 for details.

Obsolete LDAP APIs


v ldap_ssl_start (use ldap_ssl_client_init and “ldap_ssl” on page 689)
v ldap_open (use “ldap_init” on page 665)
v ldap_bind (use ldap_simple_bind)
v ldap_bind_s (use ldap_simple_bind_s)
v ldap_modrdn (use “ldap_rename” on page 681)
v ldap_modrdn_s (use ldap_rename_s)
v ldap_result2error (use “ldap_parse_results” on page 679)
v ldap_perror (use “ldap_parse_results” on page 679)

Obsolete Remote Command/Distributed Program Call APIs


v cwbRC_StartSys (use “cwbRC_StartSysEx” on page 836).
v cwbRC_GetSysName (use “cwbCO_GetSystemName” on page 74).

Obsolete Security APIs


v cwbSY_CreateSecurityObj (use “cwbCO_CreateSystem” on page 56).
v cwbSY_DeleteSecurityObj (use “cwbCO_DeleteSystem” on page 59).
v cwbSY_SetSys (use “cwbCO_CreateSystem” on page 56 and pass a system name
on the call).
v cwbSY_VerifyUserIDPwd (use “cwbCO_VerifyUserIDPassword” on page 99).
v cwbSY_ChangePwd (use “cwbCO_ChangePassword” on page 52).
v cwbSY_GetUserID (use “cwbCO_GetUserIDEx” on page 75).
v cwbSY_Logon (use “cwbCO_Signon” on page 95).
v cwbSY_LogonUser (use “cwbCO_SetUserIDEx” on page 92,
“cwbCO_SetPassword” on page 86, or “cwbCO_Signon” on page 95).
v cwbSY_GetDateTimeCurrentSignon (use “cwbCO_GetSignonDate” on page 73)
v cwbSY_GetDateTimeLastSignon (use “cwbCO_GetPrevSignonDate” on page 71)
v cwbSY_GetDateTimePwdExpires (use “cwbCO_GetPasswordExpireDate” on
page 68)
v cwbSY_GetFailedAttempts (use “cwbCO_GetFailedSignons” on page 63)

Obsolete Serviceability APIs


The following Serviceability APIs for reading problem log service records are
obsolete:
cwbSV_GetCreatedBy (not available)
cwbSV_GetCurrentFix (not available)
cwbSV_GetFailMethod (not available)
cwbSV_GetFailModule (not available)
cwbSV_GetFailPathName (not available)
cwbSV_GetFailProductID (not available)
cwbSV_GetFailVersion (not available)
cwbSV_GetOriginSystemID (not available)
cwbSV_GetOriginSystemIPAddr (not available)
cwbSV_GetPreviousFix (not available)
cwbSV_GetProblemID (not available)

14 Client Access Express Programming


cwbSV_GetProblemStatus (not available)
cwbSV_GetProblemText (not available)
cwbSV_GetProblemType (not available)
cwbSV_GetSeverity (not available)
cwbSV_GetSymptomString (not available)

Obsolete System Object Access (SOA) API


CWBSO_CreateListHandle (use “CWBSO_CreateListHandleEx” on page 928)

Express return codes and error messages


The Client Access Express C/C++ application programming interfaces (APIs)
support the return of an integer return code on most functions. The return codes
indicate how the function completed.
Express return codes categories:
v “Express return codes that correspond to operating system errors” on
page 16
v “Client Access return codes” on page 17
v “Express component-specific return codes” on page 20

Client Access Express logs error messages in the History Log, and on the AS/400
System.
Error messages in the History Log:
Client Access Express logs error messages in the History Log, which is
located in the Service folder.
Starting the History Log:
By default, the History Log is not active. To ensure that error
messages are written to this file, History logging must be started.
See the Express User’s Guide, which is shipped with Client Access
Express, for information on starting the History Log
Viewing logged messages:
To view messages that have been logged in the History Log, select
Start —> Programs —> IBM AS400 Client Access Express —>
Service —> History Log.

The entries in the History Log consist of messages with and without
message IDs. Messages with message IDs have online help available.
Messages without message IDs do not have online help available. To
display the cause and recovery information associated with a message that
has a message ID, double-click on it. You also can view any message that
has a message ID by selecting the Message topic in the online Express
User’s Guide.
Error messages on the AS/400 system:
Client Access Express also has associated messages that are logged on the
AS/400 system. These messages begin with PWS or IWS. To display a
specific PWSxxxx or IWSxxxx message, type the appropriate command at
the AS/400 command line prompt, where xxxx is the number of the
message:
DSPMSGD RANGE(IWSxxxx) MSGF(QIWS/QIWSMSG)

DSPMSGD RANGE(PWSxxxx) MSGF(QIWS/QIWSMSG)

Chapter 3. Express C/C++ APIs 15


Express return codes that correspond to operating system errors
0 CWB_OK
Successful completion.
1 CWB_INVALID_FUNCTION
Function not supported.
2 CWB_FILE_NOT_FOUND
File not found.
3 CWB_PATH_NOT_FOUND
Path not found.
4 CWB_TOO_MANY_OPEN_FILES
The system cannot open the file.
5 CWB_ACCESS_DENIED
Access is denied.
6 CWB_INVALID_HANDLE
The list handle is not valid.
8 CWB_NOT_ENOUGH_MEMORY
Insufficient memory, may have failed to allocate a temporary buffer.
15 CWB_INVALID_DRIVE
The system cannot find the drive specified.
18 CWB_NO_MORE_FILES
No more files are found.
21 CWB_DRIVE_NOT_READY
The device is not ready.
31 CWB_GENERAL_FAILURE
General error occurred.
32 CWB_SHARING_VIOLATION
The process cannot access the file because it is being used by
another process.
33 CWB_LOCK_VIOLATION
The process cannot access the file because another process has
locked a portion of the file.
38 CWB_END_OF_FILE
End of file has been reached.
50 CWB_NOT_SUPPORTED
The network request is not supported.
53 CWB_BAD_NETWORK_PATH
The network path was not found.
54 CWB_NETWORK_BUSY
The network is busy.
55 CWB_DEVICE_NOT_EXIST
The specified network resource or device is no longer available.
59 CWB_UNEXPECTED_NETWORK_ERROR
An unexpected network error occurred.
65 CWB_NETWORK_ACCESS_DENIED
Network access is denied.
80 CWB_FILE_EXISTS
The file exists.
85 CWB_ALREADY_ASSIGNED
The local device name is already in use.
87 CWB_INVALID_PARAMETER
A parameter is invalid.
88 CWB_NETWORK_WRITE_FAULT
A write fault occurred on the network.
110 CWB_OPEN_FAILED
The system cannot open the device or file specified.
111 CWB_BUFFER_OVERFLOW
Not enough room in the output buffer. Use *bufferSize to determine
the correct size.
112 CWB_DISK_FULL
There is not enough space on the disk.
115 CWB_PROTECTION_VIOLATION
Access is denied.
124 CWB_INVALID_LEVEL
The system call level is not correct.
142 CWB_BUSY_DRIVE
The system cannot perform a JOIN or SUBST at this time.
252 CWB_INVALID_FSD_NAME

16 Client Access Express Programming


The device name is incorrect.
253 CWB_INVALID_PATH
The network path specified is incorrect.

Client Access return codes


The following return codes apply only to Client Access:
v “Global Client Access return codes”
v “Client Access Express-specific return codes” on page 18

Global Client Access return codes:


4000 CWB_USER_CANCELLED_COMMAND
Command cancelled by user.
4001 CWB_CONFIG_ERROR
A configuration error has occurred.
4002 CWB_LICENSE_ERROR
A license error has occurred.
4003 CWB_PROD_OR_COMP_NOT_SET
Internal error due to failure to properly register and use a
product or component.
4004 CWB_SECURITY_ERROR
A security error has occurred.
4005 CWB_GLOBAL_CFG_FAILED
The global configuration attempt failed.
4006 CWB_PROD_RETRIEVE_FAILED
The product retrieve failed.
4007 CWB_COMP_RETRIEVE_FAILED
The computer retrieve failed.
4008 CWB_COMP_CFG_FAILED
The computer configuration failed.
4009 CWB_COMP_FIX_LEVEL_UPDATE_FAILED
The computer fix level update failed.
4010 CWB_INVALID_API_HANDLE
Invalid request handle.
4011 CWB_INVALID_API_PARAMETER
Invalid parameter specified.
4012 CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
4013 CWB_NOT_COMPATIBLE
Client Access program or function not at correct level.
4014 CWB_INVALID_POINTER
A pointer is NULL.
4015 CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
4016 CWB_API_ERROR
General API failure.
4017 CWB_CA_NOT_STARTED
Client Access has not been started.
4018 CWB_FILE_IO_ERROR
Record could not be read.
4019 CWB_COMMUNICATIONS_ERROR
A communications error occurred.
4020 CWB_RUNTIME_CONSTRUCTOR_FAILED
The C Run-time contstructor failed.
4021 CWB_DIAGNOSTIC
Unexpected error. Record the message number and data in the
message and contact IBM Support.
4022 CWB_COMM_VERSION_ERROR
Data queues will not run with this version of communications.
4023 CWB_NO_VIEWER
The viewer support for Client Access/400 was not installed.
4024 CWB_MODULE_NOT_LOADABLE
A filter DLL was not loadable.
4025 CWB_ALREADY_SETUP
Object has already been set up.
4026 CWB_CANNOT_START_PROCESS
Attempt to start process failed. See other error code(s).

Chapter 3. Express C/C++ APIs 17


4027 CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input UNICODE characters have no representation in the
code page that is being used.
8998 CWB_UNSUPPORTED_FUNCTION
The function is unsupported.
8999 CWB_INTERNAL_ERROR
An internal error occurred.

Client Access Express-specific return codes:


v “Express Security return codes”
v “Express Communications return codes”
v “Express configuration return codes”
v “Express Automation Object return codes” on page 19
v “Express WINSOCK return codes” on page 19
v “Express SSL return codes” on page 19

Express Security return codes:


8001 CWB_UNKNOWN_USERID
8002 CWB_WRONG_PASSWORD
8003 CWB_PASSWORD_EXPIRED
8004 CWB_INVALID_PASSWORD
8006 CWB_INCORRECT_DATA_FORMAT
8007 CWB_GENERAL_SECURITY_ERROR
8011 CWB_USER_PROFILE_DISABLED
8013 CWB_USER_CANCELLED
8014 CWB_INVALID_SYSNAME
8015 CWB_INVALID_USERID
8016 CWB_LIMITED_CAPABILITIES_USERID
8019 CWB_INVALID_TP_ON_HOST
8022 CWB_NOT_LOGGED_ON
8026 CWB_EXIT_PGM_ERROR
8050 CWB_TIMESTAMPS_NOT_SET
8257 CWB_PW_TOO_LONG
8258 CWB_PW_TOO_SHORT
8259 CWB_PW_REPEAT_CHARACTER
8260 CWB_PW_ADJACENT_DIGITS
8261 CWB_PW_CONSECUTIVE_CHARS
8262 CWB_PW_PREVIOUSLY_USED
8263 CWB_PW_DISALLOWED_CHAR
8264 CWB_PW_NEED_NUMERIC
8266 CWB_PW_MATCHES_OLD
8267 CWB_PW_NOT_ALLOWED
8268 CWB_PW_CONTAINS_USERID
8270 CWB_PW_LAST_INVALID_PWD

Express Communications return codes:


8400 CWB_INV_AFTER_SIGNON
8401 CWB_INV_WHEN_CONNECTED
8401 CWB_INV_BEFORE_VALIDATE
8403 CWB_SECURE_SOCKETS_NOTAVAIL
8404 CWB_RESERVED1
8405 CWB_RECEIVE_ERROR
8406 CWB_SERVICE_NAME_ERROR
8407 CWB_GETPORT_ERROR
8408 CWB_SUCCESS_WARNING
8409 CWB_NOT_CONNECTED
8410 CWB_DEFAULT_HOST_CCSID_USED

Express configuration return codes:


8500 CWB_RESTRICTED_BY_POLICY
8501 CWB_POLICY_MODIFY_MANDATED_ENV
8502 CWB_POLICY_MODIFY_CURRENT_ENV
8503 CWB_POLICY_MODIFY_ENV_LIST
8504 CWB_SYSTEM_NOT_FOUND

18 Client Access Express Programming


8505 CWB_ENVIRONMENT_NOT_FOUND
8506 CWB_ENVIRONMENT_EXISTS
8507 CWB_SYSTEM_EXISTS
8508 CWB_NO_SYSTEMS_CONFIGURED
8580 CWB_CONFIGERR_RESERVED_START
8599 CWB_CONFIGERR_RESERVED_END

Express Automation Object return codes:


8600 CWB_INVALID_METHOD_PARM
8601 CWB_INVALID_PROPERTY_PARM
8602 CWB_INVALID_PROPERTY_VALUE
8603 CWB_OBJECT_NOT_INITIALIZED
8604 CWB_OBJECT_ALREADY_INITIALIZED
8605 CWB_INVALID_DQ_ORDER

Express WINSOCK return codes:


10024 CWB_TOO_MANY_OPEN_SOCKETS
10035 CWB_RESOURCE_TEMPORARILY_UNAVAILABLE
10038 CWB_SOCKET_OPERATION_ON_NON_SOCKET
10047 CWB_PROTOCOL_NOT_INSTALLED
10050 CWB_NETWORK_IS_DOWN
10051 CWB_NETWORK_IS_UNREACHABLE
10052 CWB_NETWORK_DROPPED_CONNECTION_ON_RESET
10053 CWB_SOFTWARE_CAUSED_CONNECTION_ABORT
10054 CWB_CONNECTION_RESET_BY_PEER
10055 CWB_NO_BUFFER_SPACE_AVAILABLE
10057 CWB_SOCKET_IS_NOT_CONNECTED
10058 CWB_CANNOT_SEND_AFTER_SOCKET_SHUTDOWN
10060 CWB_CONNECTION_TIMED_OUT
10061 CWB_CONNECTION_REFUSED
10064 CWB_HOST_IS_DOWN
10065 CWB_NO_ROUTE_TO_HOST
10091 CWB_NETWORK_SUBSYSTEM_IS_UNAVAILABLE
10092 CWB_WINSOCK_VERSION_NOT_SUPPORTED
11001 CWB_HOST_DEFINITELY_NOT_FOUND
The AS/400 system name was not found during TCP/IP address lookup.
11002 CWB_HOST_NOT_FOUND_BUT_WE_ARE_NOT_SURE
The AS/400 system name was not found during TCP/IP address lookup.
11004 CWB_VALID_NAME_BUT_NO_DATA_RECORD
The AS/400 service name was not found in the local SERVICES file.

Express SSL return codes:


20001 CWB_SSL_ERROR_NO_CIPHERS
An I/O error occurred accessing the key database.
20002 CWB_SSL_ERROR_NO_CERTIFICATE
Open of the key database failed.
20004 CWB_SSL_ERROR_BAD_CERTIFICATE
Incorrect key database password.
20006 CWB_SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
Write to the key database failed.
20010 CWB_SSL_ERROR_IO
Certificate expired.
20011 CWB_SSL_ERROR_BAD_MESSAGE
Key already exists in the key database.
20012 CWB_SSL_ERROR_BAD_MAC
A bad message authentication code was received.
20013 CWB_SSL_ERROR_UNSUPPORTED
.
20014 CWB_SSL_ERROR_BAD_CERT_SIG
Duplicate key name in the key database.
20015 CWB_SSL_ERROR_BAD_CERT
Duplicate label in the key database.
20016 CWB_SSL_ERROR_BAD_PEER
Invalid password format for the key database.
20017 CWB_SSL_ERROR_PERMISSION_DENIED

Chapter 3. Express C/C++ APIs 19


20018 CWB_SSL_ERROR_SELF_SIGNED
20020 CWB_SSL_ERROR_BAD_MALLOC
20021 CWB_SSL_ERROR_BAD_STATE
20022 CWB_SSL_ERROR_SOCKET_CLOSED
20023 CWB_SSL_ERROR_INITIALIZATION_FAILED
20024 CWB_SSL_ERROR_HANDLE_CREATION_FAILED
20025 CWB_SSL_ERROR_BAD_DATE
20026 CWB_SSL_ERROR_BAD_KEY_LEN_FOR_EXPORT
20027 CWB_SSL_ERROR_NO_PRIVATE_KEY
20028 CWB_SSL_BAD_PARAMETER
20029 CWB_SSL_ERROR_INTERNAL
20030 CWB_SSL_ERROR_WOULD_BLOCK
20031 CWB_SSL_ERROR_LOAD_GSKLIB
20040 CWB_SSL_SOC_BAD_V2_CIPHER
20041 CWB_SSL_SOC_BAD_V3_CIPHER
20042 CWB_SSL_SOC_BAD_SEC_TYPE
20043 CWB_SSL_SOC_NO_READ_FUNCTION
20044 CWB_SSL_SOC_NO_WRITE_FUNCTION
20050 CWB_SSL_ERROR_NOT_SERVER
20051 CWB_SSL_ERROR_NOT_SSLV3
20052 CWB_SSL_ERROR_NOT_SSLV3_CLIENT
20099 CWB_SSL_ERROR_UNKNOWN_ERROR
20100 CWB_SSL_ERROR_BAD_BUFFER_SIZE
20101 CWB_SSL_ERROR_BAD_SSL_HANDLE
20102 CWB_SSL_ERROR_TIMEOUT
25001 CWB_SSL_KEYFILE_IO_ERROR
25002 CWB_SSL_KEYFILE_OPEN_FAILED
25003 CWB_SSL_KEYFILE_BAD_FORMAT
25004 CWB_SSL_KEYFILE_BAD_PASSWORD
25005 CWB_SSL_KEYFILE_BAD_MALLOC
25006 CWB_SSL_KEYFILE_NOTHING_TO_WRITE
25007 CWB_SSL_KEYFILE_WRITE_FAILED
25008 CWB_SSL_KEYFILE_NOT_FOUND
25009 CWB_SSL_KEYFILE_BAD_DNAME
25010 CWB_SSL_KEYFILE_BAD_KEY
25011 CWB_SSL_KEYFILE_KEY_EXISTS
25012 CWB_SSL_KEYFILE_BAD_LABEL
25013 CWB_SSL_KEYFILE_DUPLICATE_NAME
25014 CWB_SSL_KEYFILE_DUPLICATE_KEY
25015 CWB_SSL_KEYFILE_DUPLICATE_LABEL
25016 CWB_SSL_BAD_FORMAT_OR_INVALID_PW
25098 CWB_SSL_WARNING_INVALID_SERVER_CERT
25099 CWB_SSL_WARNING_INVALID_SERVER_PRIV_KEY
25100 CWB_SSL_ERR_INIT_PARM_NOT_VALID
25102 CWB_SSL_INIT_SEC_TYPE_NOT_VALID
25103 CWB_SSL_INIT_V2_TIMEOUT_NOT_VALID
25104 CWB_SSL_INIT_V3_TIMEOUT_NOT_VALID
25105 CWB_SSL_KEYFILE_CERT_EXPIRED

Express component-specific return codes


v “Express Administration APIs return code”
v “Express Communications APIs return codes” on page 21
v “Express Database (Optimized SQL) APIs return codes” on page 21
v “Express Data Queues APIs return codes” on page 24
v “Express Directory Update APIs return codes” on page 25
v “Express national language support APIs return codes” on page 25
v “Express AS/400 Object APIs return codes” on page 26
v “Express Remote Command/Distributed Program Call APIs return codes” on
page 27
v “Express Security APIs return codes” on page 27
v “Express Serviceability APIs return codes” on page 28
v “Express System Object Access APIs return codes” on page 29

Express Administration APIs return code:

20 Client Access Express Programming


6001 CWBAD_INVALID_COMPONENT_ID
The component ID is invalid.

Express Communications APIs return codes:


6001 CWBCO_END_OF_LIST
The end of system list has been reached. No system name was returned.
6002 CWBCO_DEFAULT_SYSTEM_NOT_DEFINED
The setting for the default system has not been defined.
6003 CWBCO_DEFAULT_SYSTEM_NOT_CONFIGURED
The default system is defined, but no connection to it is
configured.
6004 CWBCO_SYSTEM_NOT_CONNECTED
The specified system is not currently connected in the current process.
6005 CWBCO_SYSTEM_NOT_CONFIGURED
The specified system is not currently configured.
6007 CWBCO_INTERNAL_ERROR
Internal error.
6008 CWBCO_NO_SUCH_ENVIRONMENT
The specified environment does not exist.

Express Database (Optimized SQL) APIs return codes:


6001 CWBDB_CANNOT_CONTACT_SERVER
An error was encountered which prevented the Data Access server from
being started.
6002 CWBDB_ATTRIBUTES_FAILURE
An error was encountered during attempt to set the Data Access
server attributes.
6003 CWBDB_SERVER_ALREADY_STARTED
An attempt to start the Data Access server was made while a valid
server was running. Stop the server before restarting it.
6004 CWBDB_INVALID_DRDA_PKG_SIZE
The valid submitted for the DRDA package size was invalid.
6005 CWBDB_REQUEST_MEMORY_ALLOCATION_FAILURE
A memory allocation attempt by a request handle failed.
6006 CWBDB_REQUEST_INVALID_CONVERSION
A Request handle failed in an attempt to convert data.
6007 CWBDB_SERVER_NOT_ACTIVE
The Data Access server is not started. It must be started before
continuing.
6008 CWBDB_PARAMETER_ERROR
Attempt to set a parameter failed. Re-try. If error persists, there
may be a lack of available memory.
6009 CWBDB_CLONE_CREATION_ERROR
Could not create a clone request.
6010 CWBDB_INVALID_DATA_FORMAT_FOR_CONNECTION
The data format object was not valid for this connection.
6011 CWBDB_DATA_FORMAT_IN_USE
The data format object is already being used by another request.
6012 CWBDB_INVALID_DATA_FORMAT_FOR_DATA
The data format object does not match the format of the data.
6013 CWBDB_STRING_ARG_TOO_LONG
The string provided was too long for the parameter.
6014 CWBDB_INVALID_INTERNAL_ARG
Invalid internally generated argument (not user supplied).
6015 CWBDB_INVALID_NUMERIC_ARG
Value of numeric argument is invalid.
6016 CWBDB_INVALID_ARG
Value of argument is invalid.
6017 CWBDB_STMT_NOT_SELECT
The statement provided was not a SELECT statement. This call requires
a SELECT statement.
6018 CWBDB_STREAM_FETCH_NOT_COMPLETE
The connection is in stream fetch mode. Cannot perform desired
operation until stream fetch has ended.
6019 CWBDB_STREAM_FETCH_NOT_ACTIVE
The connection is not in stream fetch mode and must be in order to

Chapter 3. Express C/C++ APIs 21


perform the desired operation.
6020 CWBDB_MISSING_DATA_PROCESSOR
Pointer to data processor in request object is null.
6021 CWBDB_ILLEGAL_CLONE_REQUEST_TYPE
Cannot create a clone of an attributes request.
6022 CWBDB_UNSOLICITED_DATA
Data were received from the server, but none were requested.
6023 CWBDB_MISSING_DATA
Data were requested from the server, but not all were received.
6024 CWBDB_PARM_INVALID_BITSTREAM
Bitstream within a parameter is invalid.
6025 CWBDB_CONSISTENCY_TOKEN_ERROR
The data format used to interpret the data from the AS/400 does not
match the data returned.
6026 CWBDB_INVALID_FUNCTION
The function is invalid for this type of request.
6027 CWBDB_FORMAT_INVALID_ARG
A parameter value passed to the API was not valid.
6028 CWBDB_INVALID_COLUMN_POSITION
The column position passed to the API was not valid.
6029 CWBDB_INVALID_COLUMN_TYPE
The column type passed to the API was not valid.
6030 CWBDB_ROW_VECTOR_NOT_EMPTY
Invalid or corrupted format handle.
6031 CWBDB_ROW_VECTOR_EMPTY
Invalid or corrupted format handle.
6032 CWBDB_MEMORY_ALLOCATION_FAILURE
An error occurred while attempting to allocate memory.
6033 CWBDB_INVALID_CONVERSION
An invalid type conversion was attempted.
6034 CWBDB_DATASTREAM_TOO_SHORT
The data stream received from the host was too short.
6035 CWBDB_SQL_WARNING
The database server received a warning from an SQL operation.
6036 CWBDB_SQL_ERROR
The database server received an error from an SQL operation.
6037 CWBDB_SQL_PARAMETER_WARNING
The database server received a warning about a parameter used in an
SQL operation.
6038 CWBDB_SQL_PARAMETER_ERROR
The database server received an error about a parameter used in an
SQL operation.
6039 CWBDB_LIST_SERVER_WARNING
The database server returned a warning from a catalog operation.
6040 CWBDB_LIST_SERVER_ERROR
The database server returned an error from a catalog operation.
6041 CWBDB_LIST_PARAMETER_WARNING
The database server returned a warning about a parameter used in a
catalog operation.
6042 CWBDB_LIST_PARAMETER_ERROR
The database server returned an error about a parameter used in a
catalog operation.
6043 CWBDB_NDB_FILE_SERVER_WARNING
The database server returned a warning from a file processing
operation.
6044 CWBDB_NDB_FILE_SERVER_ERROR
The database server returned an error from a file processing operation.
6045 CWBDB_FILE_PARAMETER_WARNING
The database server returned a warning about a parameter used in a
file processing operation.
6046 CWBDB_FILE_PARAMETER_ERROR
The database server returned an error about a parameter used in a
file processing operation.
6047 CWBDB_GENERAL_SERVER_WARNING
The database server returned a general warning.
6048 CWBDB_GENERAL_SERVER_ERROR
The database server returned a general error.

22 Client Access Express Programming


6049 CWBDB_EXIT_PROGRAM_WARNING
The database server returned a warning from an exit program.
6050 CWBDB_EXIT_PROGRAM_ERROR
The database server returned an error from an exit program.
6051 CWBDB_DATA_BUFFER_TOO_SMALL
Target data buffer is smaller than source buffer.
6052 CWBDB_NL_CONVERSION_ERROR
Received error back from PiNlConverter.
6053 CWBDB_COMMUNICATIONS_ERROR
Received a communications error during processing.
6054 CWBDB_INVALID_ARG_API
Value of argument is invalid - API level.
6055 CWBDB_MISSING_DATA_HANDLER
Data handler not found in data handler list.
6056 CWBDB_REQUEST_DATASTREAM_NOT_VALID
Invalid datastream in catalog request.
6057 CWBDB_SERVER_UNABLE
Server incapable of performing desired function.

The following return codes are returned by the


cwbDB_StartServerDetailed API:

6058 CWBDB_WORK_QUEUE_START_ERROR
Unable to start server because of client work queue problem.
6059 CWBDB_WORK_QUEUE_CREATE_ERROR
Unable to start server because of client work queue problem.
6060 CWBDB_INITIALIZATION_ERROR
Unable to start server because of client initialization problem.
6061 CWBDB_SERVER_ATTRIBS_ERROR
Unable to start server because of server attribute problem.
6062 CWBDB_CLIENT_LEVEL_ERROR
Unable to start server because of set client level problem.
6063 CWBDB_CLIENT_LFC_ERROR
Unable to start server because of set client language feature
code problem.
6064 CWBDB_CLIENT_CCSID_ERROR
Unable to start server because of set client CCSID problem.
6065 CWBDB_TRANSLATION_INDICATOR_ERROR
Unable to start server because of set translation indicator error.
6066 CWBDB_RETURN_SERVER_ATTRIBS_ERROR
Unable to start server because of return server attribute problem.
6067 CWBDB_SERVER_ATTRIBS_REQUEST
Unable to start server because of missing server attributes request
object.
6068 CWBDB_RETURN_ATTRIBS_ERROR
Unable to start server because of return attribute problem.
6069 CWBDB_SERVER_ATTRIBS_MISSING
Unable to start server because returned server attributes too short
(missing data).
6070 CWBDB_SERVER_LFC_CONVERSION_ERROR
Unable to start server because of data conversion error on server
language feature code field of server attributes.
6071 CWBDB_SERVER_LEVEL_CONVERSION_ERROR
Unable to start server because of data conversion error on server
functional level field of server attributes.
6072 CWBDB_SERVER_LANGUAGE_TABLE_ERROR
Unable to start server because of data conversion error on server
language table ID field of server attributes.
6073 CWBDB_SERVER_LANGUAGE_LIBRARY_ERROR
Unable to start server because of data conversion error on server
language library ID field of server attributes.
6074 CWBDB_SERVER_LANGUAGE_ID_ERROR
Unable to start server because of data conversion error on server
language ID field of server attributes.
6075 CWBDB_COMM_DEQUEUE_ERROR
Unable to start server because of communications error.
6076 CWBDB_COMM_ENQUEUE_ERROR

Chapter 3. Express C/C++ APIs 23


Unable to start server because of communications error.
6077 CWBDB_UNSUPPORTED_COLUMN_TYPE
An unsupported column type was found in the data.
6078 CWBDB_SERVER_IN_USE
A connection to the database server for the given connection
handle is already being used by another connection handle which
was created with the same system object handle.
6099 CWBDB_LAST_STREAM_CHUNK
Stream fetch complete.
NOTE: Informational; not an error. There is no message or help text
for this return code.

Express Data Queues APIs return codes:


6000 CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
6001 CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
6002 CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
6003 CWBDQ_INVALID_READ_HANDLE
Invalid data queue read handle.
6004 CWBDQ_INVALID_QUEUE_LENGTH
Invalid maximum record length for a data queue.
6005 CWBDQ_INVALID_KEY_LENGTH
Invalid key length.
6006 CWBDQ_INVALID_ORDER
Invalid queue order.
6007 CWBDQ_INVALID_AUTHORITY
Invalid queue authority.
6008 CWBDQ_INVALID_QUEUE_TITLE
Queue title (description) is too long or cannot be converted.
6009 CWBDQ_BAD_QUEUE_NAME
Queue name is too long or cannot be converted.
6010 CWBDQ_BAD_LIBRARY_NAME
Library name is too long or cannot be converted.
6011 CWBDQ_BAD_SYSTEM_NAME
System name is too long or cannot be converted.
6012 CWBDQ_BAD_KEY_LENGTH
Length of key is not correct for this data queue or key length is
greater than 0 for a LIFO or FIFO data queue.
6013 CWBDQ_BAD_DATA_LENGTH
Length of data is not correct for this data queue. Either the data
length is zero or it is greater than the maximum allowed of
31744 bytes (64512 bytes for V4R5 and later versions of OS/400).
Note: The maximum allowed data lengh when connected to OS/400
V4R5MO and later systems has been increased to 64512 bytes.
When connected to earlier releases o OS/400, 64512 bytes of data
may be written to a data queue, but the maximum length of data that
may be read from a data queue is 31744 bytes.
6014 CWBDQ_INVALID_TIME
Wait time is not correct.
6015 CWBDQ_INVALID_SEARCH
Search order is not correct.
6016 CWBDQ_DATA_TRUNCATED
Returned data was truncated.
6017 CWBDQ_TIMED_OUT
Wait time has expired and no data has been returned.
6018 CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
6019 CWBDQ_USER_EXIT_ERROR
Error in user exit program or invalid number of exit programs.
6020 CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
6021 CWBDQ_QUEUE_NOT_FOUND
Queue not found on system.
6022 CWBDQ_NO_AUTHORITY
No authority to library or data queue.

24 Client Access Express Programming


6023 CWBDQ_DAMAGED_QUEUE
Data queue is in an unusable state.
6024 CWBDQ_QUEUE_EXISTS
Data queue already exists.
6025 CWBDQ_INVALID_MESSAGE_LENGTH
Invalid message length - exceeds queue maximum record length.
6026 CWBDQ_QUEUE_DESTROYED
Queue destroyed while waiting to read or peek a record.
6027 CWBDQ_NO_DATA
No data was received.
6028 CWBDQ_CANNOT_CONVERT
Data cannot be converted for this data queue. The data queue can be
used but data cannot be converted between ASCII and EBCDIC. The
convert flag on the data object will be ignored.
6029 CWBDQ_QUEUE_SYNTAX
Syntax of the data queue name is incorrect. Queue name must follow
AS/400 object syntax. First character must be alphabetic and all
following characters alphanumeric.
6030 CWBDQ_LIBRARY_SYNTAX
Syntax of the library name is incorrect. Library name must follow
AS/400 object syntax. First character must be alphabetic and all
following characters alphanumeric.
6031 CWBDQ_ADDRESS_NOT_SET
Address not set. The data object was not set with cwbDQ_SetDataAddr(),
so the address cannot be retrieved. Use cwbDQ_GetData() instead of
cwbDQ_GetDataAddr().
6032 CWBDQ_HOST_ERROR
Host error occurred for which no return code is defined. See the
error handle for the message text.
6033 CWBDQ_INVALID_SYSTEM_HANDLE
System handle is invalid.
6099 CWBDQ_UNEXPECTED_ERROR
Unexpected error.

Express Directory Update APIs return codes:


6000 CWBUP_ENTRY_NOT_FOUND
No update entry matched search value.
6001 CWBUP_SEARCH_POSITION_ERROR
Search starting position is not valid.
6002 CWBUP_PACKAGE_NOT_FOUND
The package file was not found.
6003 CWBUP_POSITION_INVALID
Position that is given is not in range.
6004 CWBUP_TOO_MANY_ENTRIES
The maximum number of update entries already exist. No more can be
created.
6005 CWBUP_TOO_MANY_PACKAGES
Maximum number of package files already exists for this entry.
6006 CWBUP_STRING_TOO_LONG
The text string parameter passed in is longer than CWBUP_MAX_LENGTH.
6007 CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.
6008 CWBUP_UNLOCK_WARNING
Application did not have the update entries locked.

Express national language support APIs return codes:


6101 CWBNL_ERR_CNV_UNSUPPORTED
An attempt was made to convert character data from a code page to
another code page but this conversion is not supported.
6102 CWBNL_ERR_CNV_TBL_INVALID
A conversion table is in a format that is not recognized.
6103 CWBNL_ERR_CNV_TBL_MISSING
An attempt was made to use a conversion table, but the table was not
found.
6104 CWBNL_ERR_CNV_ERR_GET

Chapter 3. Express C/C++ APIs 25


A code page conversion table was being retrieved from the server
when an error occurred.
6105 CWBNL_ERR_CNV_ERR_COMM
A code page conversion table was being retrieved from the server
when a communications error occurred.
6106 CWBNL_ERR_CNV_ERR_SERVER
A code page conversion table was being retrieved from the server
when a server error occurred.
6107 CWBNL_ERR_CNV_ERR_STATUS
While converting character data from one code page to another, some
untranslatable characters were encountered.
6108 CWBNL_ERROR_CONVERSION_INCOMPLETE_MULTIBYTE_INPUT_CHARACTER
While converting character data an incomplete multibyte character
was found.
6109 CWBNL_ERR_CNV_INVALID_SISO_STATUS
The SISO parameter is incorrect.
6110 CWBNL_ERR_CNV_INVALID_PAD_LENGTH
The pad length parameter is incorrect.

The following return codes are for language APIs:

6201 CWBNL_ERR_STR_TBL_INVALID
Message file not in a recognized format. It has been corrupted.
6202 CWBNL_ERR_STR_TBL_MISSING
Message file could not be found.
6203 CWBNL_ERR_STR_NOT_FOUND
The message file is missing a message.
6204 CWBNL_ERR_NLV_NO_CONFIG
The language configuration is missing.
6205 CWBNL_ERR_NLV_NO_SUBDIR
The language subdirectory is missing.
6206 CWBNL_DEFAULT_HOST_CCSID_USED
A default server CCSID (500) is used.

The following return codes are for locale APIs:

6301 CWBNL_ERR_LOC_TBL_INVALID
6302 CWBNL_ERR_LOC_TBL_MISSING
6303 CWBNL_ERR_LOC_NO_CONFIG
6304 CWBNL_ERR_LOC_NO_LOCPATH

Express AS/400 Object APIs return codes:


6000 CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
6001 CWBOBJ_RC_INVALID_TYPE
Incorrect object type.
6002 CWBOBJ_RC_INVALID_KEY
Incorrect key.
6003 CWBOBJ_RC_INVALID_INDEX
Bad index to list.
6004 CWBOBJ_RC_LIST_OPEN
The list is already opened.
6005 CWBOBJ_RC_LIST_NOT_OPEN
The list has not been opened.
6006 CWBOBJ_RC_SEEKOUTOFRANGE
Seek offset is out of range.
6007 CWBOBJ_RC_SPLFNOTOPEN
Spooled file has not been opened.
6007 CWBOBJ_RC_RSCNOTOPEN
Resource has not been opened.
6008 CWBOBJ_RC_SPLFENDOFFILE
End of file was reached.
6008 CWBOBJ_RC_ENDOFFILE
End of file was reached.
6009 CWBOBJ_RC_SPLFNOMESSAGE
The spooled file is not waiting on a message.
6010 CWBOBJ_RC_KEY_NOT_FOUND

26 Client Access Express Programming


The parameter list does not contain the specified key.
6011 CWBOBJ_RC_NO_EXIT_PGM
No exit program registered.
6012 CWBOBJ_RC_NOHOSTSUPPORT
Host does not support function.

Express Remote Command/Distributed Program Call APIs return codes:


6000 CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.
6001 CWBRC_INVALID_PROGRAM
Invalid program handle.
6002 CWBRC_SYSTEM_NAME
System name is too long or cannot be converted.
6003 CWBRC_COMMAND_STRING
Command string is too long or cannot be converted.
6004 CWBRC_PROGRAM_NAME
Program name is too long or cannot be converted.
6005 CWBRC_LIBRARY_NAME
Library name is too long or cannot be converted.
6006 CWBRC_INVALID_TYPE
Invalid parameter type specified.
6007 CWBRC_INVALID_PARM_LENGTH
Invalid parameter length.
6008 CWBRC_INVALID_PARM
Invalid parameter specified.
6009 CWBRC_TOO_MANY_PARMS
Attempt to add more than 25 parameters to a program.
6010 CWBRC_INDEX_RANGE_ERROR
Index is out of range for this program.
6011 CWBRC_REJECTED_USER_EXIT
Command rejected by user exit program.
6012 CWBRC_USER_EXIT_ERROR
Error in user exit program.
6013 CWBRC_COMMAND_FAILED
Command failed.
6014 CWBRC_PROGRAM_NOT_FOUND
Program not found or could not be accessed.
6015 CWBRC_PROGRAM_ERROR
Error occurred when calling the program.
6016 CWBRC_COMMAND_TOO_LONG
Command string is longer than the maximum of 6000 characters.
6099 CWBRC_UNEXPECTED_ERROR
Unexpected error.

Express Security APIs return codes:


6000 CWBSY_UNKNOWN_USERID
User ID does not exist.
6002 CWBSY_WRONG_PASSWORD
Password is not correct for specified user ID.
6003 CWBSY_PASSWORD_EXPIRED
Password has expired.
6004 CWBSY_INVALID_PASSWORD
One or more characters in the password are not valid or the password
is too long.
6007 CWBSY_GENERAL_SECURITY_ERROR
A general security error occurred. The user profile does not have a
password or the password validation program found an error in the
password.
6009 CWBSY_INVALID_PROFILE
The AS/400 user profile is not valid.
6011 CWBSY_USER_PROFILE_DISABLED
The AS/400 user profile (user ID) has been set to disabled.
6013 CWBSY_USER_CANCELLED
The user cancelled from the user ID/password prompt.
6015 CWBSY_INVALID_USERID
One or more characters in the user ID is not valid or the user ID is

Chapter 3. Express C/C++ APIs 27


too long.
6016 CWBSY_UNKNOWN_SYSTEM
The system specified is unknown.
6019 CWBSY_TP_NOT_VALID
The PC could not validate the AS/400 security server. This could
indicate tampering with the IBM supplied security server program on
the AS/400.
6022 CWBSY_NOT_LOGGED_ON
There is no user currently logged on for the specified system.
6025 CWBSY_SYSTEM_NOT_CONFIGURED
The system specified in the security object has not been configured.
6026 CWBSY_NOT_VERIFIED
The user ID and password defined in the object has not yet been
verified. You must verify using cwbSY_VerifyUserIDPwd API.
6255 CWBSY_INTERNAL_ERROR
Internal error. Contact IBM Service.

The following return codes are for change password APIs:

6257 CWBSY_PWD_TOO_LONG
The new password contains too many characters. The maximum number of
characters allowed is defined by the AS/400 system value, QPWDMAXLEN.
6258 CWBSY_PWD_TOO_SHORT
The new password does not contain enough characters. The minimum
number of characters allowed is defined by the AS/400 system value,
QPWDMINLEN.
6259 CWBSY_PWD_REPEAT_CHARACTER
The new password contains a character used more than once. The AS/400
configuration (system value QPWDLMTREP) does not allow passwords to
contain a repeat character.
6260 CWBSY_PWD_ADJACENT_DIGITS
The new password contains two numbers next to each other. The AS/400
configuration (system value QPWDLMTAJC) does not allow passwords to
contain consecutive digits.
6261 CWBSY_PWD_CONSECUTIVE_CHARS
The new password contains a character repeated consecutively. The
AS/400 configuration (system value QPWDLMTREP) does not allow a
password to contain a character repeated consecutively.
6262 CWBSY_PWD_PREVIOUSLY_USED
The new password matches a previously used password. The AS/400
configuration (system value QPWDRQDDIF) requires new passwords to be
different than any previous password.
6263 CWBSY_PWD_DISALLOWED_CHAR
The new password uses an installation disallowed character. AS/400
configuration (system value QPWDLMTCHR) restricts certain characters
from being used in new passwords.
6264 CWBSY_PWD_NEED_NUMERIC
The new password must contain a number. The AS/400 configuration
(system value QPWDRQDDGT) requires new passwords contain one or more
numeric digits.
6266 CWBSY_PWD_MATCHES_OLD
The new password matches an old password in one or more character
positions. The AS/400 configuration (system value QPWDPOSDIF) does
not allow the same character to be in the same position as a
previous password.
6267 CWBSY_PWD_NOT_ALLOWED
The password was rejected.
6268 CWBSY_PWD_MATCHES_USERID
The password matches the user ID.
6269 CWBSY_PWD_PRE_V3
The old password was created on a pre-V3 system which used a
different encryption technique. Password must be changed manually on
the AS/400.
6270 CWBSY_LAST_INVALID_PASSWORD
The next invalid will disable the user profile.

Express Serviceability APIs return codes:

28 Client Access Express Programming


6000 CWBSV_INVALID_FILE_TYPE
Unusable file type passed-in.
6001 CWBSV_INVALID_RECORD_TYPE
Unusable record type passed-in.
6002 CWBSV_INVALID_EVENT_TYPE
Unusable event type detected.
6003 CWBSV_NO_ERROR_MESSAGES
No error messages associated with error handle.
6004 CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.
6005 CWBSV_INVALID_MSG_CLASS
Unusable message class passed-in.

Express System Object Access APIs return codes:

0 CWBSO_NO_ERROR
No error occurred.
1 CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.
2 CWBSO_LOW_MEMORY
Not enough memory is available for the request.
3 CWBSO_BAD_LISTTYPE
The value specified for type of list is not valid.
4 CWBSO_BAD_HANDLE
The handle specified is not valid.
5 CWBSO_BAD_LIST_HANDLE
The list handle specified is not valid.
6 CWBSO_BAD_OBJ_HANDLE
The object handle specified is not valid.
7 CWBSO_BAD_PARMOBJ_HANDLE
The parameter object handle specified is not valid.
8 CWBSO_BAD_ERR_HANDLE
The error handle specified is not valid.
9 CWBSO_BAD_LIST_POSITION
The position in list specified does not exist.
10 CWBSO_BAD_ACTION_ID
An action ID specified is not valid for the type of list.
11 CWBSO_NOT_ALLOWED_NOW
The action requested is not allowed at this time.
12 CWBSO_BAD_INCLUDE_ID
The filter ID specified is not valid for this list.
13 CWBSO_DISP_MSG_FAILED
The request to display the message failed.
14 CWBSO_GET_MSG_FAILED
The error message text could not be retrieved.
15 CWBSO_BAD_SORT_ID
A sort ID specified is not valid for the type of list.
16 CWBSO_INTERNAL_ERROR
An internal processing error occurred.
17 CWBSO_NO_ERROR_MESSAGE
The error handle specified contains no error message.
18 CWBSO_BAD_ATTRIBUTE_ID
The attribute key is not valid for this object.
19 CWBSO_BAD_TITLE
The title specified is not valid.
20 CWBSO_BAD_FILTER_VALUE
The filter value specified is not valid.
21 CWBSO_BAD_PROFILE_NAME
The profile name specified is not valid.
22 CWBSO_DISPLAY_FAILED
The window could not be created.
23 CWBSO_SORT_NOT_ALLOWED
Sorting is not allowed for this type of list.
24 CWBSO_CANNOT_CHANGE_ATTR
Attribute is not changeable at this time.
25 CWBSO_CANNOT_READ_PROFILE
Cannot read from the specified profile file.

Chapter 3. Express C/C++ APIs 29


26 CWBSO_CANNOT_WRITE_PROFILE
Cannot write to the specified profile file.
27 CWBSO_BAD_SYSTEM_NAME
The system name specified is not a valid AS/400 system name.
28 CWBSO_SYSTEM_NAME_DEFAULTED
No system name was specified on the "CWBSO_CreateListHandle" call
for the list.
29 CWBSO_BAD_FILTER_ID
The filter ID specified is not valid for the type of list.

Express Administration APIs


Client Access Express Administration APIs provide functions that access
information about the Client Access Express code that is installed on the PC.
Administration APIs allow you to determine:
v The version and service level of Client Access Express
v The install status of individual components
v The install status of Operations Navigator plug-ins
Express Administration APIs required files:

Header file Import library Dynamic Link Library


cwbad.h cwbapi.lib cwbad.dll

Express Toolkit:
The Client Access Express Toolkit provides Administration APIs
documentation, access to the cwbad.h header file, and links to sample
programs. To access this information, open the Express Toolkit and select
Client Information —> C/C++ APIs.
Express Administration APIs topics:
v Express Administration APIs listing
v “Example: Express Administration APIs” on page 37
v “Express Administration APIs return code” on page 20
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Express Administration APIs listing


v cwbAD_GetClientVersion
v cwbAD_GetProductFixLevel
v cwbAD_IsComponentInstalled
v cwbAD_IsOpNavPluginInstalled

30 Client Access Express Programming


cwbAD_GetClientVersion
Purpose: Get the version of the Client Access product that currently is installed
on a PC.

Syntax:

unsigned int CWB_ENTRY cwbAD_GetClientVersion(


unsigned long *version
unsigned long *release
unsigned long *modificationLevel);

Parameters:
unsigned long *version - output
Pointer to a buffer where the version level of the Client Access product is
returned.
unsigned long *release - output
Pointer to a buffer where the release level of the Client Access product is
returned.
unsigned long *modificationLevel - output
Pointer to a buffer where the modification level of the Client Access product is
returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
One or more pointer parameters are null.

Usage: If the return code is not CWB_OK, the values in version, release, and
modificationLevel are meaningless.

Chapter 3. Express C/C++ APIs 31


cwbAD_GetProductFixLevel
Purpose: Returns the current fix level of Client Access.

Syntax:

unsigned int CWB_ENTRY cwbAD_GetProductFixLevel(


char *szBuffer
unsigned long *ulBufLen);

Parameters:
char *szBuffer - output
Buffer into which the product fix level string will be written.
unsigned long * ulBufLen - input/output
Size of szBuffer, including space for the NULL terminator. On output, will
contain the length of the fix level string, including the terminating NULL.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Buffer overflow. The required length is returned in ulBufLen.
CWB_INVALID_POINTER
Invalid pointer.

Usage: Returns the fix level of the Client Access product. Returns an empty string
if fixes have not been applied.

32 Client Access Express Programming


cwbAD_IsComponentInstalled
Purpose: Indicates whether a specific Client Access component is installed.

Syntax:

unsigned long CWB_ENTRY cwbAD_IsComponentInstalled(


unsigned long ulComponentID,
cwb_Boolean *bIndicator);

Parameters:
unsigned long ulComponentID - input
Must be set to one of the following component IDs:
CWBAD_COMP_SSL
Secure Sockets Layer
CWBAD_COMP_SSL_128_BIT
Secure Sockets Layer 128 bit
CWBAD_COMP_SSL_56_BIT
Secure Sockets Layer 56 bit
CWBAD_COMP_SSL_40_BIT
Secure Sockets Layer 40 bit
CWB_COMP_BASESUPPORT
Express required programs
CWBAD_COMP_OPTIONAL_COMPS
Express Optional Components
CWBAD_COMP_DIRECTORYUPDATE
Directory Update
CWBAD_COMP_IRC
Incoming Remote Command
CWBAD_COMP_MAPI
MAPI
CWBAD_COMP_OUG
Express Online User’s Guide
CWBAD_COMP_OPNAV
AS/400 Operations Navigator
CWBAD_COMP_DATA_ACCESS
Data Access
CWBAD_COMP_DATA_TRANSFER
Data Transfer
CWBAD_COMP_DT_BASESUPPORT
Data Transfer Base Support
CWBAD_COMP_DT_EXCEL_ADDIN
Data Transfer Excel Add-in
CWBAD_COMP_DT_WK4SUPPORT
Data Transfer WK4 file support
CWBAD_COMP_ODBC
ODBC

Chapter 3. Express C/C++ APIs 33


CWBAD_COMP_OLEDB
OLE DB Provider
CWBAD_COMP_AFP_VIEWER
AFP™ Workbench Viewer
CWBAD_COMP_JAVA_TOOLBOX
AS/400 Java Toolbox
CWBAD_COMP_PC5250
PC5250 Display and Printer Emulator
PC5250 Display and Printer Emulator subcomponents:
CWBAD_COMP_PC5250_BASE_KOREAN
CWBAD_COMP_PC5250_PDFPDT_KOREAN
CWBAD_COMP_PC5250_BASE_SIMPCHIN
CWBAD_COMP_PC5250_PDFPDT_SIMPCHIN
CWBAD_COMP_PC5250_BASE_TRADCHIN
CWBAD_COMP_PC5250_PDFPDT_TRADCHIN
CWBAD_COMP_PC5250_BASE_STANDARD
CWBAD_COMP_PC5250_PDFPDT_STANDAR
CWBAD_COMP_PC5250_FONT_ARABIC
CWBAD_COMP_PC5250_FONT_BALTIC
CWBAD_COMP_PC5250_FONT_LATIN2
CWBAD_COMP_PC5250_FONT_CYRILLIC
CWBAD_COMP_PC5250_FONT_GREEK
CWBAD_COMP_PC5250_FONT_HEBREW
CWBAD_COMP_PC5250_FONT_LAO
CWBAD_COMP_PC5250_FONT_THAI
CWBAD_COMP_PC5250_FONT_TURKISH
CWBAD_COMP_PC5250_FONT_VIET
CWBAD_COMP_PRINTERDRIVERS
Printer Drivers
CWBAD_COMP_AFP_DRIVER
AFP printer driver
CWBAD_COMP_SCS_DRIVER
SCS printer driver
CWBAD_COMP_OP_CONSOLE
AS/400 Operations Console
CWBAD_COMP_TOOLKIT
Client Access Express Toolkit
CWBAD_COMP_TOOLKIT_BASE
Headers, Libraries, and Documentation
CWBAD_COMP_TOOLKIT_VBW
Visual Basic Wizard
CWBAD_COMP_OPNAV_BASESUPPORT
Operations Navigator Base Support
CWBAD_COMP_OPNAV_BASE_OPS
Operations Navigator Basic Operations

34 Client Access Express Programming


CWBAD_COMP_OPNAV_JOB_MGMT
Operations Navigator Job Management
CWBAD_COMP_OPNAV_SYS_CFG
Operations Navigator System Configuration
CWBAD_COMP_OPNAV_NETWORK
Operations Navigator Networks
CWBAD_COMP_OPNAV_SECURITY
Operations Navigator Security
CWBAD_COMP_OPNAV_USERS_GROUPS
Operations Navigator Users and Groups
CWBAD_COMP_OPNAV_DATABASE
Operations Navigator Database
CWBAD_COMP_OPNAV_MULTIMEDIA
Operations Navigator Multimedia
CWBAD_COMP_OPNAV_BACKUP
Operations Navigator Backup
CWBAD_COMP_OPNAV_APP_DEV
Operations Navigator Application Development
CWBAD_COMP_OPNAV_APP_ADMIN
Operations Navigator Application Administration
CWBAD_COMP_OPNAV_FILE_SYSTEMS
Operations Navigator File Systems
CWBAD_COMP_OPNAV_MGMT_CENTRAL
Operations Navigator Management Central
cwb_Boolean *bIndicator - output
Will contain CWB_TRUE if the component is installed. Will return
CWB_FALSE if the component is not installed. Will not be set if an error
occurs.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Invalid pointer.
CWB_INVALID_COMPONENT_ID
The component ID is invalid for this release.

Chapter 3. Express C/C++ APIs 35


cwbAD_IsOpNavPluginInstalled
Purpose: Indicates whether a specific Operations Navigator plug-in is installed.

Syntax:

unsigned long CWB_ENTRY cwbAD_IsOpNavPluginInstalled(


const char *szPluginName,
cwb_Boolean *bIndicator);

Parameters:
const char* szPluginName - input
Pointer to a null-terminated string that contains the name of the plug-in.
cwb_Boolean *bIndicator - output
Will contain CWB_TRUE if the plug-in is installed. Will return CWB_FALSE if
the component is not installed. Will not be set if an error occurs.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
One of the pointer parameters is NULL.

Usage: If the return value is not CWB_OK, the value in bIndicator is meaningless.

36 Client Access Express Programming


Example: Express Administration APIs
This example demonstrates how an application might use Client Access Express
Administration APIs. In this example, the APIs are used to get and display:
v The current Client Access Version/Release/Modification level
v The current service pack (fix) level
v The components that currently are installed on the PC
The user then is allowed to enter Operations Navigator plug-in names, and is
informed whether the plug-in is installed.
Usage notes:
Include cwbad.h *
Link with cwbapi.lib
#include <windows.h>
#include <stdio.h>

#include "cwbad.h"

/*
* This is the highest numbered component ID we know about (it is
* the ID of the last component defined in cwbad.h).
*/
#define LAST_COMPID_WE_KNOW_ABOUT (CWBAD_COMP_SSL_40_BIT)

/*
* Array of component names, taken from comments for component IDs
* in cwbad.h, so we can display human-readable component descriptions.
* In the compDescr array, the component ID for a component must match
* the index in the array of that component's description.
*
* For a blank or unknown component name, we provide a string to display
* an indication that the component ID is unknown, and what that ID is.
*/
static char* compDescr[ LAST_COMPID_WE_KNOW_ABOUT + 1 ] = {
"", // #0 is not used
"Express required programs",
"Express Optional Components",
"Directory Update",
"Incoming Remote Command",
"MAPI",
"Express Online User's Guide",
"AS400 Operations Navigator",
"Data Access",
"Data Transfer",
"Data Transfer Base Support",
"Data Transfer Excel Add-in",
"Data Transfer WK4 file support",
"ODBC",
"OLE DB Provider",
"AFP Workbench Viewer",
"AS400 Java Toolbox",
"5250 Display and Printer Emulator",
"Printer Drivers",
"AFP printer driver",
"SCS printer driver",
"AS400 Operations Console",
"Client Access Express Toolkit",
"Headers, Libraries, and Documentation",
"Visual Basic Wizards", // #24
"", "", "", "", "", //------------ #25-29
"", "", "", "", "", // #30-34
"", "", "", "", "", // #35-39
"", "", "", "", "", // #40-44
"", "", "", "", "", // #45-49
"", "", "", "", "", // not #50-54
"", "", "", "", "", // #55-59
"", "", "", "", "", // #60-64
"", "", "", "", "", // #65-69
"", "", "", "", "", // used #70-74
"", "", "", "", "", // #75-79
"", "", "", "", "", // #80-84
"", "", "", "", "", // #85-89
"", "", "", "", "", // #90-94
"", "", "", "", "", //------------ #95-99
"Operations Navigator Base Support", // #100
"Operations Navigator Basic Operations",
"Operations Navigator Job Management",
"Operations Navigator System Configuration",

Chapter 3. Express C/C++ APIs 37


"Operations Navigator Networks",
"Operations Navigator Security",
"Operations Navigator Users and Groups",
"Operations Navigator Database",
"Operations Navigator Multimedia",
"Operations Navigator Backup",
"Operations Navigator Application Development",
"Operations Navigator Application Administrat",
"Operations Navigator File Systems",
"Operations Navigator Management Central",
"", //------------ #114
"", "", "", "", "", // #115-119
"", "", "", "", "", // not #120-124
"", "", "", "", "", // #125-129
"", "", "", "", "", // #130-134
"", "", "", "", "", // used #135-139
"", "", "", "", "", // #140-144
"", "", "", "", "", //------------ #145-149
"PC5250: BASE_KOREAN", // #150
"PC5250: PDFPDT_KOREAN",
"PC5250: BASE_SIMPCHIN",
"PC5250: PDFPDT_SIMPCHIN",
"PC5250: BASE_TRADCHIN",
"PC5250: PDFPDT_TRADCHIN",
"PC5250: BASE_STANDARD",
"PC5250: PDFPDT_STANDARD",
"PC5250: FONT_ARABIC",
"PC5250: FONT_BALTIC",
"PC5250: FONT_LATIN2",
"PC5250: FONT_CYRILLIC",
"PC5250: FONT_GREEK",
"PC5250: FONT_HEBREW",
"PC5250: FONT_LAO",
"PC5250: FONT_THAI",
"PC5250: FONT_TURKISH",
"PC5250: FONT_VIET",
"", "", //------------ #168-169
"", "", "", "", "", // #170-174
"", "", "", "", "", // not #175-179
"", "", "", "", "", // #180-184
"", "", "", "", "", // used #185-189
"", "", "", "", "", // #190-194
"", "", "", "", "", //------------ #195-199
"Secure Sockets Layer (SSL)",
"SSL 128-bit subcomponent",
"SSL 56-bit subcomponent",
"SSL 40-bit subcomponent" } ; // last one defined
static char unknownComp[] = "unknown, ID= ";
static char* pInsertID = &amp;( unknownComp[12] ); // insert ID here!

/**************************************************************************
* Show the Client Access Version/Release/Modification level
**************************************************************************/
void showCA_VRM()
{
ULONG caVer, caRel, caMod;
UINT rc;
char fixlevelBuf[ MAX_PATH ];
ULONG fixlevelBufLen = sizeof( fixlevelBuf );

printf( "Client Access level installed:\n\n" );

rc = cwbAD_GetClientVersion( &caVer;, &caRel;, &caMod; );


if ( rc != CWB_OK )
{
printf( " Error %u occurred when calling cwbAD_GetClientVersion()\n\n",
rc );
}
else
{
printf( " Version %lu, Release %lu, Modification %lu\n\n",
caVer, caRel, caMod );

printf( "Client Access service pack level installed:\n\n" );


rc = cwbAD_GetProductFixLevel( fixlevelBuf, &fixlevelBufLen; );
if ( rc != CWB_OK )
{
printf( " Error %u occurred when calling "
"cwbAD_GetProduceFixLevel()\n\n", rc );
}
else if ( fixlevelBuf[0] == '\0' ) // empty, no service packs applied
{
printf( " None\n\n" );
}
else
{

38 Client Access Express Programming


printf( " %s\n\n", fixlevelBuf );
}
}
}

/**************************************************************************
* Call Client Access API to determine if the component is installed,
* and pass back:
* NULL if the component is not installed or an error occurs,
* OR
* A string indicating the component name is unknown if the
* component ID is higher than we know about OR the component
* description is blank,
* OR
* The human-readable component description if we know it.
**************************************************************************/
char* isCompInstalled( ULONG compID )
{
cwb_Boolean bIsInstalled;
char* pCompName;

UINT rc = cwbAD_IsComponentInstalled( compID, &bIsInstalled; );

/*
* Case 1: Error OR component not installed, return NULL to
* indicate not installed.
*/
if ( ( rc != CWB_OK ) || ( bIsInstalled == CWB_FALSE ) )
{
pCompName = NULL;
}

/*
* Case 2: Component IS installed, but we do not know its name,
* return component name unknown string.
*/
else if ( ( compID > LAST_COMPID_WE_KNOW_ABOUT ) ||
( compDescr[ compID ][ 0 ] == '\0' ) )
{
pCompName = unknownComp;
sprintf( pInsertID, "%lu", compID );
}

/*
* Case 3: Component IS installed, we have a name, return it
*/
else
{
pCompName = compDescr[ compID ];
}

return pCompName;
}

/**************************************************************************
* List the Client Access components that currently are installed.
**************************************************************************/
void showCA_CompInstalled()
{
ULONG compID;
char* compName;

printf( "Client Access components installed:\n\n" );


/*
* Try all components we know about, plus a bunch more in case some
* have been added (via service pack).
*/
for ( compID = 0;
compID &lt; (LAST_COMPID_WE_KNOW_ABOUT + 50);
compID++ )
{
compName = isCompInstalled( compID );
if ( compName != NULL )
{
printf( " %s\n", compName );
}
}
printf( "\n" );
}

/**************************************************************************

Chapter 3. Express C/C++ APIs 39


* MAIN PROGRAM BODY
**************************************************************************/
void main(void)
{
UINT rc;
char pluginName[ MAX_PATH ];
cwb_Boolean bPluginInstalled;

printf( "=======================================\n");
printf( "Client Access What's Installed Reporter\n" );
printf( "=======================================\n\n");

showCA_VRM();
showCA_CompInstalled();

/*
* Allow user to ask by name what plug-ins are installed.
*/
while ( TRUE ) /* REMINDER: requires a break to exit the loop! */
{
printf( "Enter plug-in to check for, or DONE to quit:\n" );
gets( pluginName );
if ( stricmp( pluginName, "DONE" ) == 0 )
{
break; /* exit from the while loop, we are DONE at user's request */
}
rc = cwbAD_IsOpNavPluginInstalled( pluginName, &bPluginInstalled; );
if ( rc == CWB_OK )
{
if ( bPluginInstalled == CWB_TRUE )
{
printf( "The plug-in '%s' is installed.\n\n", pluginName );
}
else
{
printf( "The plug-in '%s' is NOT installed.\n\n", pluginName );
}
}
else
{
printf(
"Error %u occurred when calling cwbAD_IsOpNavPluginInstalled.\n\n",
rc );
}
} // end while (TRUE)

printf( "\nEnd of program.\n\n" );


}

Express Communications and Security APIs


The Client Access Express Communications and Security topic shows you how to
use Express application programming interfaces (APIs) to:
v Get, use, and delete an AS/400 system object. Various Client Access APIs
require a system object. It holds information about connecting to, and validating
security (user ID, password, and signon date and time) on, an AS/400 system.
For more information, see “System object attributes” on page 41 and “System
object attributes listing” on page 42.
v Obtain information about environments and connections that are configured in
the system list when you use Client Access Express. The system list is a list of
all currently configured environments, and of systems within those
environments.

Note: It is not necessary for you to explicitly configure new systems to add
them to the system list. They are added automatically when you connect
to a new system.

40 Client Access Express Programming


Express Communications and Security APIs required files:

Header file Import library Dynamic Link


Library
System object APIs System list APIs cwbapi.lib cwbco.dll
cwbcosys.h cwbco.h

Express Toolkit:
The Client Access Express Toolkit provides Communications and Security
documentation, access to the cwbco.h and cwbcosys.h header files, and
links to sample programs. To access this information, open the Express
Toolkit and select Communications and Security —> C/C++ APIs.
Express Communications and Security topics:
v Express Communications and Security system object APIs listing
v Express Communications system list APIs listing
v “Example: Using Express communications APIs” on page 125
v “Express Communications APIs return codes” on page 21
v “Express Security APIs return codes” on page 27
v “Global Client Access return codes” on page 17
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

System object attributes


System object attributes affect the behavior of signing on and communicating with
the AS/400 system that the system object represents.

Most attributes can be changed until a successful signon has occurred (either as the
result of a successful call to “cwbCO_Signon” on page 95 or to “cwbCO_Connect”
on page 54). After the signon has taken place successfully, calling the cwbCO_Set
API to try to change the value of such an attribute will fail with return code
CWB_INV_AFTER_SIGNON. The only attribute that can be changed after a
successful signon is the Window Handle.

Some values and the ability to change them may be controlled via policies. Policies
are controls that a systems administrator can set up to mandate default attribute
values, and to prohibit changes to attributes. The default values that are specified
in the System object attributes listing topic (link below) are used under the
following conditions:
v If policies do not specify or suggest different values
v If a value for such an attribute has not been configured explicitly for the AS/400
system in the system list
If an attribute’s default value may be set by policy, this also is noted. If changing
an attribute’s value can be prohibited by policy, then:
v An API is provided to check for the attribute’s modifiability.
v A specific return code is provided by the attribute’s set method if the set fails
because of such a policy.
To view a listing of system object attributes:
See “System object attributes listing” on page 42

Chapter 3. Express C/C++ APIs 41


System object attributes listing
Following is a list of system object attributes. It includes descriptions,
requirements, and considerations. Also listed with each attribute are:
v The APIs that you can use to get and to set it
v What its default value is when the system object is created

Note: The attributes’ settings apply ONLY to the system object for which they are
set, NOT to any other system objects, even if other system objects have the
same AS/400 system name.
AS/400 system name:
The AS/400 system with which to communicate and use by way of this
instance of a system object. This can be set only at the time
cwbCO_CreateSystem or cwbCO_CreateSystemLike is called. Note that the
system name is used as the unique identifier when validating security
information for a specific user ID: If two different system objects contain
different system names that represent the same physical AS/400 system,
the user ID and password require separate validation for the two system
objects. For example, this applies if the system names ″SYS1″ and
″SYS1.ACME.COM″ represent the same AS/400 system. This may result in
double prompting, and the use of different default user IDs when
connecting.
Get by using cwbCO_GetSystemName
Default:
There is no default, since this is explicitly set when the system
object is created.
User ID:
The user ID used to logon to the AS/400 system.
Get by using cwbCO_GetUserIDEx
Set by using cwbCO_SetUserIDEx
Default:
The first time that you connect to the AS/400 system which is
named in the system object, you may be prompted:
v To specify a default user ID
v To specify that the default user ID should be the same as your
Windows® user ID
v That no default will be used
On subsequent connection attempts, the default user ID that is
used will depend on which option you chose when prompted
during the first connection attempt.
Password:
The password used to signon to the AS/400 system.
Set by using cwbCO_SetPassword
Default:
Blank (no password set) if the user ID that is set in the system
object never has signed on to the AS/400 system that is named in
the system object. If a previous successful signon or connection has
been made to the AS/400 system that is named in the system
object, that password may be used for the next signon or
connection attempt.

42 Client Access Express Programming


Default user mode:
Controls behavior that is associated with the default user ID, including
where to obtain it and whether to use it. If it is not set (if the value is
CWBCO_DEFAULT_USER_MODE_NOT_SET), the user may be prompted
to choose which behavior is desired at the time a signon is attempted.
Get by using cwbCO_GetDefaultUserMode
Set by using cwbCO_SetDefaultUserMode
Check for modify restriction by using cwbCO_CanModifyDefaultUserMode
Default:
CWBCO_DEFAULT_USER_MODE_NOT_SET

Note: The default may be overridden by policies.


Prompt mode:
Controls when Client Access will prompt the user for user ID and
password. See the declaration comments for cwbCO_SetPromptMode for
possible values and for associated behaviors.
Get by using cwbCO_GetPromptMode
Set by using cwbCO_SetPromptMode
Default:
CWBCO_PROMPT_IF_NECESSARY
Window handle:
The window handle of the calling application. If this is set, any prompting
that Client Access does related to AS/400 signon will use the window
handle, and will be modal to the associated window. This means that the
prompt never will be hidden UNDER the main application window if its
handle is associated with the system object. If no window handle is set, the
prompt might be hidden behind the main application window, if one
exists.
Get by using cwbCO_GetWindowHandle
Set by using cwbCO_SetWindowHandle
Default:
NULL (not set)
Validate mode:
Specifies, when validating user ID and password, whether communication
with the AS/400 system to perform this validation actually occurs. See the
declaration comments for cwbCO_SetValidateMode and
cwbCO_GetValidateMode for possible values and for associated behaviors.
Get by using cwbCO_GetValidateMode
Set by using cwbCO_SetValidateMode
Default:
CWBCO_VALIDATE_IF_NECESSARY
Use Secure Sockets:
Specifies whether Client Access will use secure sockets to authenticate the
server (AS/400 system) and to encrypt data that is sent and received.
There are some cases where secure sockets cannot be used (for example,
when the software support for Secure Sockets has not been installed on the
PC). Accordingly, an application or user request for secure sockets use may

Chapter 3. Express C/C++ APIs 43


fail, either at the time the cwbCO_UseSecureSockets API is called, or at
connect time. If no such failure occurs, then secure sockets is being used,
and cwbCO_IsSecureSockets will return CWB_TRUE.
Get by using cwbCO_IsSecureSockets
Set by using cwbCO_UseSecureSockets
Check for modify restriction by using cwbCO_CanModifyUseSecureSockets
Default:
Whatever has been configured for this AS/400 system in the
System List will be used. If no configuration for this AS/400
system exists, or if the configuration specifies to use the Client
Access default, then secure sockets will not be used (CWB_FALSE).

Note: The default may be overridden by policies.


Port lookup mode:
Specifies how to retrieve the remote port for an AS/400 host service. It
specifies whether to look it up locally (on the PC), on the AS/400 system,
or to simply use the default (″standard″) port for the specified service. If
local lookup is selected, the standard TCP/IP method of lookup in the
SERVICES file on the PC is used. If server lookup is specified, a connection
to the AS/400 system server mapper is made to retrieve the port number
by lookup from the AS/400 system service table. If either the local or
server lookup method fails, then connecting to the service will fail. For
more information and for possible values, see the API declaration for
cwbCO_SetPortLookupMode.
Get by using cwbCO_GetPortLookupMode
Set by using cwbCO_SetPortLookupMode
Check for modify restriction by using cwbCO_CanModifyPortLookupMode
Default:
Whatever has been configured for this AS/400 system in the
System List will be used. If no configuration for this AS/400
system exists, the default is CWBCO_PORT_LOOKUP_SERVER.

Note: The default may be overridden by policies.


Persistence mode:
Specifies whether the AS/400 system named in this system object may be
added to the System List (if not already in the list) once a successful call to
cwbCO_Connect has completed. See comments where
cwbCO_SetPersistenceMode is declared for more information and for
possible values.
Get by using cwbCO_GetPersistenceMode
Set by using cwbCO_SetPersistenceMode
Check for modify restriction by using cwbCO_CanModifyPersistenceMode
Default:
CWBCO_MAY_MAKE_PERSISTENT

Note: The default may be overridden by policies.

44 Client Access Express Programming


Express Communications and Security system object APIs
listing
The following Communications and Security system object APIs are listed
alphabetically, by function:

Function Communications and Security system object APIs


Create and delete a system cwbCO_CreateSystem
object cwbCO_CreateSystemLike
cwbCO_DeleteSystem
Connect to and disconnect cwbCO_Connect
from the AS/400 system, and cwbCO_Verify
for related behavior cwbCO_Disconnect
cwbCO_IsConnected
cwbCO_SetPersistenceMode
cwbCO_GetPersistenceMode
Security validation and data cwbCO_SetUserIDEx
cwbCO_GetUserIDEx
cwbCO_SetPassword
cwbCO_SetValidateMode
cwbCO_GetValidateMode
cwbCO_SetDefaultUserMode
cwbCO_GetDefaultUserMode
cwbCO_SetPromptMode
cwbCO_GetPromptMode
cwbCO_GetWindowHandle
cwbCO_SetWindowHandle
cwbCO_Signon
cwbCO_HasSignedOn
cwbCO_VerifyUserIDPassword
cwbCO_GetSignonDate
cwbCO_GetPrevSignonDate
cwbCO_GetPasswordExpireDate
cwbCO_GetFailedSignons
cwbCO_ChangePassword
Get and set other system object cwbCO_GetSystemName
attributes, or determine if they cwbCO_UseSecureSockets
can be set (if they are restricted cwbCO_IsSecureSockets
by policies) cwbCO_SetPortLookupMode
cwbCO_GetPortLookupMode
cwbCO_SetIPAddressLookupMode
cwbCO_GetIPAddressLookupMode
cwbCO_SetIPAddress
cwbCO_GetIPAddress
cwbCO_CanModifyDefaultUserMode
cwbCO_CanModifyIPAddressLookupMode
cwbCO_CanModifyIPAddress
cwbCO_CanModifyPortLookupMode
cwbCO_CanModifyPersistenceMode
cwbCO_CanModifyUseSecureSockets
cwbCO_GetHostCCSID
cwbCO_GetHostVersionEx

Chapter 3. Express C/C++ APIs 45


cwbCO_CanModifyDefaultUserMode
Purpose: Indicates whether the default user mode for the specified system object
may be modified.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyDefaultUserMode(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if this mode may be modified, otherwise set to
CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection that is using the specified system object
already has occurred. In these cases, canModify will be set to CWB_FALSE. The
results returned from this API are correct only at the time of the call.

If policy settings are changed or a signon or connection is performed using this


system object, the results of this API could become incorrect. This must be
considered and managed, especially in a multi-threaded application.

46 Client Access Express Programming


cwbCO_CanModifyIPAddress
Purpose: Indicates whether IP Address that is used to connect may be modified
for this system object.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyIPAddress(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if the IP Address may be modified, otherwise set to
CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection by using the specified system object already
has occurred. In these cases, canModify will be set to CWB_FALSE. This value may
not be modified if the IP Address Lookup Mode is not
CWBCO_IPADDR_LOOKUP_NEVER, and policy settings prohibit modification of
the IP Address Lookup Mode. In that case, canModify will be set to CWB_FALSE.
The results returned from this API are correct only at the time of the call. If policy
settings are changed or a signon or connection is performed using this system
object, the results of this API could become incorrect. This must be considered and
managed, especially in a multi-threaded application.

Chapter 3. Express C/C++ APIs 47


cwbCO_CanModifyIPAddressLookupMode
Purpose: Indicates whether the IP Address Lookup Mode may be modified for
this system object.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyIPAddressLookupMode(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if this mode may be modified, otherwise set to
CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection using the specified system object already
has occurred. In these cases, canModify will be set to CWB_FALSE. The results
returned from this API are correct only at the time of the call.

If policy settings are changed or a signon or connection is performed using this


system object, the results of this API could become incorrect. This must be
considered and managed, especially in a multi-threaded application.

48 Client Access Express Programming


cwbCO_CanModifyPersistenceMode
Purpose: Indicates whether persistence mode for the specified system object may
be modified.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyPersistenceMode(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if this mode may be modified, otherwise set to
CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection by using the specified system object has
already occurred. In these cases, canModify will be set to CWB_FALSE. The results
returned from this API are correct only at the time of the call. If policy settings are
changed or a signon or connection is performed using this system object, the
results of this API could become incorrect. This must be considered and managed,
especially in a multi-threaded application.

Chapter 3. Express C/C++ APIs 49


cwbCO_CanModifyPortLookupMode
Purpose: Indicates whether the port lookup mode for the specified system object
may be modified.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyPortLookupMode(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if this mode may be modified, otherwise set to
CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection by using the specified system object already
has occurred. In these cases, canModify will be set to CWB_FALSE. The results
returned from this API are correct only at the time of the call. If policy settings are
changed or a signon or connection is performed using this system object, the
results of this API could become incorrect. This must be considered and managed,
especially in a multi-threaded application.

50 Client Access Express Programming


cwbCO_CanModifyUseSecureSockets
Purpose: Indicates whether the secure sockets use setting may be modified for
this system object.

Syntax:

UINT CWB_ENTRY cwbCO_CanModifyUseSecureSockets(


cwbCO_SysHandle system,
cwb_Boolean *canModify );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean *canModify - output
Set to CWB_TRUE if the secure sockets use setting may be modified, otherwise
set to CWB_FALSE.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The canModify pointer is NULL.

Usage: This value may not be modified if policy settings prohibit its modification,
or if a successful signon or connection using the specified system object has
already occurred. In these cases, canModify will be set to CWB_FALSE. The results
returned from this API are correct only at the time of the call. If policy settings are
changed or a signon or connection is performed using this system object, the
results of this API could become incorrect. This must be considered and managed,
especially in a multi-threaded application.

Chapter 3. Express C/C++ APIs 51


cwbCO_ChangePassword
Purpose: Changes the password of the specified user on the AS/400 system from
a specified old to a specified new value. This API does NOT use the user ID and
password that currently are set in the given system object, nor does it change these
values.

Syntax:

UINT CWB_ENTRY cwbCO_ChangePassword(


cwbCO_SysHandle system,
LPCSTR userID,
LPCSTR oldPassword,
LPCSTR newPassword,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPCSTR userID - input
A pointer to an ASCIIZ string that contains the user ID. The maximum length
is CWBCO_MAX_USER_ID + 1 characters, including the null terminator.
LPCSTR oldPassword - input
A pointer to an ASCIIZ string that contains the old password. The maximum
length is CWBCO_MAX_PASSWORD + 1 characters, including the null
terminator.
LPCSTR newPassword - input
A pointer to an ASCIIZ string that contains the new password. The maximum
length is CWBCO_MAX_PASSWORD + 1 characters, including the null
terminator.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
A pointer parameter is NULL.
CWB_GENERAL_SECURITY_ERROR
A general security error occurred. The user profile does not have a
password or the password validation program found an error in the
password.
CWB_INVALID_PASSWORD
One or more characters in the new password is invalid or the password is
too long.

52 Client Access Express Programming


CWB_INVALID_USERID
One or more characters in the user ID is invalid or the user ID is too long.
CWB_UNKNOWN_USERID
The supplied user ID is not known to this system.
CWB_WRONG_PASSWORD
Password is not correct.
CWB_USER_PROFILE_DISABLED
The user ID has been disabled.
CWB_PW_TOO_LONG
New password longer than maximum accepted length.
CWB_PW_TOO_SHORT
New password shorter than minimum accepted length.
CWB_PW_REPEAT_CHARACTER
New password contains a character used more than once.
CWB_PW_ADJACENT_DIGITS
New password has adjacent digits.
CWB_PW_CONSECUTIVE_CHARS
New password contains a character repeated consecutively.
CWB_PW_PREVIOUSLY_USED
New password was previously used.
CWB_PW_DISALLOWED_CHAR
New password uses an installation-disallowed character.
CWB_PW_NEED_NUMERIC
New password must contain at least one numeric.
CWB_PW_MATCHES_OLD
New password matches old password in one or more character positions.
CWB_PW_NOT_ALLOWED
New password exists in a dictionary of disallowed passwords.
CWB_PW_CONTAINS_USERID
New password contains user ID as part of the password.
CWB_PW_LAST_INVALID_PWD
The next invalid password will disable the user profile.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: None.

Chapter 3. Express C/C++ APIs 53


cwbCO_Connect
Purpose: Connect to the specified AS/400 host service.

Syntax:

UINT CWB_ENTRY cwbCO_Connect(


cwbCO_SysHandle system,
cwbCO_Service service,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system to connect to.
cwbCO_Service service - input
The service to connect to on the AS/400 system. Valid values are those listed in
“Defines for cwbCO_Service” on page 101, except for the values
CWBCO_SERVICE_ANY and CWBCO_SERVICE_ALL. Only one service may
be specified for this API, unlike for cwbCO_Disconnect, which can disconnect
multiple services at once.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_SERVICE_NAME_ERROR
The service identifier is not a valid value, or was a combination of values
(only a single value is allowed for this API).
CWB_CONNECTION_TIMED_OUT
It took too long to find the AS/400 system, so the attempt timed out.
CWB_CONNECTION_REFUSED
The AS/400 system refused to accept our connection attempt.
CWB_NETWORK_IS_DOWN
A network error occurred, or TCP/IP is not configured correctly on the PC.
CWB_NETWORK_IS_UNREACHABLE
The network segment to which the AS/400 system is connected currently
is not reachable from the segment to which the PC is connected.

Note: Other return codes may be commonly returned as the result of a failed
security validation attempt. See the list of common return codes in the
comments for cwbCO_Signon.

Usage: If signon to the AS/400 system has not yet occurred, the signon will be
performed first when cwbCO_Connect is called. If you want the signon to occur at
a separate time, call cwbCO_Signon first, then call cwbCO_Connect at a later time.

54 Client Access Express Programming


For more information about signon and its behavior, see comments for
cwbCO_Signon. If the signon attempt fails, a connection to the specified service
will not be established.

If the AS/400 system as named in the specified system object does not exist in the
System List, and the system object Persistence Mode is set appropriately, then
when cwbCO_Connect or cwbCO_Signon is first successfully called, the AS/400
system, as named in the system object, will be added to the System List. For more
information about the Persistence Mode, see the comments for
cwbCO_SetPersistenceMode.

If a connection to the specified service already exists, no new connection will be


established, and CWB_OK will be returned. Each time this API is successfully
called, the usage count for the connection to the specified service will be
incremented.

Each time cwbCO_Disconnect is called for the same service, the usage count will
be decremented. When the usage count reaches zero, the actual connection is
ended.

Therefore, it is VERY IMPORTANT that for every call to the cwbCO_Connect API
there is a later paired call to the cwbCO_Disconnect API, so that the connection
can be ended at the appropriate time. The alternative is to call the
cwbCO_Disconnect API, specifying CWBCO_SERVICE_ALL, which will disconnect
all existing connections to ALL services madethrough the specified system object,
and reset all usage counts to 0.

Chapter 3. Express C/C++ APIs 55


cwbCO_CreateSystem
Purpose: Create a new system object and return a handle to it that can be used
with subsequent calls. The system object has many attributes that can be set or
retrieved. See“System object attributes” on page 41 for more information.

Syntax:

UINT CWB_ENTRY cwbCO_CreateSystem(


LPCSTR systemName,
cwbCO_SysHandle *system);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the NULL-terminated name of the AS/400
system. This can be its host name, or the AS/400 system’s dotted-decimal IP
address itself. It must not be zero length and must not contain blanks. If the
name specified is not a valid AS/400 system host name or IP address string (in
the form ″nnn.nnn.nnn.nnn″), any connection attempt or security validation
attempt will fail.
cwbCO_SysHandle *system - output
The system object handle is returned in this parameter.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_POINTER
One of the pointer parameters is NULL.
CWB_INVALID_SYSNAME
The system name is not valid.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from creating a system object for a
system not already defined in the System List.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage that is being used.

Usage: When you are done using the system object, you must call
cwbCO_DeleteSystem to free resources the system object is using. If you want to
create a system object that is like one you already have, use
cwbCO_CreateSystemLike.

56 Client Access Express Programming


cwbCO_CreateSystemLike
Purpose: Create a new system object that is similar to a given system object. You
may either provide a specific system name for the new system object, or specify
NULL to use the given system object’s name. All attributes of the given system
object are copied into the new one, with the following exceptions:
v User ID
v Password
v System name, if a different one is specified
v IP address, when the system names are different.
See “System object attributes listing” on page 42 for a list of system object
attributes.

Syntax:

UINT CWB_ENTRY cwbCO_CreateSystemLike(


cwbCO_SysHandle systemToCopy,
LPCSTR systemName
cwbCO_SysHandle *system);

Parameters:
cwbCO_SysHandle systemToCopy - input
Handle that was returned by a previous call to either cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system. This is the object
that will be ″copied.″
LPCSTR systemName - input
Pointer to a buffer that contains the NULL-terminated name of the AS/400
system to use in the new system object. If NULL or the empty string is passed,
the name from the given system object is copied into the new system object. If
a system name is specified, it can be the host name, or the AS/400 system’s
dotted-decimal IP address. If the name that is specified is not a valid AS/400
system host name or IP address string (in the form ″nnn.nnn.nnn.nnn″), any
connection attempt or security validation attempt will fail.
cwbCO_SysHandle *newSystem - output
The system object handle of the new system object is returned in this
parameter.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
A pointer that is supplied to the API is not valid.
CWB_INVALID_SYSNAME
The system name is not valid.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from creating a system object for a
system not already defined in the System List.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage that is being used.

Chapter 3. Express C/C++ APIs 57


Usage: When you are done using the new system object, you must call
cwbCO_DeleteSystem to free resources that the system object is using.

The state of the new system object might not be the same as that of the given
system object, since user ID and password validation has not been performed yet
for the new one. Also, the new system object has no connections associated with it,
whereas the given system object may. Because of this, even though you might not
be able to change attributes of the given system object because of its state, you
might be able to change the attributes of the new system object because of its
possibly different state.

58 Client Access Express Programming


cwbCO_DeleteSystem
Purpose: Deletes the system object that is specified by its handle, and frees all
resources the system object has used.

Syntax:

UINT CWB_ENTRY cwbCO_DeleteSystem(


cwbCO_SysHandle system);

Parameters:
cwbCO_SysHandle system - input
Handle that was returned by a previous call to either cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.

Usage: Before the system object resources are freed, if there are any connections
that were made using the specified system object, they will be ended, forcefully if
necessary. To determine if there are active connections, call cwbCO_IsConnected. If
you want to know whether disconnecting any existing connections was successful,
call cwbCO_Disconnect explicitly before calling this API.

Chapter 3. Express C/C++ APIs 59


cwbCO_Disconnect
Purpose: Disconnect from the specified AS/400 host service.

Syntax:

UINT CWB_ENTRY cwbCO_Disconnect(


cwbCO_SysHandle system,
cwbCO_Service service,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle system - input
Handle that was returned by a previous call to either cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system from which to
disconnect.
cwbCO_Service service - input
The service from which to disconnect on the AS/400 system. Valid values are
those listed at the start of this file, except for the value
CWBCO_SERVICE_ANY. If CWBCO_SERVICE_ALL is specified, the
connections to ALL connected services will be ended, and all connection usage
counts reset back to zero.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_SERVICE_NAME_ERROR
The service identifier is invalid.
CWB_NOT_CONNECTED
The single service was not connected.

Usage: This function should be called when a connection that is established by


using cwbCO_Connect no longer is needed.

If any service specified cannot be disconnected, the return code will indicate this
error. If more than one error occurs, only the first one will be returned as the API
return code.
Usage Notes for individual service disconnect:
This function will cause the usage count for this system object’s specified
service to be decremented, and may or may not end the actual connection.
For more information, read the Usage Notes for the cwbCO_Connect API.
Disconnecting a service that is not currently connected results in
CWB_NOT_CONNECTED.
An individual service is gracefully disconnected.

60 Client Access Express Programming


Usage Notes for CWBCO_SERVICE_ALL:
The return code CWB_NOT_CONNECTED is not returned when
CWBCO_SERVICE_ALL is specified, regardless of the number of connected
services.
Requesting that all active services be disconnected may generate messages
on the AS/400.

Chapter 3. Express C/C++ APIs 61


cwbCO_GetDefaultUserMode
Purpose: This function gets, for the specified system object, the default user mode
that currently is set.

Syntax:

UINT CWB_ENTRY cwbCO_GetDefaultUserMode(


cwbCO_SysHandle system,
cwbCO_DefaultUserMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_DefaultUserMode * mode - output
Returns the default user mode for this system object. See comments for
cwbCO_SetDefaultUserMode for the list of possible values and their meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

62 Client Access Express Programming


cwbCO_GetFailedSignons
Purpose: Retrieves the number of unsuccessful security validation attempts since
the last successful attempt.

Syntax:

UINT CWB_ENTRY cwbCO_GetFailedSignons(


cwbCO_SysHandle system,
PUSHORT numberFailedAttempts);

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
PUSHORT numberFailedAttempts - output
A pointer to a short that will contain the number of failed logon attempts if
this call is successful.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The numberFailedAttempts pointer is NULL.
CWB_INV_BEFORE_VALIDATE
The user ID and password that were set in the specified system object have
not been validated yet, so this information is not available.

Usage: You successfully must have called cwbCO_VerifyUserIDPassword,


cwbCO_Signon, or cwbCO_Connect before using this API. If you want to ensure
that the value that is returned is recent, you either must call
cwbCO_VerifyUserIDPassword explicitly, or set the Validate Mode to
CWBCO_VALIDATE_ALWAYS before you call cwbCO_Signon or cwbCO_Connect.

Chapter 3. Express C/C++ APIs 63


cwbCO_GetHostCCSID
Purpose: Returns the associated CCSID of the AS/400 system that is represented
by the given system object that was in use when the signon to the AS/400 system
occurred, and that is associated with the user ID that is set in the sytem object.

Syntax:

UINT CWB_ENTRY cwbCO_GetHostCCSID(


cwbCO_SysHandle system,
PULONG pCCSID );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
PULONG pCCSID - output
The host CCSID is copied into here if successful.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
the CCSID pointer is NULL.
CWB_DEFAULT_HOST_CCSID_USED
Host CCSID 500 is returned because this API is unable to determine the
host CCSID appropriate for the user ID as set in the system object.

Usage: This API does not make or require an active connection to the host system
to retrieve the associated CCSID value.However, it does depend on a prior
successful connection to the host system by using the same user ID as is set in the
specified system object. This is because the CCSID that is returned is the one from
the specific user profile, NOT the AS/400 system’s default CCSID. To retrieve a
host CCSID without requiring a user ID, call cwbNL_GetHostCCSID.

64 Client Access Express Programming


cwbCO_GetHostVersionEx
Purpose: Get the version and release level of the host.

Syntax:

UINT CWB_ENTRY cwbCO_GetHostVersionEx(


cwbCO_SysHandle system,
PULONG version,
PULONG release);

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
PULONG version - output
Pointer to a buffer where the version level of the system is returned.
PULONG release - output
Pointer to a buffer where the release level of the system is returned.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWB_NOT_CONNECTED
The system has never been connected to when using the currently active
environment.
CWB_INVALID_POINTER
One of the pointers passed in is NULL.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate a temporary buffer.

Usage: The host version is retrieved and saved whenever a connection is made to
the AS/400 system. If no connection has been made yet to this AS/400 system in
the currently-active environment, this information will not be available, and the
error code CWB_NOT_CONNECTED will be returned. If you know that a
connection to the AS/400 system recently was made successfully, it is likely that
the version and release levels returned are current. If you want to make sure that
the values are available and recently have been retrieved, call cwbCO_Signon or
cwbCO_Connect for this system object first, then call cwbCO_GetHostVersionEx.

Chapter 3. Express C/C++ APIs 65


cwbCO_GetIPAddress
Purpose: This function gets, for the specified system object, the IP address of the
AS/400 system it represents. This is the IP address that was used to connect to the
AS/400 system (or was set some other way, such as by using
cwbCO_SetIPAddress), and will be used for later connections, when using the
specified system object.

Syntax:

UINT CWB_ENTRY cwbCO_GetIPAddress(


cwbCO_SysHandle system,
LPSTR IPAddress,
PULONG length );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned by cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPSTR IPAddress - output
Pointer to a buffer that will contain the NULL-terminated IP address in
dotted-decimal notation (in the form ″nnn.nnn.nnn.nnn″ where each ″nnn″ is in
the range of from 0 to 255).
PULONG length - input/output
Pointer to the length of the IPAddress buffer. If the buffer is too small to hold
the output, including room for the terminating NULL, the size of the buffer
needed will be filled into this parameter and CWB_BUFFER_OVERFLOW will
be returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
One of the input pointers is NULL.
CWB_BUFFER_OVERFLOW
The IPAddress buffer is not large enough to hold the entire IPAddress
string.

Usage: None.

66 Client Access Express Programming


cwbCO_GetIPAddressLookupMode
Purpose: This function gets, for the specified system object, the indication of
when, if ever, the AS/400 system’s IP address will be looked up dynamically.

Syntax:

UINT CWB_ENTRY cwbCO_GetIPAddressLookupMode(


cwbCO_SysHandle system,
cwbCO_IPAddressLookupMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned by cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_IPAddressLookupMode * mode - output
Returns the IP address lookup mode that currently is in use. See comments for
“cwbCO_SetIPAddressLookupMode” on page 84 for possible values and their
meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

Chapter 3. Express C/C++ APIs 67


cwbCO_GetPasswordExpireDate
Purpose: Retrieves the date and time the password will expire for the user ID that
is set in the given system object on the AS/400 system that it represents.

Syntax:

UINT CWB_ENTRY cwbCO_GetPasswordExpireDate(


cwbCO_SysHandle system,
cwb_DateTime *expirationDateTime);

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_DateTime * expirationDateTime - output
A pointer to a structure that contains the date and time at which the password
will expire for the current user ID, in the following format:

Bytes Content
1-2 Year (Example: 1998 = 0x07CF)
3 Month (January = 0x01)
4 Day (First day = 0x01;31st day = 0x1F)
5 Hour (Midnight = 0x00;23rd hour = 0x17)
6 Minute (On the hour = 0x00; 59th minute = 0x3B)
7 Second (On the minute = 0x00; 59th second = 0x3B)
8 One-hundredth of a second (on the second = 0x00; maximum = 0x63)

Note: On a given day, the maximum time is 23 hours, 59 minutes, and 59.99
seconds. Midnight is 0 hours, 0 minutes, and 0.0 seconds on the
following day.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The pointer to the cwb_DateTime structure is NULL.
CWB_INV_BEFORE_VALIDATE
The user ID and password that were set in the specified system object have
not been validated yet, so this information is not available.

Usage: You successfully must have called cwbCO_VerifyUserIDPassword,


cwbCO_Signon, or cwbCO_Connect before using this API. If you want to ensure
that the value that is returned is recent, you either must call
cwbCO_VerifyUserIDPassword explicitly, or set the Validate Mode to
CWBCO_VALIDATE_ALWAYS before you call cwbCO_Signon or cwbCO_Connect.

68 Client Access Express Programming


cwbCO_GetPersistenceMode
Purpose: This function gets, for the specified system object, if the system it
represents, along with its attributes, will be added to the System List (if not
already in the list) once a successful signon has occurred.

Syntax:

UINT CWB_ENTRY cwbCO_GetPersistenceMode(


cwbCO_SysHandle system,
cwbCO_PersistenceMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PersistenceMode * mode - output
Returns the persistence mode. See comments for cwbCO_SetPersistenceMode
for possible values and their meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

Chapter 3. Express C/C++ APIs 69


cwbCO_GetPortLookupMode
Purpose: This function gets, for the specified system object, the mode or method
by which host service ports are looked up when they are needed by Client Access
to establish a service connection.

Syntax:

UINT CWB_ENTRY cwbCO_GetPortLookupMode(


cwbCO_SysHandle system,
cwbCO_PortLookupMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned by cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PortLookupMode * mode - output
Returns the host service port lookup mode. See comments for
cwbCO_SetPortLookupMode for possible values and their meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

70 Client Access Express Programming


cwbCO_GetPrevSignonDate
Purpose: Retrieves the date and time of the previous successful security
validation.

Syntax:

UINT CWB_ENTRY cwbCO_GetPrevSignonDate(


cwbCO_SysHandle system,
cwb_DateTime *signonDateTime);

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem
orcwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_DateTime * signonDateTime - output
A pointer to a structure that contains the date and time at which the previous
signon occurred, in the following format:

Bytes Content
1-2 Year (Example: 1998 = 0x07CF)
3 Month (January = 0x01)
4 Day (First day = 0x01;31st day = 0x1F)
5 Hour (Midnight = 0x00;23rd hour = 0x17)
6 Minute (On the hour = 0x00; 59th minute = 0x3B)
7 Second (On the minute = 0x00; 59th second = 0x3B)
8 One-hundredth of a second (on the second = 0x00; maximum = 0x63)

Note: On a given day, the maximum time is 23 hours, 59 minutes, and 59.99
seconds. Midnight is 0 hours, 0 minutes, and 0.0 seconds on the
following day.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The pointer to the cwb_DateTime structure is NULL.
CWB_INV_BEFORE_VALIDATE
The user ID and password that were set in the specified system object have
not been validated yet, so this information is not available.

Usage: You successfully must have called cwbCO_VerifyUserIDPassword,


cwbCO_Signon, or cwbCO_Connect before using this API. If you want to ensure
that the value that is returned is recent, you either must call
cwbCO_VerifyUserIDPassword explicitly, or set the Validate Mode to
CWBCO_VALIDATE_ALWAYS before you call cwbCO_Signon or cwbCO_Connect.

Chapter 3. Express C/C++ APIs 71


cwbCO_GetPromptMode
Purpose: This function gets, for the specified system object, the prompt mode that
currently is set.

Syntax:

UINT CWB_ENTRY cwbCO_GetPromptMode(


cwbCO_SysHandle system,
cwbCO_PromptMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PromptMode * mode - output
Returns the prompt mode. See comments for cwbCO_SetPromptMode for
possible values and their meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

72 Client Access Express Programming


cwbCO_GetSignonDate
Purpose: Retrieves the date and time of the current successful security validation.

Syntax:

UINT CWB_ENTRY cwbCO_GetSignonDate(


cwbCO_SysHandle system,
cwb_DateTime *signonDateTime);

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_DateTime * signonDateTime - output
A pointer to a structure that will contain the date and time at which the
current signon occurred, in the following format:

Bytes Content
1-2 Year (Example: 1998 = 0x07CF)
3 Month (January = 0x01)
4 Day (First day = 0x01;31st day = 0x1F)
5 Hour (Midnight = 0x00;23rd hour = 0x17)
6 Minute (On the hour = 0x00; 59th minute = 0x3B)
7 Second (On the minute = 0x00; 59th second = 0x3B)
8 One-hundredth of a second (on the second = 0x00; maximum = 0x63)

Note: On a given day, the maximum time is 23 hours, 59 minutes, and 59.99
seconds. Midnight is 0 hours, 0 minutes, and 0.0 seconds on the
following day.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The pointer to the cwb_DateTime structure is NULL.
CWB_INV_BEFORE_VALIDATE
The user ID and password set in the specified system object have not been
validated yet, so this information is not available.

Usage: You successfully must have called cwbCO_VerifyUserIDPassword,


cwbCO_Signon, or cwbCO_Connect before using this API. If you want to ensure
that the value returned is recent, you must either call
cwbCO_VerifyUserIDPassword explicitly, or set the Validate Mode to
CWBCO_VALIDATE_ALWAYS before you call cwbCO_Signon or cwbCO_Connect.

Chapter 3. Express C/C++ APIs 73


cwbCO_GetSystemName
Purpose: This function gets the AS/400 system name that is associated with the
specified system object.

Syntax:

UINT CWB_ENTRY cwbCO_GetSystemName(


cwbCO_SysHandle system,
LPSTR sysName,
PULONG length );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPSTR sysName - output
Pointer to a buffer that will contain the NULL-terminated system name. The
name will be CWBCO_MAX_SYS_NAME characters long at most, not
including the terminating NULL.
PULONG length - input/output
Pointer to the length of the sysName buffer. If the buffer is too small to hold
the system name, including room for the terminating NULL, the size of the
buffer needed will be filled into this parameter and
CWB_BUFFER_OVERFLOW will be returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
One of the pointer parameters passed in is NULL.
CWB_BUFFER_OVERFLOW
The sysName buffer is not large enough to hold the entire system name.

Usage: None.

74 Client Access Express Programming


cwbCO_GetUserIDEx
Purpose: This function gets the current user ID that is associated with a specified
system object. This is the user ID that is being used for connections to the AS/400.

Syntax:

UINT CWB_ENTRY cwbCO_GetUserIDEx(


cwbCO_SysHandle system,
LPSTR userID,
PULONG length );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPSTR userID - output
Pointer to a buffer that will contain the NULL-terminated user ID. The user ID
will be at most CWBCO_MAX_USER_ID characters long.
PULONG length - input/output
Pointer to the length of the userID buffer. If the buffer is too small to hold the
user ID, including space for the terminating NULL, the size of the buffer
needed will be filled into this parameter.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
One of the pointer parameters passed in is NULL.
CWB_BUFFER_OVERFLOW
The userID buffer is not large enough to hold the entire user ID name.

Usage: The user ID may or may not have been validated on the AS/400 system
yet. To make sure it has been, call cwbCO_Signon or cwbCO_Connect before
calling this API.

If no user ID has been set and a signon has not occurred for the system object, the
returned user ID will be the empty string, even if a default user ID has been
configured for the AS/400 system.

Chapter 3. Express C/C++ APIs 75


cwbCO_GetValidateMode
Purpose: This function gets, for the specified system object, the validate mode
currently set.

Syntax:

UINT CWB_ENTRY cwbCO_GetValidateMode(


cwbCO_SysHandle system,
cwbCO_ValidateMode *mode );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_ValidateMode * mode - output
Returns the validate mode. See comments for cwbCO_SetValidateMode for
possible values and their meanings.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The mode pointer is NULL.

Usage: None.

76 Client Access Express Programming


cwbCO_GetWindowHandle
Purpose: This function gets, for the specified system object, the window handle, if
any, that currently is associated with it.

Syntax:

UINT CWB_ENTRY cwbCO_GetWindowHandle(


cwbCO_SysHandle system,
HWND *windowHandle );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
HWND * pWindowHandle - output
Returns the window handle associated with the system object, or NULL if no
window handle is associated with it.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The windowHandle pointer is NULL.

Usage: None.

Chapter 3. Express C/C++ APIs 77


cwbCO_HasSignedOn
Purpose: Returns an indication of whether the specified system object has ″signed
on″ (whether the user ID and password have been validated at some point in the
life of the specified system object).

Syntax:

UINT CWB_ENTRY cwbCO_HasSignedOn(


cwbCO_SysHandle system,
cwb_Boolean *signedOn );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean * signedOn - output
A pointer to a cwb_Boolean into which is stored the indication of
″signed-on-ness.″ If the specified system object has signed on, it will be set to
CWB_TRUE, otherwise it will be set to CWB_FALSE. (On error it will be set to
CWB_FALSE as well.)

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The signedOn pointer is NULL.

Usage: A returned indication of CWB_TRUE does not mean that the user ID and
password have been validated within a certain time period, but only that since the
system object’s creation, a signon has occurred. That signon may not have caused
or included a connection and security validation flow to the AS/400 system. This
means that, even if CWB_TRUE is returned, the next call to the system object that
requires a successful signon might connect and attempt to re-validate the user ID
and password, and that validation, and hence the signon, may fail. The signedOn
indicator reflects the results of the most-recent user ID and password validation. If
user ID and password validation (signon) has occurred successfully at one time,
but since then this validation has failed, signedOn will be set to CWB_FALSE.

78 Client Access Express Programming


cwbCO_IsConnected
Purpose: Find out if any, and how many, connections to the AS/400 system that
are using the specified system object currently exist.

Syntax:

UINT CWB_ENTRY cwbCO_IsConnected(


cwbCO_SysHandle system,
cwbCO_Service service,
PULONG numberOfConnections );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_Service service - input
The service to check for a connection. Any of the cwbCO_Service values listed
in “Defines for cwbCO_Service” on page 101 are valid. To find out if ANY
service is connected, specify CWBCO_SERVICE_ANY. To find out how many
services are connected using this system object, specify
CWBCO_SERVICE_ALL.
PULONG numberOfConnections - output
Used to return the number of connections active for the service(s) that are
specified. If the service specified is not CWBCO_SERVICE_ALL, the value
returned will be either 0 or 1, since there can be at most one active connection
per service per system object. If CWBCO_SERVICE_ALL is specified, this could
be from zero to the possible number of services, since one connection per
service might be active.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion, all services specified are connected, or if
CWBCO_SERVICE_ANY is specified, at least one service is connected.
CWB_NOT_CONNECTED
If a single service was specified, that service is not connected. If the value
CWBCO_SERVICE_ANY was specified, there are NO active connections. If
the value CWBCO_SERVICE_ALL was specified, there is at least one
service that is NOT connected.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_SERVICE_NAME_ERROR
The service identifier is invalid.
CWB_INVALID_POINTER
The numberOfConnections parameter is NULL.

Usage: If CWBCO_SERVICE_ALL was specified and CWB_NOT_CONNECTED is


returned, there may be some active connections, and the count of active
connections still will be passed back. To find out how many connections through
the specified system object exist, call this API and specify CWBCO_SERVICE_ALL.
If the return code is either CWB_OK or CWB_NOT_CONNECTED, the number of
connections that exist is stored in numberOfConnections.

Chapter 3. Express C/C++ APIs 79


cwbCO_IsSecureSockets
Purpose: This function gets (for the specified system object) whether Secure
Sockets is being used (if connected), or would be attempted (if not currently
connected) for a connection.

Syntax:

UINT CWB_ENTRY cwbCO_IsSecureSockets(


cwbCO_SysHandle system,
cwb_Boolean *inUse );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean * inUse - output
Returns whether Client Access is using, or will try to use, secure sockets for
communication:
CWB_TRUE
IS in use or would be if connections active.
CWB_FALSE
NOT in use, would not try to use it.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The inUse pointer is NULL.

Usage: This flag is an indication of what Client Access will TRY to do for any
future communications. If CWB_TRUE is returned, then any attempt to
communicate to the AS/400 system that cannot be performed using secure sockets
will fail.

80 Client Access Express Programming


cwbCO_SetDefaultUserMode
Purpose: This function sets, for the specified system object, the behavior with
respect to any configured default user ID.

Syntax:

UINT CWB_ENTRY cwbCO_SetDefaultUserMode(


cwbCO_SysHandle system,
cwbCO_DefaultUserMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_DefaultUserMode mode - input
Specifies what will be done with the default user ID. Possible values are:
CWBCO_DEFAULT_USER_MODE_NOT_SET
No default user mode is currently in use. When this mode is active,
and the Prompt Mode setting does not prohibit prompting, the user
will be prompted at signon or connect time to select which of the
remaining default user modes should be used from then on. The
signon or connect cannot succeed until one of these other mode values
is selected. Setting the Default User Mode back to this value will cause
the prompt to appear the next time a default user ID is needed by
Client Access.
CWBCO_DEFAULT_USER_USE
When no user ID has explicitly been set (by using
cwbCO_SetUserIDEx) and a signon is to occur, use the default user ID
that is configured for the AS/400 system as named in the system
object.
CWBCO_DEFAULT_USER_IGNORE
Specifies never to use a default user ID. When a signon takes place and
no user ID has explicitly been set for this system object instance, the
user will be prompted to enter a user ID if the Prompt Mode allows it
(see cwbCO_SetPromptMode comments), and no initial value for the
user ID will be filled in in the prompt.
CWBCO_DEFAULT_USER_USEWINLOGON
The user ID that is used when logging on to Windows will be used as
the default if no user ID explicitly has been set for this system object
(by using cwbCO_SetUserIDEx).

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.

Chapter 3. Express C/C++ APIs 81


CWB_INV_AFTER_SIGNON
Signon successfully has occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object. The default
user mode set with this API will be ignored if a user ID has been set explicitly
with the cwbCO_SetUserIDEx API.

82 Client Access Express Programming


cwbCO_SetIPAddress
Purpose: This function sets, for the specified system object, the IP address that
will be used to connect to the AS/400 system. It also changes the IP Address
Lookup Mode for the system object to CWBCO_IPADDR_LOOKUP_NEVER. These
changes will NOT affect any other system object that exists or is created later.

Syntax:

UINT CWB_ENTRY cwbCO_SetIPAddress(


cwbCO_SysHandle system,
LPCSTR IPAddress );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPCSTR IPAddress - input
Specifies the IP address as a character string, in dotted-decimal notation
(″nnn.nnn.nnn.nnn″), where each ″nnn″ is a decimal value ranging from 0 to
255. The IPAddress must not be longer than CWBCO_MAX_IP_ADDRESS
characters, not including the terminating NULL character.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The IPAddress parameter does not contain a valid IP address.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon has successfully occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object.

Use this API to force use of a specific IP address whenever any connection is made
using the specified system object. Since the IP Address Lookup Mode is set to
NEVER lookup the IP address, the address specified always will be used, unless
before a connect or signon occurs, the IP Address Lookup Mode is changed by
calling cwbCO_SetIPAddressLookupMode.

Chapter 3. Express C/C++ APIs 83


cwbCO_SetIPAddressLookupMode
Purpose: This function sets, for the specified system object, when Client Access
dynamically will lookup the AS/400 system’s IP address when a connection is to
be made. If the system name that is specified when cwbCO_CreateSystem or
cwbCO_CreateSystemLike was called is an actual IP address, this setting is
ignored, because Client Access never needs to lookup the address.

Syntax:

UINT CWB_ENTRY cwbCO_SetIPAddressLookupMode(


cwbCO_SysHandle system,
cwbCO_IPAddressLookupMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_IPAddressLookupMode mode - input
Specifies when the dynamic address lookup can occur. Possible values are:
CWBCO_IPADDR_LOOKUP_ALWAYS
Every time a connection is to occur, dynamically lookup the AS/400
system’s IP address.
CWBCO_IPADDR_LOOKUP_1HOUR
Lookup the IP address dynamically if it has been at least one hour
since the last lookup for this AS/400 system.
CWBCO_IPADDR_LOOKUP_1DAY
Lookup the IP address dynamically if it has been at least one day since
the last lookup for this AS/400 system.
CWBCO_IPADDR_LOOKUP_1WEEK
Lookup the IP address dynamically if it has been at least one week
since the last lookup for this AS/400 system.
CWBCO_IPADDR_LOOKUP_NEVER
Never dynamically lookup the IP address of this AS/400 system,
always use the IP address that was last used for this AS/400 system on
this PC.
CWBCO_IPADDR_LOOKUP_AFTER_STARTUP
Lookup the IP address dynamically if Windows has been re-started
since the last lookup for this AS/400 system.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.

84 Client Access Express Programming


CWB_INV_AFTER_SIGNON
Signon has successfully occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object.

Setting this to a value other than CWB_IPADDR_LOOKUP_ALWAYS could shorten


the time to connect to the AS/400 system, since the dynamic lookup may cause
network traffic and take many seconds to complete. If the dynamic lookup is not
performed, there is a risk that the IP address of the AS/400 system will have
changed and a connection will either fail or will be made to the wrong AS/400
system.

Chapter 3. Express C/C++ APIs 85


cwbCO_SetPassword
Purpose: This function sets the password to associate with the specified system
object. This password will be used when connecting to the AS/400 with either the
cwbCO_Signon or cwbCO_Connect call, and when a user ID has been set with the
cwbCO_SetUserIDEx call.

Syntax:

UINT CWB_ENTRY cwbCO_SetPassword(


cwbCO_SysHandle system,
LPCSTR password );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPCSTR password - input
Pointer to a buffer that contains the NULL-terminated password. The
password must not be longer than CWBCO_MAX_PASSWORD characters, not
including the terminating NULL character.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The password pointer is NULL.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage that is being used.
CWB_INV_AFTER_SIGNON
Signon successfully has occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object. A password set
with this API will not be used unless a corresponding user ID has been set with
cwbCO_SetUserIDEx.

86 Client Access Express Programming


cwbCO_SetPersistenceMode
Purpose: This function sets for the specified system object if the system it
represents (as named in the system object), along with its attributes, may be added
to the System List (if not already in the list) once a signon successfully has
occurred.

Syntax:

UINT CWB_ENTRY cwbCO_SetPersistenceMode(


cwbCO_SysHandle system,
cwbCO_PersistenceMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle returned previously from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PersistenceMode mode - input
Specifies the persistence mode. Possible values are:
CWBCO_MAY_MAKE_PERSISTENT
If the system that is named in the specified system object is not yet in
the System List, add it to the list once a successful signon has
completed. This will make the system, as defined by this system object,
available for selection by this AND other applications running, now or
in the future, on this personal computer (until the system is deleted
from this list).
CWBCO_MAY_NOT_MAKE_PERSISTENT
The system that is named in the specified system object (along with its
attributes) may NOT be added to the System List.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon successfully has occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object.

If the system as named in the system object already is in the System List, this
setting has no effect.

Chapter 3. Express C/C++ APIs 87


cwbCO_SetPortLookupMode
Purpose: This function sets, for the specified system object, how a host server port
lookup will be done.

Syntax:

UINT CWB_ENTRY cwbCO_SetPortLookupMode(


cwbCO_SysHandle system,
cwbCO_PortLookupMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned by cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PortLookupMode mode - input
Specifies port lookup method. Possible values are:
CWBCO_PORT_LOOKUP_SERVER
Lookup of a host server port will be done by contacting the host
(AS/400) server mapper each time the connection of a service is to be
made when one does not yet exist. The server mapper returns the port
number that is then used to connect to the desired service on the
AS/400 system.
CWBCO_PORT_LOOKUP_LOCAL
Lookup of a host server port will be done by lookup in the SERVICES
file on the PC itself.
CWBCO_PORT_LOOKUP_STANDARD
The ″standard″ port—that set by default for a given host server and in
use if no one has changed the services table on the AS/400 system for
that service—will be used to connect to the desired service.

The latter two modes eliminate the AS/400 server mapper connection and its
associated delay, network traffic, and load on the AS/400 system.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon has successfully occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object.

88 Client Access Express Programming


Use CWBCO_PORT_LOOKUP_SERVER to be most certain of the accuracy of the
port number for a service; however, this requires an extra connection to the server
mapper on the AS/400 system every time a new connection to a service is to be
made.

Use CWBCO_PORT_LOOKUP_STANDARD to achieve the best performance,


although if the system administrator has changed the ports of any Client Access
host service in the service table on that AS/400 system, this mode will not work.

Use CWBCO_PORT_LOOKUP_LOCAL for best performance when the port for a


Client Access host service has been changed on the AS/400 system represented by
the system object. For this to work, entries for each host service port must be
added to a file on the PC named SERVICES. Each such entry must contain first the
standard name of the host service (for example, ″as-rmtcmd″ without the quotes)
followed by spaces and the port number for that service. The SERVICES file should
be located in the Windows install directory in Windows 95/98, or in subdirectory
system32\drivers\etc under the Windows NT® install directory in Windows NT.

Chapter 3. Express C/C++ APIs 89


cwbCO_SetPromptMode
Purpose: This function sets, for the specified system object, the prompt mode,
which specifies when and if the user should be prompted for user ID and
password, or other information, when a signon is performed.

Syntax:

UINT CWB_ENTRY cwbCO_SetPromptMode(


cwbCO_SysHandle system,
cwbCO_PromptMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_PromptMode - input
Specifies the prompt mode. Possible values are:
CWBCO_PROMPT_IF_NECESSARY
Client Access will prompt if either the user ID or password have not
been explicitly set or cannot be retrieved from the persistent
configuration for this system, the password cache (if enabled), or by
some other means.
If the Default User Mode has not been set, and if for this AS/400
system the user has not been prompted yet for default user ID, Client
Access will prompt for it at cwbCO_Connect or cwbCO_Signon time
CWBCO_PROMPT_ALWAYS
Client Access will always prompt when a signon is to occur for the
specified system object, even if a successful signon using the same user
ID to the same AS/400 system has occurred using a different system
object. Since a signon can occur only once for a system object, this
means that exactly one prompt per system object will occur. Additional
explicit signon calls will do nothing (including prompt). See two
exceptions to using this mode in the usage notes below.
CWBCO_PROMPT_NEVER
Client Access never will prompt for user ID and password, or for
default user ID. When this mode is used, a call to any API that
requires a signon for completion (for example, cwbCO_Signon or
cwbCO_Connect) will fail if either the user ID or password have not
been set and cannot be programmatically retrieved (from the AS/400
password cache). This mode should be used when either
v Client Access is running on a PC that is unattended or for some
other reason cannot support end-user interaction.
v The application itself is prompting for or otherwise fetching the user
ID and password, and explicitly setting them by using
cwbCO_SetUserIDEx and cwbCO_SetPassword.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.

90 Client Access Express Programming


CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon successfully has occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object. Setting the
prompt mode to CWBCO_PROMPT_ALWAYS will not prompt the user in the
following two cases:
v A user ID and password explicitly have been set with the cwbCO_setUserIDEx
and cwbCO_SetPassword APIs.
v Use Windows logon info (CWBCO_DEFAULT_USER_USEWINLOGON) has
been set with the cwbCO_SetDefaultUserMode API.

Chapter 3. Express C/C++ APIs 91


cwbCO_SetUserIDEx
Purpose: This function sets the user ID to associate with the specified system
object. This user ID will be used when connecting to the AS/400 with either the
cwbCO_Signon or cwbCO_Connect call.

Syntax:

UINT CWB_ENTRY cwbCO_SetUserIDEx(


cwbCO_SysHandle system,
LPCSTR userID );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPCSTR userID - input
Pointer to a buffer that contains the NULL-terminated user ID. The user ID
must not be longer than CWBCO_MAX_USER_ID characters, not including the
terminating NULL character.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
The userID pointer is NULL.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage that is being used.
CWB_INV_AFTER_SIGNON
Signon successfully has occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object. Setting a user
ID explicitly with this API will cause any default user mode set with the
cwbCO_SetDefaultUserMode API to be ignored.

92 Client Access Express Programming


cwbCO_SetValidateMode
Purpose: This function sets, for the specified system object, the validate mode,
which affects behavior when validating the user ID and password.

Syntax:

UINT CWB_ENTRY cwbCO_SetValidateMode(


cwbCO_SysHandle system,
cwbCO_ValidateMode mode );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbCO_ValidateMode mode - input
Specifies the validate mode. Possible values are:
CWBCO_VALIDATE_IF_NECESSARY
If validation of this user ID on this AS/400 system has occurred from
this PC within the last 24 hours, and the validation was successful,
then use the results of the last validation and do not connect to
validate at this time. There may be other scenarios where re-validation
will occur; Client Access will re-validate as needed.
CWBCO_VALIDATE_ALWAYS
Communication with the AS/400 system to validate user ID and
password will occur every time this validation is requested or required.
Setting this mode forces the validation to occur (when the system
object is not signed on yet). Once a system object is signed on, this
setting is ignored.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_PARAMETER
The mode parameter is an invalid value.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon has successfully occurred using the specified system object, so this
setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object.

Chapter 3. Express C/C++ APIs 93


cwbCO_SetWindowHandle
Purpose: This function sets, for the specified system object, the window handle to
use if any prompting is to be done that is associated with the system object (for
example, prompting for user ID and password). When so set (to a non-NULL
window handle), such a prompt would appear ’modal’ to the main application
window and therefore never would get hidden behind that window.

Syntax:

UINT CWB_ENTRY cwbCO_SetWindowHandle(


cwbCO_SysHandle system,
HWND windowHandle );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
HWND windowHandle - input
Specifies the window handle to associate with the system object. If NULL, no
window handle is associated with the system object.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.

Usage: This API may be used any time to change the window handle for the
specified system object, even after a successful signon.

94 Client Access Express Programming


cwbCO_Signon
Purpose: Sign the user on to the AS/400 system that is represented by the
specified system object by using user ID and password.

Note: Passing an incorrect password on the cwbCO_Signon API increments the


invalid signon attempts counter for the specified user. The user profile is
disabled if sufficient invalid passwords are sent to the host.

Syntax:

UINT CWB_ENTRY cwbCO_Signon(


cwbCO_SysHandle system,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_UNKNOWN_USERID
The supplied user ID is not known to this system.
CWB_WRONG_PASSWORD
Password is not correct.
CWB_PASSWORD_EXPIRED
Password has expired.
CWB_USER_PROFILE_DISABLED
The user ID has been disabled.
CWB_INVALID_PASSWORD
One or more characters in the password is invalid or the password is too
long.
CWB_INVALID_USERID
One or more characters in the user ID is invalid or the user ID is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Other return codes commonly may be returned as a result of a failed attempt to


connect to the signon server. For a list of such return codes, see comments for
cwbCO_Connect.

Chapter 3. Express C/C++ APIs 95


Usage: Both whether the user is prompted for user ID and password, and
whether the AS/400 system actually is contacted during user validation, are
influenced by current system object settings, such as user ID, password, Prompt
Mode, Default User Mode, and Validate Mode. See declarations for the get/set
APIs of these attributes for more information. If the AS/400 system as named in
the specified system object does not exist in the System List, and the system object
Persistence Mode is set appropriately, then when cwbCO_Connect or
cwbCO_Signon first is called successfully, the AS/400 system, as named in the
system object, will be added to the System List.

For more information about the Persistence Mode, see the comments for
cwbCO_SetPersistenceMode. If successful, and AS/400 password caching is
enabled, the password will be stored for the resulting user ID in the PC’s AS/400
password cache.

See also:
v “Differences between cwbCO_Signon and cwbCO_VerifyUserIDPassword” on
page 101
v “Similarities between cwbCO_Signon and cwbCO_VerifyUserIDPassword” on
page 101

96 Client Access Express Programming


cwbCO_UseSecureSockets
Purpose: Specify that all communication to the AS/400 system that uses the
specified system object either must use secure sockets or must not use secure
sockets.

Syntax:

UINT CWB_ENTRY cwbCO_UseSecureSockets(


cwbCO_SysHandle system,
cwb_Boolean useSecureSockets );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
cwb_Boolean useSecureSockets - input
Specifies whether to require secure sockets use when communicating with the
AS/400 system that the specified system object handle represents. Use the
appropriate value:
CWB_TRUE
Require secure sockets use for communication
CWB_FALSE
Do not use secure sockets for communication

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_SECURE_SOCKETS_NOTAVAIL
Secure sockets is not available. It may not be installed on the PC,
prohibited for this user, or not available on the AS/400 system.
CWB_RESTRICTED_BY_POLICY
A policy exists that prohibits the user from changing this value.
CWB_INV_AFTER_SIGNON
Signon has successfully occurred by using the specified system object, so
this setting no longer may be changed.

Usage: This API cannot be used after a successful signon has occurred for the
specified system object. A signon has occurred if either cwbCO_Signon or
cwbCO_Connect has been called successfully for this system object. If you specify
that secure sockets must be used, any attempt to communicate with the AS/400
system that cannot be completed using secure sockets will fail.

Client Access may or may not be able to detect at the time this API is called if
Secure Sockets will be available for use at connect time for this AS/400 system.
Even if CWB_SECURE_SOCKETS_NOTAVAIL is NOT returned, it may be
determined at a later time that secure sockets is not available.

Chapter 3. Express C/C++ APIs 97


cwbCO_Verify
Purpose: Verifies that a connection can be made to a specific host service on an
AS/400 system.

Syntax:

UINT CWB_ENTRY cwbCO_Verify(


cwbCO_SysHandle system,
cwbCO_Service service,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle system - input
Handle previously returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system to which to verify
connectability.
cwbCO_Service service - input
The service to verify connectability to on the AS/400 system. Valid values are
those listed in “Defines for cwbCO_Service” on page 101, except for the value
CWBCO_SERVICE_ANY. To verify connectability of ALL services, specify
CWBCO_SERVICE_ALL.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_SERVICE_NAME_ERROR
The service identifier is invalid.
CWB_COMMUNICATIONS_ERROR
An error occurred attempting to verify a connection to the service.

Usage: This API does not require user ID and password to be set, nor will it
cause a signon to occur, thus it will never prompt for this information. It does not
change the state of the system object in any way.

If a connection to any specified service already exists, no new connection will be


established, and connectability will be considered verified for that service.

If CWBCO_SERVICE_ALL is specified for verification, the return code will be


CWB_OK only if ALL services can be connected to. If any one verification attempt
fails, the return code will be that from the first failure, although verification of the
other services still will be attempted.

Since this API does not establish a usable connection, it automatically will
disconnect when the verification is complete; therefore, do NOT call
cwbCO_Disconnect to end the connection.

98 Client Access Express Programming


cwbCO_VerifyUserIDPassword
Purpose: This function verifies the correctness of the user ID and password
passed in, on the AS/400 system that the specified system object represents. If the
user ID and password are correct, it also retrieves data related to signon attempts
and password expiration.

Note: Passing an incorrect password on the cwbCO_VerifyUserIDPassword API


increments the invalid signon attempts counter for the specified user. The
user profile is disabled if sufficient invalid passwords are sent to the host.

Syntax:

UINT CWB_ENTRY cwbCO_VerifyUserIDPassword(


cwbCO_SysHandle system,
LPCSTR userID,
LPCSTR password,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle system - input
Handle that previously was returned from cwbCO_CreateSystem or
cwbCO_CreateSystemLike. It identifies the AS/400 system.
LPCSTR userID - input
Pointer to a buffer that contains the NULL-terminated user ID, which must not
exceed CWBCO_MAX_USER_ID characters in length, not including the
terminating NULL.
LPCSTR password - input
Pointer to a buffer that contains the NULL-terminated password, which must
not exceed CWBCO_MAX_PASSWORD characters in length, not including the
terminating NULL.
cwbSV_ErrHandle errorHandle - input/output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, or if the errorHandle is
invalid, no messages will be retrieved.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
A pointer supplied to the API is not valid.
CWB_UNKNOWN_USERID
The supplied user ID is not known to this system.
CWB_WRONG_PASSWORD
Password is not correct.
CWB_PASSWORD_EXPIRED
Password has expired.

Chapter 3. Express C/C++ APIs 99


CWB_USER_PROFILE_DISABLED
The user ID has been disabled.
CWB_INVALID_PASSWORD
One or more characters in the password is invalid or the password is too
long.
CWB_INVALID_USERID
One or more characters in the user ID is invalid or the user ID is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate a temporary buffer.
CWB_API_ERROR
General API failure.

Usage: See “Differences between cwbCO_Signon and


cwbCO_VerifyUserIDPassword” on page 101 and “Similarities between
cwbCO_Signon and cwbCO_VerifyUserIDPassword” on page 101.

100 Client Access Express Programming


Defines for cwbCO_Service
The following are values that define cwbCO_Service:
v CWBCO_SERVICE_CENTRAL
v CWBCO_SERVICE_NETFILE
v CWBCO_SERVICE_NETPRINT
v CWBCO_SERVICE_DATABASE
v CWBCO_SERVICE_ODBC
v CWBCO_SERVICE_DATAQUEUES
v CWBCO_SERVICE_REMOTECMD
v CWBCO_SERVICE_SECURITY
v CWBCO_SERVICE_DDM
v CWBCO_SERVICE_MAPI
v CWBCO_SERVICE_USF
v CWBCO_SERVICE_WEB_ADMIN
v CWBCO_SERVICE_TELNET
v CWBCO_SERVICE_MGMT_CENTRAL
v CWBCO_SERVICE_ANY
v CWBCO_SERVICE_ALL

Differences between cwbCO_Signon and


cwbCO_VerifyUserIDPassword
Following are listed some of the significant differences between cwbCO_Signon
and cwbCO_VerifyUserIDPassword:
v cwbCO_VerifyUserIDPassword requires that a user ID and password be
passed-in (system object values for these will NOT be used), and will not
prompt for this information. cwbCO_Signon may use prompting, depending on
other system object settings, and in that case will use whatever values are
supplied by the user for user ID and password in its validation attempt.
v Since cwbCO_VerifyUserIDPassword never will prompt for user ID and
password, these settings in the specified system object will not be changed as a
result of that call. A call to cwbCO_Signon, however, may change the user ID or
password of the system object as the result of possible prompting for this
information.
v cwbCO_VerifyUserIDPassword ALWAYS will result in a connection to the
AS/400 system being established to perform user ID and password validation,
and to retrieve current values (such as date and time of last successful signon)
related to signon attempts. cwbCO_Signon, however, might not connect to
validate the user ID and password, but instead may use recent results of a
previous validation. This is affected by recency of previous validation results as
well as by the Validation Mode attribute of the given system object.
v The password will be cached in the AS/400 password cache only in the case of
the successful completion of cwbCO_Signon, never as the result of a call to
cwbCO_VerifyUserIDPassword.
v cwbCO_VerifyUserIDPassword NEVER will set the system object state to ’signed
on’, whereas a successful cwbCO_Signon WILL change the state to ’signed on’.
This is important because when a system object is in a ’signed on’ state, most of
its attributes may no longer be changed.

Similarities between cwbCO_Signon and


cwbCO_VerifyUserIDPassword
Both APIs, when using a connection to validate the user ID and password, also
retrieve current data related to signon attempts. This data then can be retrieved by
using the following APIs:
v cwbCO_GetSignonDate
v cwbCO_GetPrevSignonDate
v cwbCO_GetPasswordExpireDate

Chapter 3. Express C/C++ APIs 101


v cwbCO_GetFailedSignons

Express Communications system list APIs listing


The following Communications system list APIs are listed alphabetically, by
function:

Function APIs
Create a list of configured systems, either cwbCO_CreateSysListHandle
in the currently active environment or in a cwbCO_CreateSysListHandleEnv
different environment. Retrieve the number cwbCO_GetSysListSize
of entries in the list, and each entry in cwbCO_GetNextSysName
succession. cwbCO_DeleteSysListHandle
Obtain information about individual cwbCO_GetDefaultSysName
systems that are configured or connected in cwbCO_GetConnectedSysName
the current process. Unless the environment cwbCO_IsSystemConfigured
name is passed as a parameter, these APIs cwbCO_IsSystemConfiguredEnv*
work only with the currently active cwbCO_IsSystemConnected
environment: cwbCO_GetUserID
cwbCO_GetActiveConversations
cwbCO_GetHostVersion
Obtain the names of environments that cwbCO_GetNumberOfEnvironments
have been configured. cwbCO_GetEnvironmentName
cwbCO_GetActiveEnvironment
Determine if the calling application can cwbCO_CanConnectNewSystem
modify environments and connection cwbCO_CanSetActiveEnvironment
information. cwbCO_CanModifyEnvironmentList
cwbCO_CanModifySystemList
cwbCO_CanModifySystemListEnv

102 Client Access Express Programming


cwbCO_CanConnectNewSystem
Purpose: Indicates whether the user may connect to a system not currently
configured in the System List within the active environment.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_CanConnectNewSystem();

Parameters: None

Return Codes: The following list shows common return values:


CWB_TRUE
Can connect to systems not already configured.
CWB_FALSE
Cannot connect to systems not already configured.

Usage: If this API returns CWB_FALSE, a call to cwbCO_CreateSystem with a


system name not currently configured will fail, as will various other Client Access
APIs that take system name as a parameter.

Chapter 3. Express C/C++ APIs 103


cwbCO_CanModifyEnvironmentList
Purpose: Indicates whether the user can create/remove/rename environments.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_CanModifyEnvironmentList();

Parameters:
None

Return Codes: The following list shows common return values.


CWB_TRUE
Can create/remove/rename/delete environments.
CWB_FALSE
Cannot create/remove/rename/delete environments.

Usage: This API indicates whether environments can be manipulated. To see if


systems within an environment may be manipulated, use the
cwbCO_CanModifySystemList and cwbCO_CanModifySystemListEnv APIs.

104 Client Access Express Programming


cwbCO_CanModifySystemList
Purpose: Indicates whether the user can add/remove/delete systems within the
active environment. Note that systems ″suggested″ by the administrator via
policies cannot be removed.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_CanModifySystemList();

Parameters:
None

Return Codes: The following list shows common return values:


CWB_TRUE
Can modify system list.
CWB_FALSE
Cannot modify system list.

Usage: This API indicates whether systems within the active environment can be
manipulated. To see if environments can be manipulated see the
cwbCO_CanModifyEnvironmentList API.

Chapter 3. Express C/C++ APIs 105


cwbCO_CanModifySystemListEnv
Purpose: Indicates whether the user can add/remove/delete systems within an
input environment. Note that systems ″suggested″ by the administrator via policies
cannot be removed.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_CanModifySystemListEnv(


char *environmentName);

Parameters:
char *environmentName - input
Pointer to a string that contains the desired environment name. If this pointer
is NULL, or if it points to an empty string, the currently active environment is
used.

Return Codes: The following list shows common return values:


CWB_TRUE
Can modify system list.
CWB_FALSE
Cannot modify system list, or an error occurred, such as having been
passed a non-existent environment name.

Usage: This API indicates whether systems within an environment can be


manipulated. To see if environments can be manipulated see the
cwbCO_CanModifyEnvironmentList API.

106 Client Access Express Programming


cwbCO_CanSetActiveEnvironment
Purpose: Indicates whether the user can set an environment to be the active
environment.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_CanSetActiveEnvironment();

Parameters:
None

Return Codes: The following list shows common return values:


CWB_TRUE
Can set the active environment.
CWB_FALSE
Cannot set the active environment.

Usage: None

Chapter 3. Express C/C++ APIs 107


cwbCO_CreateSysListHandle
Purpose: Creates a handle to a list of configured system names in the active
environment.

Syntax:

unsigned int CWB_ENTRY cwbCO_CreateSysListHandle(


cwbCO_SysListHandle *listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbCO_SysListHandle *listHandle - output
Pointer to a list handle that will be passed back on output. This handle is
needed for other calls using the list.
cwbSV_ErrorHandle errorHandle - input
If the API call fails, the message object that is associated with this handle will
be filled in with message text that describes the error. If this parameter is zero,
no messages will be available.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_POINTER
Pointer to the list handle is NULL.

Usage: cwbCO_DeleteSysListHandle must be called to free resources that are


allocated with this API.

108 Client Access Express Programming


cwbCO_CreateSysListHandleEnv
Purpose: Creates a handle to list of configured system names of the specified
environment.

Syntax:

unsigned int CWB_ENTRY cwbCO_CreateSysListHandleEnv(


cwbCO_SysListHandle *listHandle,
cwbSV_ErrHandle errorHandle,
LPCSTR pEnvironment );

Parameters:
cwbCO_SysListHandle *listHandle - output
Pointer to a list handle that will be passed back on output. This handle is
needed for other calls that are using the list.
cwbSV_ErrorHandle errorHandle - input
If the API call fails, the message object that is associated with this handle will
be filled in with message text that describes the error. If this parameter is zero,
no messages will be available.
LPCSTR pEnvironment
Pointer to a string containing the desired environment name. If pEnvironment
is the NULL pointer, or points to the NULL string (″\0″), the system list of the
current active environment is returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_INVALID_POINTER
Pointer to the list handle is NULL.
CWBCO_NO_SUCH_ENVIRONMENT
The specified environment does not exist.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: cwbCO_DeleteSysListHandle must be called to free resources allocated


with this API.

Chapter 3. Express C/C++ APIs 109


cwbCO_DeleteSysListHandle
Purpose: Deletes a handle to a list of configured system names. This must be
called when you are finished using the system name list.

Syntax:

unsigned int CWB_ENTRY cwbCO_DeleteSysListHandle(


cwbCO_SysListHandle listHandle);

Parameters:
cwbCO_SysListHandle - listHandle
A handle to the system name list to delete.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_API_HANDLE
Invalid system handle.

Usage: Use this API to delete the list created with the
cwbCO_CreateSysListHandle or cwbCO_CreateSysListHandleEnv API.

110 Client Access Express Programming


cwbCO_GetActiveConversations
Purpose: Get the number of active conversations of the system.

Syntax:

int CWB_ENTRY cwbCO_GetActiveConversations(


LPCSTR systemName);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.

Return Codes: The number of active conversations, if any, is returned. If the


systemName pointer is NULL, points to an empty string, the system is not
currently connected, or system name contains one or more Unicode characters
which cannot be converted, 0 will be returned.

Usage: This API returns the number of conversations active for the specified
AS/400 system within the CURRENT PROCESS ONLY. There may be other
conversations active within other processes running on the PC.

Chapter 3. Express C/C++ APIs 111


cwbCO_GetActiveEnvironment
Purpose: Get the name of the environment currently active.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetActiveEnvironment(


char *environmentName,
unsigned long *bufferSize);

Parameters:
char *environmentName - output
Pointer to a buffer into which will be copied the name of the active
environment, if the buffer that is passed is large enough to hold it. The buffer
should be large enough to hold at least CWBCO_MAX_ENV_NAME + 1
characters, including the terminating NULL character.
unsigned long * bufferSize - input/output
input Size of the buffer pointed to by *environmentName.
output
Size of buffer needed.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
One or more pointer parameters are NULL.
CWB_BUFFER_OVERFLOW
Not enough room in output buffer to hold entire environment name. Use
*bufferSize to determine the correct size. No error message is logged to the
History Log since the caller is expected to recover from this error and
continue.
CWBCO_NO_SUCH_ENVIRONMENT
No environments have been configured, so there is no active environment.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Usage:

112 Client Access Express Programming


cwbCO_GetConnectedSysName
Purpose: Get the name of the connected system corresponding to the index.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetConnectedSysName(


char *systemName,
unsigned long *bufferSize,
unsigned long index);

Parameters:
char *systemName - output
Pointer to a buffer that will contain the system name. This buffer should be
large enough to hold at least CWBCO_MAX_SYS_NAME + 1 characters,
including the terminating NULL character.
unsigned long * bufferSize - input/output
input Size of the buffer pointed to by *systemName.
output
Size of buffer needed.
unsigned long index
Indicates which connected system to retrieve the name for. The first connected
system’s index is 0, the second index is 1, and so on.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
Pointer to system name or pointer to buffer size needed is NULL. Check
messages in the History Log to determine which are NULL.
CWB_BUFFER_OVERFLOW
Not enough room in output buffer to hold entire system name. Use
*bufferSize to determine the correct size. No error message is logged to the
History Log since the caller is expected to recover from this error and
continue.
CWBCO_END_OF_LIST
The end of connected system list has been reached. No system name was
returned.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Usage: Connections for which system names can be retrieved are those within the
current process only.

Chapter 3. Express C/C++ APIs 113


cwbCO_GetDefaultSysName
Purpose: Get the name of the default system in the active environment.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetDefaultSysName(


char *defaultSystemName,
unsigned long bufferSize,
unsigned long *needed,
cwbSV_ErrHandle errorHandle);

Parameters:
char *defaultSystemName - output
Pointer to a buffer that will contain the NULL-terminated system name. This
buffer should be large enough to hold at least CWBCO_MAX_SYS_NAME + 1
characters, including the terminating NULL character.
unsigned long bufferSize - input
Size of input buffer.
unsigned long *needed - output
Number of bytes needed to hold entire system name including the terminating
NULL.
cwbSV_ErrorHandle errorhandle - input
If the API call fails, the message object associated with this handle will be
filled in with message text that describes the error. If this parameter is zero, no
messages will be available.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
Pointer to the system name or pointer to buffer size needed is NULL.
Check messages in the History Log to determine which are NULL.
CWB_BUFFER_OVERFLOW
Not enough room in output buffer to hold the entire system name. Use
*needed to determine the correct size. No error message is logged to the
History Log since the caller is expected to recover from this error and
continue.
CWBCO_DEFAULT_SYSTEM_NOT_DEFINED
The setting for the default system has not been defined in the active
environment.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Usage:

114 Client Access Express Programming


cwbCO_GetEnvironmentName
Purpose: Get the name of the environment corresponding to the index.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetEnvironmentName(


char *environmentName,
unsigned long *bufferSize,
unsigned long index);

Parameters:
char *environmentName - output
Pointer to a buffer that will contain the environment name. This buffer should
be large enough to hold at least CWBCO_MAX_ENV_NAME + 1 characters,
including the terminating NULL character.
unsigned long * bufferSize - input/output
input Size of the buffer pointed to by *environmentName.
output
Size of buffer needed, if the buffer provided was too small.
unsigned long index - input
0 corresponds to the first environment.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
One or more pointer parameters are NULL.
CWB_BUFFER_OVERFLOW
Not enough room in output buffer to hold entire environment name. Use
*bufferSize to determine the correct size. No error message is logged to the
History Log since the caller is expected to recover from this error and
continue.
CWBCO_END_OF_LIST
The end of the environments list has been reached. No environment name
was returned.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Usage:

Chapter 3. Express C/C++ APIs 115


cwbCO_GetHostVersion
Purpose: Get the version and release level of the host.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetHostVersion(


LPCSTR system,
unsigned int * version,
unsigned int * release );

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.
unsigned int * version - output
Pointer to a buffer where the version level of the system is returned.
unsigned int * release - output
Pointer to a buffer where the release level of the system is returned.

Return Codes: The following list shows common return values:


CWB_OK
Successful Completion.
CWBCO_SYSTEM_NOT_CONFIGURED
The system is not configured in the currently active environment.
CWBCO_SYSTEM_NOT_CONNECTED
The system has never been connected to when using the currently active
environment.
CWB_INVALID_POINTER
One of the pointers passed is NULL.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: The host version is retrieved and saved whenever a connection is made to
the system; this API does not go to the host to get it on each call. The system must
have been connected previously, though not necessarily at the time the API is
called. Host information can only be retrieved for systems configured in the
currently active environment.

116 Client Access Express Programming


cwbCO_GetNextSysName
Purpose: Get the name of the next system from a list of systems.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetNextSysName(


cwbCO_SysListHandle listHandle,
char *systemName,
unsigned long bufferSize,
unsigned long *needed);

Parameters:
cwbCO_SysListHandle handleList - input
Handle to a list of systems.
char *systemName - output
Pointer to a buffer that will contain the system name. This buffer should be
large enough to hold at least CWBCO_MAX_SYS_NAME + 1 characters,
including the terminating NULL character.
unsigned long bufferSize - input
Size of the buffer pointed to by systemName.
unsigned long *needed - output
Number of bytes needed to hold entire system name.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
Pointer to system name or pointer to buffer size needed is NULL. Check
messages in the History Log to determine which are NULL.
CWB_BUFFER_OVERFLOW
Not enough room in output buffer to hold entire system name. Use
*needed to determine the correct size. No error message is logged to the
History Log since the caller is expected to recover from this error and
continue.
CWBCO_END_OF_LIST
The end of the system list has been reached. No system name was
returned.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_API_ERROR
General API failure.

Usage: If the system list passed in was created using the API
cwbCO_CreateSystemListHandle, then the system returned is configured in the
currently active environment, unless between these API calls the user has removed
it or switched to a different environment. If cwbCO_CreateSysListHandleEnv was
called to create the system list, then the system returned is configured in the
environment passed to that API, unless the user has since removed it.

Chapter 3. Express C/C++ APIs 117


cwbCO_GetNumberOfEnvironments
Purpose: Get the number of Client Access environments that exist. This includes
both the active and all non-active environments.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetNumberOfEnvironments(


unsigned long *numberOfEnv);

Parameters:
unsigned long *numberOfEnv - output
On output this will be set to the number of environments.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
The numberOfEnv pointer parameter is NULL.

Usage: None.

118 Client Access Express Programming


cwbCO_GetSysListSize
Purpose: Gets the number of system names in the list.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetSysListSize(


cwbCO_SysListHandle listHandle,
unsigned long *listSize);

Parameters:
cwbCO_SysListHandle listHandle - input
Handle of the list of systems.
unsigned long *listSize - output
On output this will be set to the number of systems in the list.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_API_HANDLE
Invalid system handle.
CWB_INVALID_POINTER
Pointer to the list size is NULL.

Usage: None.

Chapter 3. Express C/C++ APIs 119


cwbCO_GetUserID
Purpose: Get signon or default user ID of the input system as it is configured and
possibly connected in the currently active environment.

Syntax:

unsigned int CWB_ENTRY cwbCO_GetUserID(


LPCSTR systemName,
char *userID,
unsigned int userID_Type,
unsigned long *bufferSize);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.
char *userID - output
Pointer to a buffer where the desired userID of the system is returned. This
buffer should be large enough to hold at least CWBCO_MAX_USER_ID + 1
characters, including the terminating NULL character.
unsigned int userID_Type - input
Specify whether current user ID of connected system
(CWBCO_CURRENT_USER_ID) or default user ID of configured system
(CWBCO_DEFAULT_USER_ID) is to be returned.
unsigned long * bufferSize - input/output
Pointer to a value that indicates the size of the userID buffer. If the buffer is
not big enough, the value needed is returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
One or more input pointers are invalid.
CWB_INVALID_PARAMETER
The value for userID_Type is invalid.
CWB_BUFFER_OVERFLOW
Not enough room in userID buffer to store the user ID. Use *bufferSize to
determine the correct size. No error message is logged to the History Log
since the caller is expected to recover from this error and continue.
CWBCO_SYSTEM_NOT_CONNECTED
The system of the ″current user ID″ is not connected.
CWBCO_SYSTEM_NOT_CONFIGURED
The system of the ″default user ID″ is not configured in the currently
active environment.
CWBCO_INTERNAL_ERROR
Internal error.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.

120 Client Access Express Programming


CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: If the default user ID is specified, and none was entered when the
connection was configured, CWB_OK will be returned and the user ID sent back to
the caller will be the empty string, ″\0″. The user ID retrieved will be that of the
specified system from the currently active environment.

Chapter 3. Express C/C++ APIs 121


cwbCO_IsSystemConfigured
Purpose: Check if the input system is configured in the environment currently in
use.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_IsSystemConfigured(


LPCSTR systemName);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.

Return Codes: The following list shows common return values:


CWB_TRUE:
System is configured.
CWB_FALSE:
System is not configured, systemName is NULL, or system name contains
one or more Unicode characters that cannot be converted.

Usage: None

122 Client Access Express Programming


cwbCO_IsSystemConfiguredEnv
Purpose: Check if the input system is configured in the environment specified.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_IsSystemConfiguredEnv(


LPCSTR systemName,
LPCSTR pEnvironment);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.
LPCSTR pEnvironment - input
Pointer to a buffer that contains the environment name. If pEnvironment is
NULL, or if it points to an empty string, the environment currently in use is
checked.

Return Codes: The following list shows common return values:


CWB_TRUE:
System is configured.
CWB_FALSE:
System is not configured, systemName is NULL, or system name contains
one or more Unicode characters that cannot be converted.

Usage: None

Chapter 3. Express C/C++ APIs 123


cwbCO_IsSystemConnected
Purpose: Check if the input system is currently connected.

Syntax:

cwb_Boolean CWB_ENTRY cwbCO_IsSystemConnected(


LPCSTR systemName);

Parameters:
LPCSTR systemName - input
Pointer to a buffer that contains the system name.

Return Codes: The following list shows common return values.


CWB_TRUE:
System is connnected.
CWB_FALSE:
System is not connected, systemName is NULL, or system name contains
one or more Unicode characters that cannot be converted.

Usage: This API indicates connection status within the current process only. The
system may be connected within a different process, but this has no effect on the
output of this API.

124 Client Access Express Programming


Example: Using Express communications APIs
The example program below shows the use of communications APIs to retrieve
and display the names of the default (managing) system, along with all the
systems that are configured in the active environment.
/*******************************************************************/
/* */
/* Module: */
/* GETSYS.C */
/* */
/* Purpose: */
/* This module is used to demonstrate how an application might use */
/* the Communication API's. In this example, these APIs are used to */
/* get and display the list of all configured systems. The user can */
/* choose either to be shown all of a system's connection properties */
/* (the attributes of the created system object), or to have */
/* connectability to all Client Access Express servers checked. */
/* */
/* Usage Notes: */
/* */
/* Includes CWBCO.H, CWBCOSYS.H, and CWBSV.H */
/* Link with CWBAPI.LIB */
/* */
/* */
/* LICENSE AND DISCLAIMER */
/* */
/* This material contains IBM copyrighted sample programming source */
/* code for your consideration. This sample code has not been */
/* thoroughly tested under all conditions. IBM, therefore, cannot */
/* guarantee or imply reliability, serviceability, or function. */
/* IBM provides no program services for this material. This material */
/* is provided "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR */
/* IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
/* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SOME */
/* JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO */
/* THE ABOVE EXCLUSIONS MAY NOT APPLY TO YOU. IN NO EVENT WILL IBM */
/* BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT, SPECIAL OR OTHER */
/* CONSEQUENTIAL DAMAGES FOR ANY USE OF THIS MATERIAL INCLUDING, */
/* WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS INTERRUPTION, LOSS */
/* OF PROGRAMS OR OTHER DATA ON YOUR INFORMATION HANDLING SYSTEM OR */
/* OTHERWISE, EVEN IF EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH */
/* DAMAGES. */
/* */
/* */
/* COPYRIGHT */
/* --------- */
/* (C) Copyright IBM CORP. 1998, 1999 */
/* All rights reserved. */
/* US Government Users Restricted Rights - */
/* Use, duplication or disclosure restricted */
/* by GSA ADP Schedule Contract with IBM Corp. */
/* Licensed Material - Property of IBM */
/* */
/************************************************************************/

#include <windows.h>
#include <stdio.h>

#include "cwbsv.h" /* Service APIs for retrieving any error messages */


#include "cwbco.h" /* Comm APIs for enumerating systems configured */
#include "cwbcosys.h" /* Comm APIs for creating and using system objects */

#define SUCCESS (0)


#define FAILURE (1)

Chapter 3. Express C/C++ APIs 125


/*
* Arrays of system object attribute description strings, for
* display of these values in human-readable form.
*/
char* valModeStr[2] = { "CWBCO_VALIDATE_IF_NECESSARY" ,
"CWBCO_VALIDATE_ALWAYS" } ;

char* promptModeStr[3] = { "CWBCO_PROMPT_IF_NECESSARY" ,


"CWBCO_PROMPT_ALWAYS" ,
"CWBCO_PROMPT_NEVER" } ;

char* dfltUserModeStr[4] = { "CWBCO_DEFAULT_USER_MODE_NOT_SET" ,


"CWBCO_DEFAULT_USER_USE" ,
"CWBCO_DEFAULT_USER_IGNORE" ,
"CWBCO_DEFAULT_USER_USEWINLOGON" } ;

char* IPALModeStr[6] = { "CWBCO_IPADDR_LOOKUP_ALWAYS" ,


"CWBCO_IPADDR_LOOKUP_1HOUR" ,
"CWBCO_IPADDR_LOOKUP_1DAY" ,
"CWBCO_IPADDR_LOOKUP_1WEEK" ,
"CWBCO_IPADDR_LOOKUP_NEVER" ,
"CWBCO_IPADDR_LOOKUP_AFTER_STARTUP" } ;

char* portLookupModeStr[3] = { "CWBCO_PORT_LOOKUP_SERVER" ,


"CWBCO_PORT_LOOKUP_LOCAL" ,
"CWBCO_PORT_LOOKUP_STANDARD" } ;

char* cwbBoolStr[2] = { "False", "True" } ;

/* NOTE! The corresponding service CONSTANT integers start


* at 1, NOT at 0; that is why the dummy "FAILURE" value
* was added at position 0.
*/
char* serviceStr[15] = { "CWBCO_SERVICE_BADSERVICE!",
"CWBCO_SERVICE_CENTRAL" ,
"CWBCO_SERVICE_NETFILE" ,
"CWBCO_SERVICE_NETPRINT" ,
"CWBCO_SERVICE_DATABASE" ,
"CWBCO_SERVICE_ODBC" ,
"CWBCO_SERVICE_DATAQUEUES" ,
"CWBCO_SERVICE_REMOTECMD" ,
"CWBCO_SERVICE_SECURITY" ,
"CWBCO_SERVICE_DDM" ,
"CWBCO_SERVICE_MAPI" ,
"CWBCO_SERVICE_USF" ,
"CWBCO_SERVICE_WEB_ADMIN" ,
"CWBCO_SERVICE_TELNET" ,
"CWBCO_SERVICE_MGMT_CENTRAL" } ;

/*
* Node in a singly-linked list to hold a system object
* handle. (The system name is retrievable from the
* system object by calling cwbCO_GetSystemName().)
* Note that the creator of an instance of this node must
* allocate the space to hold the system name himself,
* only a pointer is supplied here.

*/
typedef struct sysListNodeStruct SYSLISTNODE, *PSYSLISTNODE;
struct sysListNodeStruct
{
cwbCO_SysHandle hSys;
PSYSLISTNODE next;
} ;

126 Client Access Express Programming


/****************************************************************************
* Add a system name to the list of configured systems we will keep around.
****************************************************************************/
UINT addSystemToList(
char* sysName,
SYSLISTNODE** ppSysList )
{
PSYSLISTNODE pNewSys;
UINT apiRC;

pNewSys = (PSYSLISTNODE) malloc (sizeof( SYSLISTNODE ));


if ( pNewSys == NULL )
{
printf( "Failed to allocate storage for a SYSLISTNODE!\n" );
return FAILURE;
}

apiRC = cwbCO_CreateSystem( sysName, &(pNewSys->hSys) );


if ( CWB_OK != apiRC )
{
printf(
"Failed to create system object for '%s', cwbCO_CreateSystem rc=%u\n",
sysName, apiRC );
free (pNewSys);
return FAILURE;
}

pNewSys->next = *ppSysList;
*ppSysList = pNewSys;

return SUCCESS;
}

/****************************************************************************
* Clear the list of system names and clean up used storage.
****************************************************************************/
void clearList( SYSLISTNODE* pSysList )
{
PSYSLISTNODE pCur, pNext;
UINT apiRC;

pCur = pSysList;

while ( pCur != NULL )


{
pNext = pCur->next;
apiRC = cwbCO_DeleteSystem( pCur->hSys );
if ( CWB_OK != apiRC )
{
/* Advise user of this failure, since this may indicate
* that there is a bug in our program! (The system
* object handle SHOULD be good, so delete SHOULD work.)
*/
printf( "In clearList, cwbCO_DeleteSystem() failed, rc=%u\n", apiRC );
}
free (pCur);
pCur = pNext;
}
}

/****************************************************************************

Chapter 3. Express C/C++ APIs 127


* Retrieve and display Client Access FAILURE messages.
****************************************************************************/
void reportCAErrors( cwbSV_ErrHandle hErrs )
{
ULONG msgCount;
UINT apiRC;
UINT i;
char msgText[ 200 ]; /* 200 is big enuf to hold most msgs */
ULONG bufLen = sizeof( msgText ); /* holds size of msgText buffer */
ULONG lenNeeded; /* to hold length of buf needed */

apiRC = cwbSV_GetErrCount( hErrs, &msgCount );


if ( CWB_OK != apiRC )
{
printf( "Failed to get message count, cwbSV_GetErrCount rc=%u\n", apiRC );
if ( ( CWB_INVALID_POINTER == apiRC ) ||
( CWB_INVALID_HANDLE == apiRC ) )
{
printf( " --> likely a programming FAILURE!\n");
}
return;
}

bufLen = sizeof( msgText );


for ( i=1; i<=msgCount; i++ )
{
apiRC = cwbSV_GetErrTextIndexed(hErrs, i, msgText, bufLen, &lenNeeded);
if ( ( CWB_OK == apiRC ) ||
( CWB_BUFFER_OVERFLOW == apiRC ) ) /* if truncated, that's ok */
{
printf( "CA ERROR #%u: %s\n", i, msgText );
}
else
{
printf( "CA ERROR #%u unavailable, cwbSV_GetErrTextIndexed rc=%u\n",
i, apiRC );
}
}
}

/****************************************************************************
* Build the list of systems as it is currently configured in Client
* Access.
****************************************************************************/
UINT buildSysList(
SYSLISTNODE** ppSysList )
{
cwbSV_ErrHandle hErrs;
cwbCO_SysListHandle hList;
char sysName[ CWBCO_MAX_SYS_NAME + 1 ];
ULONG bufSize = sizeof( sysName );
ULONG needed;
UINT apiRC;
UINT myRC = SUCCESS;

/* Create a FAILURE handle so that, in case of FAILURE, we can


* retrieve and display the messages (if any) associated with
* the failure.
*/
apiRC = cwbSV_CreateErrHandle( &hErrs );
if ( CWB_OK != apiRC )
{
/* Failed to create an FAILURE handle, use NULL instead.
* This means we'll not be able to get at FAILURE messages.
*/
hErrs = 0;

128 Client Access Express Programming


}

apiRC = cwbCO_CreateSysListHandle( &hList, hErrs );


if ( CWB_OK != apiRC )
{
printf( "Failure to get a handle to the system list.\n" );
reportCAErrors( hErrs );
myRC = FAILURE;
}

/* Get each successive system name and add the system to our
* internal list for later use.
*/
while ( ( CWB_OK == apiRC ) && ( myRC == SUCCESS ) )
{
apiRC = cwbCO_GetNextSysName( hList, sysName, bufSize, &needed );

/* Note that since the sysName buffer is as large as it will


* ever need to be, we don't check specifically for the return
* code CWB_BUFFER_OVERFLOW. We could instead choose to use a
* smaller buffer, and if CWB_BUFFER_OVERFLOW were returned,
* allocate one large enough and call cwbCO_GetNextSysName
* again.
*/
if ( CWB_OK == apiRC )
{
myRC = addSystemToList( sysName, ppSysList );
if ( myRC != SUCCESS )
{
printf( "Failure to add the next system name to the list.\n");
}
}
else if ( CWBCO_END_OF_LIST != apiRC )
{
printf( "Failed to get the next system name.\n" );
myRC = FAILURE;
}
} /* end while (to build a list of system names) */

/*
* Free the FAILURE handle if one was created
*/
if ( hErrs != 0 ) /* (non-NULL if it was successfully created) */
{
apiRC = cwbSV_DeleteErrHandle( hErrs );
if ( CWB_INVALID_HANDLE == apiRC )
{
printf("Failure: FAILURE handle invalid, could not delete!\n");
myRC = FAILURE;
}
}

return myRC;
}

/****************************************************************************
* Get a system object given an index into our list of systems.
****************************************************************************/
UINT getSystemObject(
UINT sysNum,
SYSLISTNODE* pSysList,
cwbCO_SysHandle* phSys )
{
SYSLISTNODE* pCur;
UINT myRC = SUCCESS;

Chapter 3. Express C/C++ APIs 129


pCur = pSysList;
for ( ; sysNum > 1; sysNum-- )
{
/* We have come to the end of the list without finding
* the system requested, break out of loop and set FAILURE rc.
*/
if ( NULL == pCur )
{
myRC = FAILURE;
break;
}

pCur = pCur->next;
}

/* If we're at a real system node, return its system object handle


*/
if ( NULL != pCur )
{
*phSys = pCur->hSys;
}

return myRC;
}

/****************************************************************************
* Allow the user to select a system from the list we have.
****************************************************************************/
UINT selectSystem(
UINT* pNumSelected,
SYSLISTNODE* pSysList,
BOOL refreshList )
{
UINT myRC = SUCCESS;
SYSLISTNODE* pCur;
UINT sysNum, numSystems;
char choiceStr[ 20 ];
UINT apiRC;
char sysName[ CWBCO_MAX_SYS_NAME + 1 ];
ULONG sysNameBufLen = sizeof( sysName );

/* If the user wants the list refreshed, clear any existing list
* so we can rebuilt it from scratch.
*/
if ( refreshList )
{
clearList( pSysList );
pSysList = NULL;
}

/* If the list of system names is NULL (no list exists), build


* the list of systems using Client Access APIs.
*/
if ( NULL == pSysList )
{
myRC = buildSysList( &pSysList );
if ( SUCCESS != myRC )
{
*pNumSelected = 0;
printf( "Failed to build sys list, cannot select a system.\n");
}
}

if ( SUCCESS == myRC )
{

130 Client Access Express Programming


printf( "-------------------------------------------- \n" );
printf( "The list of systems configured is as follows:\n" );
printf( "-------------------------------------------- \n" );
for ( sysNum = 1, pCur = pSysList;
pCur != NULL;
sysNum++, pCur = pCur->next )
{
printf( " %u) ", sysNum );
sysNameBufLen = sizeof( sysName ); /* set in case the API changed it */
apiRC = cwbCO_GetSystemName( pCur->hSys, sysName, &sysNameBufLen );
if ( CWB_OK == apiRC )
{
printf( "%s\n", sysName );
}
else
{
printf( "unknown (cwbCO_GetSystemName() rc=%u)\n", apiRC );
}
}
numSystems = sysNum - 1;

printf( "Enter the number of the system of your choice:\n");


gets( choiceStr );
*pNumSelected = atoi( choiceStr );

if ( *pNumSelected > numSystems )


{
printf( "Invalid selection, there are only %u systems configured.\n",
numSystems );
*pNumSelected = 0;
myRC = FAILURE;
}
}

return myRC;
}

/****************************************************************************
* Display a single attribute and its value, or a failing return code
* if one occurred when trying to look it up.
****************************************************************************/
void dspAttr(
char* label,
char* attrVal,
UINT lookupRC,
cwb_Boolean* pCanBeModified,
UINT canBeModifiedRC )
{
if ( CWB_OK == lookupRC )
{
printf( "%-25s : %-30s ", label, attrVal );
if ( CWB_OK == canBeModifiedRC )
{
if ( pCanBeModified != NULL )
{
printf( "%s\n", cwbBoolStr[ *pCanBeModified ] );
}
else
{
printf( "(N/A)\n" );
}
}
else
{
printf( "(Error, rc=%u)\n", canBeModifiedRC );

Chapter 3. Express C/C++ APIs 131


}
}
else
{
printf( "%-25s : (Error, rc=%u)\n", label, lookupRC );
}
}

/****************************************************************************
*
* Load the host/version string into the buffer specified. The
* buffer passed in must be at least 7 bytes long! A pointer to
* the buffer itself is passed back so that the output from this
* function can be used directly as a parameter.
*
****************************************************************************/
char* hostVerModeDescr(
ULONG ver,
ULONG rel,
char* verRelBuf )
{
char* nextChar = verRelBuf;

if ( verRelBuf != NULL )
{
*nextChar++ = 'v';
if ( ver < 10 )
{
*nextChar++ = '0' + (char)ver;
}
else
{
*nextChar++ = '?';
*nextChar++ = '?';
}

*nextChar++ = 'r';
if ( rel < 10 )
{
*nextChar++ = '0' + (char)rel;
}
else
{
*nextChar++ = '?';
*nextChar++ = '?';
}

*nextChar = '\0';
}

return verRelBuf;
}

/****************************************************************************
* Display all attributes of the system whose index in the passed list
* is passed in.
****************************************************************************/
void dspSysAttrs(
SYSLISTNODE* pSysList,
UINT sysNum )
{
cwbCO_SysHandle hSys;
UINT rc;

132 Client Access Express Programming


char sysName[ CWBCO_MAX_SYS_NAME + 1 ];
char IPAddr[ CWBCO_MAX_IP_ADDRESS + 1 ];
ULONG bufLen, IPAddrLen;
UINT apiRC, apiRC2;
cwbCO_ValidateMode valMode;
cwbCO_DefaultUserMode dfltUserMode;
cwbCO_PromptMode promptMode;
cwbCO_PortLookupMode portLookupMode;
cwbCO_IPAddressLookupMode IPALMode;
ULONG ver, rel;
char verRelBuf[ 10 ];
cwb_Boolean isSecSoc;
cwb_Boolean canModify;

rc = getSystemObject( sysNum, pSysList, &hSys );


if ( rc == FAILURE )
{
printf( "Failed to get system object for selected system.\n");
return;
}

printf("\n\n");
printf("-----------------------------------------------------------\n");
printf(" S y s t e m A t t r i b u t e s \n");
printf("-----------------------------------------------------------\n");
printf("\n");
printf( "%-25s %-30s %s\n", "Attribute", "Value", "Modifiable" );
printf( "%-25s %-30s %s\n", "---------", "-----", "----------" );
printf("\n");

apiRC = cwbCO_GetSystemName( hSys, sysName, &bufLen );


dspAttr( "System Name", sysName, apiRC, NULL, 0 );

apiRC = cwbCO_GetIPAddress( hSys, IPAddr, &IPAddrLen );


dspAttr( "IP Address", IPAddr, apiRC, NULL, 0 );

apiRC = cwbCO_GetHostVersionEx( hSys, &ver, &rel );


dspAttr( "Host Version/Release",
hostVerModeDescr( ver, rel, verRelBuf ), apiRC, NULL, 0 );

apiRC = cwbCO_IsSecureSockets( hSys, &isSecSoc );


apiRC2 = cwbCO_CanModifyUseSecureSockets( hSys, &canModify );
dspAttr( "Secure Sockets In Use", cwbBoolStr[ isSecSoc ],
apiRC, &canModify, apiRC2 );

apiRC = cwbCO_GetValidateMode( hSys, &valMode );


canModify = CWB_TRUE;
dspAttr( "Validate Mode", valModeStr[ valMode ], apiRC,
&canModify, 0 );

apiRC = cwbCO_GetDefaultUserMode( hSys, &dfltUserMode );


apiRC2 = cwbCO_CanModifyDefaultUserMode( hSys, &canModify );
dspAttr( "Default User Mode", dfltUserModeStr[ dfltUserMode ], apiRC,
&canModify, apiRC2 );

apiRC = cwbCO_GetPromptMode( hSys, &promptMode );


canModify = CWB_TRUE;
dspAttr( "Prompt Mode", promptModeStr[ promptMode ], apiRC,
&canModify, 0 );

apiRC = cwbCO_GetPortLookupMode( hSys, &portLookupMode );


apiRC2 = cwbCO_CanModifyPortLookupMode( hSys, &canModify );
dspAttr( "Port Lookup Mode", portLookupModeStr[ portLookupMode ], apiRC,
&canModify, apiRC2 );

apiRC = cwbCO_GetIPAddressLookupMode( hSys, &IPALMode );


apiRC2 = cwbCO_CanModifyIPAddressLookupMode( hSys, &canModify );

Chapter 3. Express C/C++ APIs 133


dspAttr( "IP Address Lookup Mode", IPALModeStr[ IPALMode ], apiRC,
&canModify, apiRC2 );

printf("\n\n");
}

/****************************************************************************
* Display connectability to all Client Access services that are
* possible to connect to.
****************************************************************************/
void dspConnectability(
PSYSLISTNODE pSysList,
UINT sysNum )
{
UINT rc;
UINT apiRC;
cwbCO_Service service;
cwbCO_SysHandle hSys;

rc = getSystemObject( sysNum, pSysList, &hSys );


if ( rc == FAILURE )
{
printf( "Failed to get system object for selected system.\n");
}
else
{
printf("\n\n");
printf("-----------------------------------------------------------\n");
printf(" S y s t e m S e r v i c e s S t a t u s \n");
printf("-----------------------------------------------------------\n");
for ( service=(cwbCO_Service)1;
service <= CWBCO_SERVICE_MGMT_CENTRAL;
service++ )
{
apiRC = cwbCO_Verify( hSys, service, 0 ); // 0=no err handle
printf(" Service %-30s : ", serviceStr[ service ] );
if ( apiRC == CWB_OK )
{
printf("Connectable\n");
}
else
{
printf("CONNECT TEST FAILED, rc = %u\n", apiRC );
}
}
}

printf("\n");
}

/****************************************************************************
* MAIN PROGRAM BODY
****************************************************************************/
void main(void)
{
PSYSLISTNODE pSysList = NULL;
UINT numSelected;
UINT rc;
char choiceStr[10];
UINT choice;

rc = buildSysList( &pSysList );
if ( SUCCESS != rc )

134 Client Access Express Programming


{
printf( "\nFailure to build the system list, exiting.\n\n");
exit( FAILURE );
}

do
{
printf( "\n" );
printf( "Select one of the following options:\n" );
printf( " (1) Display current system attributes\n");
printf( " (2) Display service connectability for a system\n");
printf( " (3) Refresh the list of systems\n" );
printf( " (9) Quit\n" );
gets( choiceStr );
printf( "\n" );
choice = atoi( choiceStr );
switch ( choice )
{
// ---- Display current system attributes ---------------
case 1 :
{
rc = selectSystem( &numSelected, pSysList, FALSE );
if ( SUCCESS == rc )
{
dspSysAttrs( pSysList, numSelected );
}

break;
}

// ---- Display service connectability for a system -----


case 2 :
{
rc = selectSystem( &numSelected, pSysList, FALSE );
if ( SUCCESS == rc )
{
dspConnectability( pSysList, numSelected );
}

break;
}

// ---- Refresh the list of systems ---------------------


case 3 :
{
clearList( pSysList );
pSysList = NULL;
rc = buildSysList( &pSysList );
break;
}

// ---- Quit --------------------------------------------


case 9 :
{
break;
}

default :
{
printf("Invalid choice. Please make a different selection.\n");
}
}
} while ( choice != 9 );

/* Cleanup the list, we're done */


clearList( pSysList );
pSysList = NULL;

Chapter 3. Express C/C++ APIs 135


printf( "\nEnd of program.\n\n" );
}

Express database programming


Client Access Express provides multiple programming interfaces for accessing
database files on the AS/400. Some of these interfaces are common interfaces,
allowing you to write a single application that accesses both the AS/400 database
and non-AS/400 databases. Express also supports a proprietary C API to expose
the unique strengths of DB2® for AS/400.

Express provides both Structured Query Language (SQL) and record-level access
interfaces. The SQL interfaces provide access to DB2 Universal Database (UDB) for
AS/400 database files and stored procedures. The record-level access interface
provides the fastest access to single records within a file. The IBM DB2 UDB for
AS/400 SQL Programming book contains detailed information.
How to access the book:
Follow these steps to view a hypertext markup language (HTML) online
version of the DB2 UDB for AS/400 SQL Programming book, and to print a
PDF version:
1. Link to the DB2 Universal Database™ for AS/400 books online topic in
the AS/400 Information Center
2. Select SQL Programming Concepts

The following Express database interfaces are available to C/C++ programmers:


“Express OLE DB Provider”
Supports record-level access and SQL access to AS/400 database files. Use
the ActiveX Data Objects (ADO) and the OLE DB interfaces to take
advantage of this support.
“Express ODBC” on page 137
A common database interface that uses SQL as its database access
language. Express provides an ODBC driver to support this interface.
“Express database APIs (Optimized SQL)” on page 291
The Express proprietary C/C++ Database APIs provide support for AS/400
database and catalog functions, in addition to SQL access to AS/400
database files.

Express OLE DB Provider


The Client Access Express OLE DB Provider, along with the Client Access Express
Toolkit, makes AS/400 client/server application development quick and easy from
the Windows client PC. The Client Access Express OLE DB Provider gives AS/400
programmers record-level access interfaces to AS/400 logical and physical DB2
Universal Database (UDB) for AS/400 database files. In addition, it provides
support for SQL, data queues, programs, and commands. If you use Visual Basic,
the Visual Basic Wizards make it simple and easy to develop customized, working
applications.

ADO and OLE DB standards provide programmers with consistent interfaces to


AS/400 data and services. The IBMDA400 Provider handles all AS/400-to-PC and
data type-to-data type conversions.

136 Client Access Express Programming


To install OLE DB Provider:
When you install Client Access Express (or when you run Selective Setup
if Express is installed), select the Data Access component. Make sure that
the OLE DB Provider subcomponent also is selected.
To access OLE DB Technical Reference:
The Express OLE DB Technical Reference, which is shipped with Client
Access Express, provides complete documentation of OLE DB Provider
support. To access it from the Client Access Express Toolkit, select
Overview —> Common Interfaces —> ADO/OLE DB.
To install Client Access Express Toolkit and the Visual Basic Wizards:
When you install Client Access Express (or when you run Selective Setup
if Express is installed), select the Client Access Express Toolkit
component. See “Installing the Express Toolkit” on page 10 for more
information.

Other OLE DB information resources:

v IBM Client Access OLE DB Support Web site.


v IBM Redbook Fast Path to AS/400 Client/Server Using AS/400 OLE DB
Support: SG24–5183

Express ODBC
What is ODBC?
ODBC stands for open database connectivity. It consists of:
v A well-defined set of functions (application programming interfaces)
v Standards for SQL syntax (that are recommended but not imposed)
v Error codes
v Data types

The application programming interfaces provide a rich set of functions to connect


to a database management system, run SQL statements and to retrieve data. Also
included are functions to interrogate the SQL catalog of the database and the
capabilities of the driver.

ODBC drivers return standard error codes and translate data types to a common
(ODBC) standard. ODBC allows the application developer to obtain integrated
database error information, and to avoid some of the most complex problems that
are involved with making applications portable.
What you can do with ODBC:
Use ODBC to:
v Send SQL requests to the database management system (DBMS).
v Use the same program to access different database management system
(DBMS) products without re-compiling.
v Create an application that is independent of the data communications
protocol.
v Handle data in a format convenient to the application.

The flexibility of Express ODBC APIs allows you to use them in transaction-based,
line-of-business applications (where the SQL is predefined). They also can use
them in query tools such as Lotus® Approach® or Microsoft® Query (where the
select statement is created at run time).

Chapter 3. Express C/C++ APIs 137


Structured Query Language (SQL):
ODBC supports dynamic SQL, which sometimes is associated with poor
performance. However, careful use of parameter markers enables repeated
statements to achieve static SQL-like performance. Also, extended dynamic
SQL–a special capability of the Client Access Express for Windows ODBC
driver–enables previously prepared SQL statements to achieve performance
that rivals static SQL.
Where to find information on SQL:
For more information on SQL, see the IBM SQL Reference book.
View an HTML online version of the book, or print a PDF version,
from the DB2 Universal Database for AS/400 books online AS/400
Information Center topic.
Express ODBC topics:
v “Express ODBC driver”
v “The ODBC interface” on page 190
v ODBC APIs
v “Express ODBC performance” on page 201
v “Express ODBC programming examples” on page 265
v “Express ODBC troubleshooting” on page 280
Where to find documentation on the ODBC standard:

See the Microsoft ODBC Web site

Express ODBC driver


Client Access Express clients feature a full-function, high-performance ODBC
driver. The following topics explain many of the driver’s capabilities. Conformance
levels establish standard sets of functionality between applications and drivers.
Conformance levels for drivers are defined in two areas: ODBC APIs and ODBC
SQL grammar.

The Client Access Express ODBC driver has the following conformance levels:
API conformance level:
Level 2
SQL grammar conformance level:
Core, with support for most Extended grammar

Note: Client Access Express ODBC driver supports ODBC version 2.5
specifications.
Express ODBC driver topics:
v “Setting up the Express ODBC driver”
v “Express ODBC driver: related information” on page 159
v “ODBC core conformance APIs” on page 194
v “ODBC level-1 conformance APIs” on page 195
v “ODBC level-2 conformance APIs” on page 196

Setting up the Express ODBC driver: By using the Client Access Express ODBC
driver, you enable your ODBC client applications to effectively share data with
each other and with the AS/400.
To set up the Express ODBC driver:
1. Add the local AS/400 system to the relational database (RDB) directory.
2. Select the Client Access ODBC driver.
3. Set up the ODBC data source.

138 Client Access Express Programming


4. Configure formatting options and performance options for the ODBC
data source.

Adding the local AS/400 system to the RDB directory: To use ODBC, the local AS/400
must appear in the RDB directory.
To add the local AS/400 system to the RDB directory:
1. From the AS/400 command prompt, send the CL command Add
Relational Database Directory Entry (ADDRDBDIRE).
2. When the ADDRDBDIRE screen prompts you for values, enter the
name of the AS/400 as the Relational Database parameter.
3. Enter *LOCAL as the Remote Location parameter.

Note: Many ODBC applications use a naming format such as


COLLECTION.TABLE. SQL/400® allows the addition of the associated
system name to the front of each table or file name (for example, SYSTEM
NAME.COLLECTION.TABLE). To use an application that provides the
system name, the ODBC driver checks the AS/400 RDB directory entry for
the local system name. To run the Client Access ODBC driver, you must add
the name of your local AS/400 system to the RDB directory.
What to do next:
Select the Client Access ODBC driver

Selecting the Client Access ODBC driver: To access data, you must select an ODBC
driver.
To select the Client Access ODBC Driver:
1. To start ODBC Administration from the Windows Taskbar, select Start
and choose Programs –> IBM AS400 Client Access Express –> ODBC
Administration.

Tip: You also can double-click the IBM AS400 Client Access Express
icon on the desktop, if you have one, and then select ODBC
Administration.

Chapter 3. Express C/C++ APIs 139


Express ODBC Data Source Administrator — User DSN dialog

2. Select the tab for the type of DSN you want. See “ODBC components”
on page 191 for an explanation of DSN types.
3. In the Data Source Administrator dialog, select Add....

Note: If you selected the User DSN or System DSN tabs, the ODBC
Administrator calls the ConfigDSN ODBC function. This
function is in the CWBSTP.DLL setup DLL.
4. In the Create New Data Source dialog, select Client Access ODBC
Driver [32-bit] from the Installed ODBC Drivers selection box.
5. Select Finish to complete the selection and to activate the Client Access
ODBC Setup [32-bit] dialog.
What to do next:
Set up the ODBC data source

Setting up the ODBC data source: You must set up the data source for your
application to access and manipulate data.
To set up the ODBC data source:
1. Enter the required information that is in the General tab of the Client
Access ODBC Setup [32-bit] dialog.

140 Client Access Express Programming


Express ODBC Setup (32-bit) dialog — General tab

Note: If you complete only the General tab, the Client Access ODBC
driver supplies default values for the information in the remaining
tabs. See “Configuring ODBC data-source options” on page 145 for
additional information.
To set up the Client Access ODBC Driver:
1. Enter a descriptive Data source name in the textbox. This is required
information that enables the Client Access ODBC driver to access
AS/400 data.

Detail: The data source name can include up to 32 characters, must


start with an alphabetic character, and cannot include the
following characters:

Unallowed data-source characters


Left bracket ([) Question mark (?)
Right bracket (]) Asterisk (*)
Left brace ({) Equal sign (=)
Right brace (}) Exclamation point (!)
Left parenthesis ( ( ) At sign (@)
Right parenthesis ( ) ) Semicolon (;)

2. Enter a Description of the data that is found in the data source. This
information is optional but useful in identifying the data source when
changing attributes at a later time.
3. Type a system name or select a previously configured AS/400 System
that contains the data source. Select the drop-down arrow to choose

Chapter 3. Express C/C++ APIs 141


another system. This is required information that enables the Client
Access ODBC driver to access AS/400 data.
4. Select the Connection Options button to display the Connection
Options dialog, in which you can configure signon and security
options.
Express ODBC Setup (32-bit) — Connection Options dialog

Note: When you select the Connection Options button, the system
name that you specified is verified. If the verification fails, an
error-message alert displays.You must enter a valid system name.
The following options can be configured:
Signon information
Specifies what default user ID to use, if any. See “ODBC
connection APIs prompting considerations” on page 143 for
additional information.
Use Windows user name and password, no prompting
Specifies to use your Windows user name and
password without any prompting every time you sign
on to the AS/400 system.
Use default user ID, prompt as needed
Specifies to use your default user ID that you must
specify in the field provided. Otherwise, you will be
prompted for the information.
Prompt every time
Specifies to prompt you for the signon information
every time you connect to this AS/400.
Use Operations Navigator default
Specifies to use the current Operations Navigator
setting.
Security
Specifies whether you want to use Secure Sockets Layer (SSL),
or use the same security as specified in the Operations
Navigator connection.

142 Client Access Express Programming


Do not use Secured Sockets Layer (SSL)
Specifies that the connection is not secured, and that
the information is not encrypted.
Use Secured Sockets Layer (SSL)
Specifies that the connection is secured by using
Secured Sockets Layer (SSL). Information is encrypted
to and from your AS/400 system.
Use same security as Operations Navigator connection
Specifies that you can use the same security as
Operations Navigator. Any security changes to
Operations Navigator will be reflected in subsequent
transfer requests.
5. Select OK to set up the Client Access ODBC data source.

Note: When you select OK, the AS/400 system verifies the names that
you specified.
What to do next:
Configure formatting and performance options for the ODBC data source

ODBC connection APIs prompting considerations: To fix potential connection


disruptions in three-tier environments, Client Access Express V4R4 - Service Pack 2
introduced options that affect the prompting behavior of the ODBC driver. The
information that follows explains how ODBC connection APIs with various
parameter options affect the ODBC keyword settings and their prompting
behaviors.

Note: If default user ID or Windows user name and password is passed as an


option to the ODBC connection API, it is used to prompt unless noted
below.

Default ODBC signon keyword settings


Setting Result
0 Use Windows user name and password, no prompting
1 Use default user ID, prompt as needed
2 Prompt every time
3 Use Operations Navigator default system settings

SQLDriverConnect with SQL_DRIVER_NOPROMPT:


User ID not passed in on API call:
The ODBC driver examines the signon setting from the connection
string, if it is available.
Signon keyword not in the connection string:
The setting from the DSN is used. This is the only option where
users are guaranteed that the driver will not prompt for user ID
and password. In addition, no error pop-ups are displayed.
No user ID specified:

Signon settings for SQLDriverConnect with SQL_DRIVER_NOPROMPT


Setting Result
0 The Windows user name and password are used.

Chapter 3. Express C/C++ APIs 143


Signon settings for SQLDriverConnect with SQL_DRIVER_NOPROMPT
Setting Result
1 The ODBC driver attempts to use the default user ID, and connects
if a valid password is available.
2 Will not prompt since the API was called with the NOPROMPT
option.
3 The Operations Navigator settings are honored, and if the user ID
and password are valid, a connection is made.

SQLDriverConnect with SQL_DRIVER_PROMPT:


The signon prompt appears if a Windows name and password combination
was not passed in, or if the user name and password that were passed in
fail to connect.
No user ID passed in:
The user ID that is used depends on the signon setting.
Signon setting set in the connection string:
The signon setting is used.
Signon keyword not in the connection string:
The setting from the DSN is used.
No user ID specified:

Signon settings for SQLDriverConnect with SQL_DRIVER_PROMPT, no user ID


specified
Setting Result
0 The Windows user name and password are used. If the connection is
successful, no prompting occurs.
1 The ODBC driver attempts to use the default user ID, and connects
if a valid password is available. If the correct information is not
available, the driver will prompt.
2 A prompt always appears.
3 The Operations Navigator settings are honored, and if the user ID
and password are valid, a connection is made.

SQLDriverConnect with SQL_DRIVER_COMPLETE or


SQL_DRIVER_COMPLETE REQUIRED:
User ID and password passed in:
The signon prompt appears only if an error occurs, and the user
indicates to retry the signon.
User ID and password not passed in:
The signon setting is retrieved from the connection string or from
the DSN.
No user ID specified:

Signon settings for SQLDriverConnect with SQL_DRIVER_PROMPT, no user ID


specified
Setting Result
0 The Windows user name and password are used. If the connection is
successful, no prompting occurs.

144 Client Access Express Programming


Signon settings for SQLDriverConnect with SQL_DRIVER_PROMPT, no user ID
specified
Setting Result
1 The ODBC driver attempts to use the default user ID, and connects
if a valid password is available. If the correct information is not
available, the driver will prompt.
2 A prompt always appears.
3 The Operations Navigator settings are honored, and if the user ID
and password are valid, a connection is made.

SQLConnect:
User ID and password passed in:
The signon prompt appears only if an error occurs, and the user
indicates to retry the signon.
User ID not passed in:
The signon setting is retrieved from the connection string, or from
the DSN.
No user ID specified:

Signon settings for SQLDriverConnect with SQL_DRIVER_PROMPT, no user ID


specified
Setting Details
0 The Windows user name and password are used. If the connection is
successful, no prompting occurs.
1 The ODBC driver attempts to use the default user ID, and connects
if a valid password is available. If the correct information is not
available, the driver will prompt.
2 A signon prompt always appears.
3 The Operations Navigator settings are honored, and if the user ID
and password are valid, a connection is made.

Configuring ODBC data-source options: After you specify General tab data-source
options, use the remaining tabs (Server, Packages, Performance, Language, Other,
Translation, and Format) to configure additional data-source options. The Client
Access Express ODBC driver supplies default values for those options that are not
changed.
Configuring ODBC data-source options topics:
v “Configuring Server options”
v “Configuring Package(s) options” on page 147
v “Configuring Performance options” on page 149
v “Configuring Language options” on page 151
v “Configuring Other options” on page 152
v “Configuring Translation options” on page 153
v “Configuring Format options” on page 154

Note: See “ODBC data-source options” on page 155 for detailed information.

Configuring Server options: The Server options tab allows you to set the default
library or libraries, the level of commitment control, and the maximum threshold
field data size.

Chapter 3. Express C/C++ APIs 145


Express ODBC Setup (32-bit) — Server dialog

To configure Server options:


1. Enter the AS/400 Default libraries that you will use during
connections to this data source. Separate names with either commas or
spaces. See Default libraries in the “Server options” on page 155 topic
for additional information.

Detail:
v To replace the current default library list or to add libraries
within an existing list, specify the complete library names.
v To add a library to the front or end of an existing user library
list, use *USRLIBL to specify the existing user library list.
Add the new libraries in the appropriate order.
Examples:
a. LIB1, LIB2, LIB3 replaces the user library list with the
three specified libraries. The default collection is LIB1.
b. , LIB1, *USRLIBL, LIB2 adds LIB1 to the front of the
user library list, adds LIB2 to the end of the list and
specifies no default collection.
2. Use the Commit mode default value, or select another Commit mode
by using the drop-down list. See Commitment control in the “Server
options” on page 155 topic for more information.
3. Specify the Maximum field data returned by selecting a value from the
drop-down list. This option allows you to specify, in kilobytes, the
threshold field length, thereby optimizing your ODBC connection to the
server. If a field is greater than this value, the information for that field
will be returned on additional calls to the AS/400 system.

146 Client Access Express Programming


4. When Search Pattern is selected (the default), underscores in the library
name are treated as wild cards (search patterns), and not as
underscores.

Configuring Package(s) options: The Package(s) options tab allows you to enable
and control implementation of extended dynamic support. See also “Configuring
Package(s) options for multiple users” on page 149.

Express ODBC Setup (32-bit) — Package(s) dialog

To configure Package(s) options:


1. Select the Enable extended dynamic (package) support check box to
enable or disable extended dynamic support. See Extended dynamic
(package) support in the “Package options” on page 156 topic for more
information.
2. Enter the name of your preferred Default package library, if you have
one.

Detail: The following options are set initially when a client ODBC
application is run for the first time after enabling extended
dynamic support. After you set these options for an application,
you may change them at any time by using the Client Access
Express ODBC Setup [32-bit] dialog.
3. Select the Application name for which you want to customize the
package options. Select the down arrow to select from available
applications.

Detail: Selecting an application name enables the remaining options on


the Package(s) options tab.

Chapter 3. Express C/C++ APIs 147


4. Type the AS/400 library in which the Package library for the selected
application resides or will be created. This information is optional
except when configuring shared packages.

Detail: Selecting a package library for a particular application will


override the default package library setting.
5. Enter a Package name for the package for the selected application. This
information is optional.

Detail: The package name is limited to seven characters. The ODBC


driver adds a three-character suffix to the package name.
6. Select Clear package if package size is: and specify the maximum
number of stored SQL statements. When the number of statements in
the package exceeds the specified limit, the package is cleared. The
value range is 1 - 9999. The default value is 512. If a value is entered
but the check box is not selected, the package will become read-only
when it reaches its limit.

Note: There is a physical size limit to the SQL package: The maximum
number of stored statements might actually be less than 9999,
depending on the complexity of the stored SQL statements. The
physical size of an SQL package cannot exceed approximately
15MB.
7. Select Cache package locally if you want to cache a copy of the SQL
package on your PC. By caching the package locally, you can improve
performance for some applications. See Local package caching in the
“Package options” on page 156 topic for more information.
8. Select a Package usage option to specify how the ODBC driver uses the
package for this application. Select from the following options:
Disable
The ODBC driver will not use a package for this application.
Use The ODBC driver uses an existing package in read-only mode.
Use/Add
The ODBC driver uses an existing package (or creates a
package if one does not exist), adds new statements to the
package, and reuses existing statements.
9. Select an Unusable package option to specify the kind of return code
and message that are returned by the ODBC driver when the package
is not usable:
Error The ODBC driver returns an error when a package is unusable.
Warning
The ODBC driver returns a warning when a package is
unusable.
Ignore The ODBC driver does not return a message when a package is
unusable.

Note: If the package is unusable and Warning or Ignore options are


selected, the statement is prepared without using the package.
To configure Package(s) options for multiple users:
See “Configuring Package(s) options for multiple users” on page 149

148 Client Access Express Programming


Configuring Package(s) options for multiple users: The administrator can set up an
application that uses a fixed number of SQL statements to have a single package
that all users effectively share without contention. See Private and shared
packages in the “Package options” on page 156 topic for additional information.
To configure Package(s) options for multiple users:
1. Use the Client Access ODBC Administrator to set up and configure the
data source. See “Setting up the ODBC data source” on page 140 and
“Configuring ODBC data-source options” on page 145 for instructions.
2. Run the client application. The ODBC driver creates the package, if a
package does not already exist.
3. Start the ODBC Administrator. See “Selecting the Client Access ODBC
driver” on page 139 for instructions.
4. From the Package(s) tab of the Client Access ODBC Setup [32-bit]
dialog, select Use/Add under the Package Usage option.
5. Use the client application to add the desired SQL statements to the
package, then exit the application.
6. From the Package(s) tab of the Client Access ODBC Setup [32-bit]
dialog, select Use under Package Usage. This will ensure that the
ODBC driver uses the existing package in read-only mode.
7. Configure identical Package(s) options for each user of the shared
package.

Detail: Be sure to select the same Application name, enter the same
Package library and Package name and select Use under
Package Usage.

Configuring Performance options: The Performance tab allows you to set ODBC
options for the AS/400 database server that can enhance the performance of ODBC
applications.

Chapter 3. Express C/C++ APIs 149


Express ODBC Setup (32-bit) — Performance dialog

To configure Performance options:


1. Select Enable lazy close support to enable or disable this option.

Detail: Enabling lazy close support delays transmission of an


SQLFreeStmt with the SQL_CLOSE option to the AS/400 until
the client application sends the next request. This enhances
AS/400 performance. When lazy close support is disabled, an
SQLFreeStmt with the SQL_CLOSE option causes an explicit
flow to the AS/400 to close the statement. See Lazy close
support in the “Performance options” on page 158 topic for
additional information.
2. Select Enable pre-fetch during EXECUTE to enable or disable this
option.

Detail: Leave this option unchecked if your application uses SQL


ExtendedFetch or if you are unsure. See Pre-fetch during
EXECUTE in the “Performance options” on page 158 topic for
more information.
3. The Enable data compression option enables you to compress data that
is received from the host.
4. Select the Type of record blocking under which the driver retrieves
multiple rows of data from the AS/400 system. Select the down arrow
to select a different setting.

Detail: The types of record blocking available are:


v Record blocking is disabled.

150 Client Access Express Programming


v Record blocking enabled only for SELECT statements that end with
an explicit ″FOR FETCH ONLY″ clause.
v Record blocking enabled for everything except SELECT statements
containing a ″FOR UPDATE OF″ clause.
5. Select the Size in kilobytes of the block of rows that is used when
record blocking is enabled. Select the down arrow to select a different
size.

Detail: Size is measured in kilobytes (1 kilobyte = 1024 bytes). The


block size is divided by the size of one row of data to
determine the maximum number of rows that can be retrieved
in one request.
6. Select an OS/400 library view to specify the set of libraries that is
searched when the SQLTables function returns a list of table owners.

Detail: In general, this option should be left at the default setting. See
OS/400 library view in the “Performance options” on page 158
topic for more information.

Configuring Language options: The Language tab allows you to set options for the
ODBC driver that affects certain types of sorting and matching that are based on
language.

Express ODBC Setup (32-bit) — Language dialog

To configure Language options:


1. Select whether the Sort type (sort sequence) is based on hexadecimal
value, job profile, language ID, or sort sequence table. Select the down
arrow to specify a new sort type.
Details:
a. Job profile is not supported in the current release and, if chosen, is
treated as hexadecimal.

Chapter 3. Express C/C++ APIs 151


b. Select Sort based on language ID to enable the Sort weight and
Language ID options.
c. Select Sort based on specified table to enable the Sort
Library/Table Name text box.
2. Enter the Sort Library/Table Name (library and file names) of a sort
sequence table on an AS/400 to be used as the sort sequence.
3. Select one of the following Sort Weight options:
Shared-Weight
Sort uppercase and lowercase representations of each letter as
the same letter.
Unique-Weight
Sort uppercase and lowercase representations of each letter as
unique letters.
4. Select the Language ID that is used to assign a sorting sequence. Select
the down arrow to specify a different language.
5. Select Allow Unsupported Character to suppress error messages that
occur when characters that cannot be translated (Unsupported) are
detected.

Configuring Other options: The Other options tab allows you to select the type of
connection, type of object description, and cursor preferences.

Express ODBC Setup (32–bit) — Other dialog

To configure Other options:


1. Select the preferred Connection type. The default selection is
Read/Write.

152 Client Access Express Programming


2. Select the preferred Object description type to determine the type of
value you want ODBC catalog APIs to return in the REMARKS column.
3. Select one of the following Scrollable cursor options to enable or
disable scrollable cursors when the rowset size is 1:
Scrollable unless rowset size is 1
Cursors with a rowset size of 1 are not scrollable.
Always scrollable
Cursors are always scrollable.

Detail: Scrollable cursors enable the ability to scroll forward and


backward in a result set. With scrollable cursors, if you fetch
two rows of data, you can view row 1, row 2, and then scroll
back to view row 1 again. With a forward-only cursor, if you
viewed row 1, and then viewed row 2, you could not scroll
back to view row 1: you would be required to perform another
data fetch.

Some client applications expect that the cursors they use are
scrollable, but the AS/400 normally treats a cursor with a
rowset size of 1 as non-scrollable. Select Always scrollable to
force all cursors, including those with a rowset size of 1, to be
scrollable. This applies only to SQLExtendedFetch.

Configuring Translation options: The Translation options affect how the AS/400 and
the ODBC driver translate data.

Express ODBC Setup (32-bit) — Translation dialog

To configure Translation options:

Chapter 3. Express C/C++ APIs 153


1. Select a Translation option to enable or disable the translation of data
that is stored in columns on the AS/400 system with an explicit coded
character set identifier (CCSID) of 65535. The default is Do not
translate CCSID 65535. See “Translation options” on page 158 for
additional information.
2. Enter a Translation DLL filename for the ODBC driver to use. This
information is optional because the ODBC driver handles all normal
character and numeric conversions. See “Translation options” on
page 158 for more information.

Tip: Select Browse to locate an ODBC translation DLL.


3. Specify the Translation Option that is passed to the translation DLL.
This information is optional and is dependent on the translation DLL.
See “Translation options” on page 158 for more information. Select
Configure to configure the Translation option that you specified.
4. In the CCSID box, specify the CCSID number that should override the
current client ANSI code page. Type in the appropriate CCSID. If left
blank, this option is ignored.

Configuring Format options: The Format options determine certain types of


formatting that are used for AS/400 database server data.

Express ODBC Setup (32-bit) — Format dialog

To configure Format options:


1. Select the Naming convention. Select the down arrow to specify a
different convention.

Details: The different naming conventions are:

154 Client Access Express Programming


SQL The SQL naming convention, which uses a period (.) between
the collection name and table name. This is the default.
SYS The SYS naming convention, which uses a forward slash (/)
between the library and file names.
2. Select the Decimal separator — period (.) or comma (,) — that your
AS/400 system supports. The default is a period. Select the down
arrow to specify a different separator.
3. Under the Time option, select the Format that the ODBC driver uses to
transfer time data to and from the AS/400 system. The default is
hour:minute:second (hh:mm:ss). Select the down arrow to specify a
different format.

Detail: This option tells the SQL/400 parser how to interpret time data
that is embedded as a constant within an SQL statement.
4. Under the Time option, select the Separator for the hh:mm:ss (*HMS)
time format. This setting is disabled when the time format is anything
but *HMS.
5. Under the Date option, select the Format that the ODBC driver uses to
transfer date data to and from the AS/400 system. The default is
yyyy-mm-dd. Select the down arrow to specify a different setting.

Detail: This option directs the SQL/400 parser how to interpret date
data that is embedded as a constant within an SQL statement.
6. Under the Date option, select the Separator for the following date
formats: mm/dd/yy (*MDY), dd/mm/yy (*DMY), and yy/mm/dd
(*YMD). Select the down arrow to specify a different setting.

ODBC data-source options: The following formatting and performance options


topics are not comprehensive. The explanations are provided only to help you set
up the data source.
v “Server options”
v “Package options” on page 156
v “Performance options” on page 158
v “Translation options” on page 158

Server options:
Default libraries:
A library list has three portions: a system portion, a current library
(designated in the user’s AS/400 profile) and a user portion. The Default
libraries option changes only the user portion.
Specify only the libraries that you need to access. Returning information
for all the AS/400 libraries during a catalog request is unnecessary and
decreases performance.
The first library that is listed is the default collection. If you do not want a
default collection, start the library list with a comma.
When using the *SQL naming convention, the default collection is normally
the only collection that is used to satisfy unqualified table names in an
SQL collection. For example, SELECT * FROM MYTABLE is treated as
SELECT * FROM default_collection.MYTABLE. If no default collection is
specified, the library with the same name as the user profile of the ODBC
job is used for unqualified table names. The request will fail if the library
does not exist.

Chapter 3. Express C/C++ APIs 155


When using the *SYS naming convention, the unqualified SQL statements
will go first to the default collection, if there is one. If there is no default
collection, the current library is used; if there is no current library, the
library list is used.
If there is no default collection and no current library, the CREATE TABLE
request will create the table in library QGPL. Catalog requests for both
naming conventions use the default collection, the current library, and the
library list.
Two libraries that do not appear on the Server options tab are always
added to the default libraries list. ODBC adds the library QIWS to include
the ODBC server code in the library path. ODBC also adds the current
library (from the AS/400 user profile), which appears as a data source
choice in your client application. Do not add these two libraries to the
library list. This may generate an error when a connection is attempted.
Commitment control:
Commitment control is a means of processing separate jobs as a single unit
of work. A job is an application process that can include the processing of
one or more SQL programs. A unit of work is a recoverable sequence of
operations.
The ODBC default for SQL_AUTOCOMMIT is SQL_AUTOCOMMIT_ON,
effectively disabling all commitment control. Unless the application sets the
mode to SQL_AUTOCOMMIT_OFF, this setting will have no affect. Also,
the application can override this setting by way of the application
programming interface (API).
The commit modes available are:
Commit immediate (*NONE):
Specifies that commitment control is not used. Calls to the
SQLTransact API are ignored. Uncommitted changes in other jobs
can be seen. If the SQL DROP COLLECTION statement is included
in the program, *NONE must be used. When a relational database
that is specified on the RDB parameter is on a non-AS/400 system,
*NONE cannot be specified.
Read committed (*CS):
Specifies the objects referred to in SQL COMMENT ON, CREATE,
DROP, GRANT, LABEL ON, and REVOKE statements. Rows that
are updated, deleted and inserted are locked until the end of the
transaction. A row that is selected but not updated is locked until
the next row is selected. Uncommitted changes in other jobs cannot
be seen.
Read uncommitted (*CHG):
Specifies the objects referred to in SQL COMMENT ON, CREATE,
DROP, GRANT, LABEL ON and REVOKE statements. Rows that
are updated, deleted and inserted are locked until the end of the
transaction. Uncommitted changes in other jobs can be seen.
Repeatable read (*ALL):
Specifies the objects referred to in SQL COMMENT ON, CREATE,
DROP, GRANT, LABEL ON, and REVOKE statements. Rows that
are updated, deleted and inserted are locked until the end of the
transaction. Uncommitted changes in other jobs cannot be seen.

Package options:

156 Client Access Express Programming


Extended dynamic (package) support:
Extended dynamic (package) support is a way to store prepared dynamic
SQL statements on the AS/400 server. After enabling extended dynamic
support, the first time an ODBC application runs an SQL statement,
information about the statement is saved in an SQL package object
(package).
The package is saved in a default library on the AS/400 server. On
subsequent uses of the statement, the database management system
(DBMS) recognizes that the statement has been run before. The DBMS then
uses the information that has been saved in the package to skip a
significant part of the processing.
All statements that contain parameter markers can be stored in a package.
The following statements are stored in the package, even if they do not
contain parameter markers:
v INSERT with subselect
v DECLARE PROCEDURE
Local package caching:
When you cache the package locally, a copy of relevant information that is
retrieved from the SQL package on the host is kept locally on the PC. Any
application that benefits from extended dynamic support benefits from
local package caching.
Applications that use parameter markers and re-execute statements with
SQLExecDirect (instead of SQLPrepare followed by multiple calls to
SQLExecute) may experience a significant improvement. Use extended
dynamic, and possibly avoid preparing an SQL statement that uses
SQLPrepare or SQLExecDirect.

Note: This option is recommended only for relatively small packages,


because the PC must allocate memory for the cache. Select this
option based on the amount of memory in your PC.
Private and shared packages:
Users who generate different SQL statements for changing tasks in a
particular application should use a private (non-shared) package for that
application. Using a private package prevents the package from being
locked and ensures that only the desired statements are added to the
package. A private package requires that the user’s package library name
or the first seven characters of the package name be unique.
Multiple users can add to or use a given non-shared package at the same
time. However, adding a new statement to the package locks the entire
package, which can cause contention between users. This reduces the
benefits of using extended dynamic support.
All users who share a package must use the same default library. If the
default library for a data source does not match the default library when
the package was created, the package cannot be used. In this case, the
warning, or error, message ″Extended dynamic support disabled″ will be
returned to the application.
The administrator can set up an application that uses a fixed number of
SQL statements to have a single package that all users effectively share
without contention. See “Configuring Package(s) options for multiple
users” on page 149 for instructions on how to set up multiple users with a
shared package.

Chapter 3. Express C/C++ APIs 157


Performance options:
Lazy close support:
To enable lazy close support delays transmission of an SQLFreeStmt with
the SQL_CLOSE option to the AS/400 until the client application sends the
next request. This enhances AS/400 performance. When lazy close support
is disabled, an SQLFreeStmt with the SQL_CLOSE option causes an
explicit flow to the AS/400 to close the statement.
Pre-fetch during EXECUTE:
When pre-fetch during EXECUTE is enabled, open and fetch operations are
combined when a SELECT statement is processed. Combining the
operations allows a fetch of the first block of data in advance, before the
application requests it. This ″pre-fetch″ reduces the amount of
communication between the client and the server.
OS/400 library view:
This option is used only when calling the special case usage of the
SQLTables function with parameters that request a list of table owners
(libraries), not tables.
To select Default library list returns the libraries in that list. This is the
preferred setting for maximum performance. The default library list is set
with the Default libraries option on the Server options tab.
Selecting All libraries on the system potentially can return a significant
number of libraries on a large system, with a corresponding performance
reduction.
It is important to note that this is a special case usage of the SQLTables
API. The normal use of SQLTables (to get lists of tables) and all other
ODBC catalog functions are unaffected by this setting.
Following are the parameters for the special case usage of the SQLTables
function:
szTableQualifier = "" (empty string)
cbTableQualifier = SQL_NTS
szTableOwner = %
cbTableOwner = SQL_NTS
szTableName = "" (empty string)
cbTableName = SQL_NTS
szTableType = NULL
cbTableType = 0

Translation options:
CCSID 65535 translation:
The coded character set identifier (CCSID) is a 2-byte binary (hexadecimal)
identifier. The AS/400 identifies the CCSID in which character data is
coded for each column in a database.
The CCSID of a field determines which conversion table is required for
converting the data, for example, from EBCDIC to ASCII. A CCSID of
65535 often identifies raw data, such as bitmapped graphics.
Selecting Translate CCSID 65535 allows translation of CCSID 65535 data to
the same CCSID of the job. Choosing this option may cause translation of
data that is meant to remain untranslated. The administrator should set
these options for users.
Translation DLL:
This option specifies the translation Dynamic Link Library (DLL) that is
used to translate the data that is passed between the ODBC driver and the

158 Client Access Express Programming


data source. Frequently, the application and data source store data in
different character sets. ODBC provides a generic mechanism that allows
the driver to translate data from one character set to another. It consists of
a DLL that implements the translation functions SQLDriverToDataSource
and SQLDataSourceToDriver.
Translation DLLs are provided by application developers, driver
developers and third parties. The Client Access ODBC driver normally
does any necessary data translations, but a translation DLL may be useful
for some cases, such as right-to-left or bi-directional languages.
After a translation DLL has been specified, the driver loads it and calls it
to translate all data that flows between the application and data source.
This includes all SQL statements and character parameters that are sent to
the data source, character results, character metadata such as column
names, and error messages that are retrieved from the data source.

Note: Connection data is not translated. The translation DLL is not loaded
until after the application has connected to the data source.
Translation option:
Translation option specifies a 32-bit integer translation option that is passed
to the translation DLL. The translation DLL determines the meaning of this
option. Refer to the documentation that is provided with the translation
DLL for more information. This parameter is optional.

Express ODBC driver: related information: See the following topics for ODBC
driver-related information:
v “ODBC connection strings and keywords”
v “Using large objects (LOBs) and DataLinks with Express ODBC” on page 216
v “ODBC-to-AS/400 data mapping” on page 163
v “SQL statements, grammar and limitations” on page 164
v “Client Access ODBC error messages” on page 165
v “Sample: ODBC trace” on page 165
v “Enabling table and file updates” on page 182
v “Express ODBC security” on page 185
v “Client Access ODBC APIs implementation issues and requirements” on
page 200

ODBC connection strings and keywords: Connection strings consist of a series


keywords and their values, in the following format:
KEYWORD=Value;KEYWORD=Value;KEYWORD=Value

Use connection strings with SQLDriverConnect to provide additional information.


User DSN and System DSN keywords:
The keywords that the CA/400 driver stores in the registry for User DSNs
and System DSNs do not match the keywords in this topic. User DSN and
System DSN keywords have an associated long-named keyword. For
example, if you specify CMT on the connection string, it is stored in the
registry as Commit Mode. For a full list of these keywords, call
SQLBrowseConnect and specify the following input string:
DSN=my_DSN; input string

SQLBrowseConnect returns an output string that contains every possible


keyword in the following format:
keyword_short_name:keyword_long_name=?;

Chapter 3. Express C/C++ APIs 159


File DSNs store information by using the keywords that follow.
To view an example that uses a connection string:
See “Example: Connection string” on page 163
Keywords to use with the CA/400 driver:
BLOCKSIZE
Block size for fetch (in kilobytes). Possible values are:
1
2
4
8
16
32
64
128
256
512
CCSID
The CCSID number that should override the current client ANSI
code page.
CMT Commit mode (optional). Possible values are:
0 - Commit Immediate (*NONE)
1 - Read Committed (*CS)
2 - Read Uncommitted (*CHG)
3 - Repeatable Read (*ALL)
COMPRESSION
Data compression (optional). Possible values are:
0 - Not set
1 - Set
CONNTYPE
Connection type. Possible values are:
0 - Read/write (all SQL statements allowed)
1 - Read/Call (Select and Call statements allowed)
2 - Read-Only (Select statements only)
DBQ User-specified default library (optional).
DEC Decimal separator format (optional). Possible values are:
0 - . (period)
1 - , (comma)
DFT Date format (optional). Possible values are:
0 - yy/dd (*JUL)
1 - mm/dd/yy (*MDY)
2 - dd/mm/yy (*DMY)
3 - yy/mm/dd (*YMD)
4 - mm/dd/yyyy (*USA)
5 - yyyy-mm-dd (ISO)
6 - dd.mm.yyyy (*EUR)
7 - yyyy-mm-dd (*JIS)
DFTPKGLIB
Default package library
DRIVER
This must be used in combination with the SYSTEM keyword for
this to work. The only possible value for this keyword is:
Client Access ODBC Driver (32-bit)
DSN Data source name
DSP Date separator (optional). Possible values are:

160 Client Access Express Programming


0 - / (forward slash)
1 - - (dash)
2 - . (period)
3 - , (comma)
4 - (blank)
EXTTYPE
Possible options are:
0 - Not set
1 - Return AS/400 database types as unique ODBC-defined types
Base ODBC-defined types:
Data types that are documented in the ODBC
specifications. The ODBC driver uses these data types
internally when performing data type conversions.
Unique ODBC-defined types:
Data types other than those which are documented in the
ODBC specifications.

The following formula shows how to convert between the unique


ODBC-defined type and the base ODBC-defined type:
if (received type is > -93) and (received type < -80)
{
received base type = absolute value of (received type +80);
}
else
{
if (received type > -97) and (received type < -92)
{
received base type = received type + 92;
}
else
{
received base type = received type;
}
}

For example, BLOBs have a unique ODBC-defined type of -96, but


have a base ODBC-defined type of -4 (SQL_LONGVARBINARY).
LANGUAGEID
Language ID for sort. Possible values are:
ENU - English US
JPN - Japanese Katakana
(and so forth)
LAZYCLOSE
Enable lazy close support. Possible values are:
0 - Disable lazy close
1 - Enable lazy close
LIBVIEW
OS/400® library view. Possible values are:
0 - Use default library list
1 - All libraries on the system
MAXFIELDLEN
Maximum amount of data allowed in a field (in kilobytes). Any
number greater than 0 is valid, but 32, 64, 128, and so on (up to
16384) are options predefined in the list box. You also may enter a
value.
NAM Naming convention (optional).
0 - SQL naming convention, in which there is a period (.) between the collection and table names.
1 - AS/400 system naming convention, in which there is a slash (/) between the collection and table names.

Chapter 3. Express C/C++ APIs 161


PREFETCH
Enable pre-fetch during EXECUTE. Possible values are:
0 - No
1 - Yes
PWD User-specified password (optional)
RECBLOCK
Record blocking. Possible values are:
0 - Disable record blocking
1 - Block if FOR FETCH ONLY specified
2 - Block except FOR UPDATE OF specified
REMARKS
Object description type. Possible values are:
0 - OS/400 object description
1 - SQL object comment
SCROLLABLE
Scrollable cursor. Possible values are:
0 - Scrollable unless row size is 1
1 - Always scrollable
SEARCHPATTERN
Possible options are:
0 - Not set
1 - Treat underscores in the library and table names as wildcards (search patterns) a
SIGNON
Signon information.Possible values are:
0 - User Windows user name and password, no prompting
1 - Use default user ID, prompt as needed
2 - Prompt every time
3 - Use Operations Navigator default system settings

See “ODBC connection APIs prompting considerations” on


page 143 for more information.
SORTTABLE
Library/table name of sort table
SORTTYPE
Sort type. Possible values are:
0 - Sort based on hex values
1 - Sort based on job profile
2 - Sort based on language ID
3 - Sort based on specified table
SORTWEIGHT
Sort weight. Possible values are:
0 - Shared-weight
1 - Unique-weight
SSL Secure Sockets Layer. Possible values are:
0 - Do not use Secured Sockets Layer
1 - Use Secured Sockets Layer
2 - Use same security as Operations Navigator connection
SYSTEM
System name as configured for Client Access Express
TFT Time format (optional). Possible values are:
0 - hh:mm:ss (*HMS)
1 - hh.mm AM/PM (*USA)
2 - hh.mm.ss (*ISO)
3 - hh.mm.ss (*EUR)
4 - hh:mm:ss (*JIS)
TRANSLATE
Translate CCSID 65535. Possible values are:

162 Client Access Express Programming


0 - Do not translate CCSID 65535
1 - Translate CCSID 65535
TSP Time separator (optional). Possible values are:
0 - : (colon)
1 - . (period)
2 - , (comma)
3 - (blank)
UID User ID for AS/400 (optional)
XDYNAMIC
Enable Extended Dynamic Support. Possible values are:
0 - No
1 - Yes
XLATEDLL
Translation DLL name. Example:
C:\LANGUAGE\BIDI.DLL

where BIDI.DLL is provided by other vendors


XLATEOPT
Translation DLL option. Passed to and values defined by the
translation DLL.

Example: Connection string: The following is an example of a connection string:


DSN=Travel;UID=Bruce;PWD=Parrot;DBQ=Testlib;RECBLOCK=1;BLOCKSIZE=256;
NAM=1;DFT=4;DSP=0;TFT=1;TSP=0;DEC=0

Use connection strings to set defaults for the connection to a data source through
SQLDriverConnect. As an example, the user ID and password for connection to
the data source can be supplied here. They override the user ID and password that
are supplied as part of the Client Access logon procedure, and provide greater or
less authority as required.

ODBC-to-AS/400 data mapping: The table below shows the default data-type
mapping that the Client Access ODBC driver provides. Refer to this table when
you code the SQLBindParameter function. It helps you understand more clearly
how data—particularly numeric and date/time types—are represented in the PC
program and in the database.
Table 2. ODBC-to-AS/400 data mapping
SQL data type DB2 UDB for AS/400 SQL data type
SQL_BINARY CHAR FOR BIT DATA
SQL_CHAR CHAR or DATALINK or UDT
SQL_DATE DATE
SQL_DECIMAL PACKED DECIMAL
SQL_DOUBLE FLOAT (8 byte)
SQL_FLOAT FLOAT (8 byte)
SQL_INTEGER LARGE INTEGER
SQL_LONGVARBINARY CHAR FOR BIT DATA or BLOB
SQL_LONGVARCHAR VARCHAR or CLOB or DBCLOB
SQL_NUMERIC ZONED DECIMAL
SQL_REAL FLOAT (4 byte)
SQL_SMALLINT SMALL INTEGER
SQL_TIME TIME

Chapter 3. Express C/C++ APIs 163


Table 2. ODBC-to-AS/400 data mapping (continued)
SQL data type DB2 UDB for AS/400 SQL data type
SQL_TIMESTAMP TIMESTAMP
SQL_VARBINARY VARCHAR FOR BIT DATA
SQL_VARCHAR VARCHAR

Note: All conversions in the Microsoft ODBC Software Development Kit and
Programmer’s Reference, Version 3.0 ISBN 1-57231-516-4. are supported for
these ODBC SQL data types.
For more information:
See the DB2 Universal Database for AS/400 topic in the Information
Center.

SQL statements, grammar and limitations: The Client Access Express ODBC Driver
supports core SQL grammar, as well as SQL statements that are supported by
AS/400 SQL and most extended-grammar SQL statements.

The same limitations that exist with DB2 Universal Database for AS/400 are
imposed on the ODBC SQL grammar. The SQL Reference book contains additional
information. To view an HTML online version of the book, or print a PDF version,
link to the DB2 Universal Database for AS/400 books online topic in the AS/400
Information Center.
SQL statements, grammar and limitations topics:
v “Unsupported ODBC SQL grammar”
v “Implementation of the ODBC SQL grammar”

Unsupported ODBC SQL grammar: The Client Access Express ODBC Driver
supports SQL statements and clauses in both the core and extended ODBC
grammars, except for the following statements:
Integrity Enhancement Facility (IEF):
The CASCADE and RESTRICT clauses in the DROP TABLE, DROP VIEW,
and REVOKE statements are not supported.
The DEFAULT, REFERENCES CHECK, UNIQUE, PRIMARY KEY and
FOREIGN KEY clauses in the CREATE TABLE statement are not
supported. The REFERENCES clause in the GRANT statement is not
supported.

Implementation of the ODBC SQL grammar: Whenever the table name is not
qualified, the Client Access ODBC Driver uses the library list. Name the default
library either by specifying the DBQ parameter if SQLDriverConnect API or
SQLBrowseConnect APIs are called, or by setting it in the Client Access ODBC
Driver Setup dialog box.

Libraries can be added to the current server job’s library list, or they can replace
the list entirely. To replace the list, specify a list of library names. To add to the
existing list, add a special entry, *USRLIBL, to the list of libraries. All libraries
listed before *USRLIBL are added to the front of the library list. All libraries listed
after *USRLIBL are added to the end of the list. The first library in the list is used
as the default collection. If you do not want a default collection, start the list with
a comma.

For example:

164 Client Access Express Programming


DefaultLibraries=LIB1 LIB2 LIB3 ;

replaces the server job’s library list with the three libraries specified. The default
collection is LIB1. However,
DefaultLibraries=LIB1, *USRLIBL, LIB2 ;

adds LIB1 to the front of the server job’s library list and add LIB2 to the end of the
list. The default collection is LIB1.

Client Access ODBC error messages: When an error occurs, the Client Access ODBC
Driver returns the SQLSTATE (an ODBC error code) and an error message. The
driver obtains this information both from errors that are detected by the driver and
from errors that are returned by the AS/400 DBMS.

For errors that occur in the data source, the Client Access ODBC Driver maps the
returned native error to the appropriate SQLSTATE. When both the Client Access
ODBC Driver and the Microsoft Driver Manager detect an error, they generate the
appropriate SQLSTATE. The Client Access Express ODBC Driver returns an error
message based on the message returned by the AS/400 DBMS.

For errors that occur in the Client Access 400® ODBC Driver or the Microsoft
Driver Manager, the Client Access ODBC Driver returns an error message based on
the text associated with the SQLSTATE.

Error messages have the following format:


[vendor][ODBC-component][data-source]
error-message

The prefixes in brackets ([]) identify the source of the error. The following table
shows the values of these prefixes returned by the Client Access ODBC Driver.

When the error occurs in the data source, the [vendor] and [ODBC-component]
prefixes identify the vendor and name of the ODBC component that received the
error from the data source.
Table 3. ODBC Error Messages
Error Source Prefix Value
Driver Manager [vendor] [Microsoft]
[ODBC-component] [ODBC Driver Manager]
[data-source] [N/A]
Client Access [vendor] [IBM]
Express ODBC [ODBC-component] [Client Access Express ODBC Driver (32-bit)]
Driver (32–bit) [data-source] N/A
AS/400 DBMS1 [vendor] [IBM]
[ODBC-component] [Client Access Express ODBC Driver (32-bit)]
[data-source] [DB2 UDB for AS/400][Host message:]

1
See “Communication errors” on page 283 for detailed information.

Sample: ODBC trace: The following is the SQL.LOG (trace) of an ODBC connection
to an AS/400 data source. This record was generated by using the tracing facility
of Microsoft ODBC Administrator. It records a sample ODBC conversation from
Microsoft Query. See “Collecting an SQL.LOG (ODBC Trace)” on page 288 for more
information.

Chapter 3. Express C/C++ APIs 165


Note: Comments enclosed in asterisks (***) describe what is occurring with the
ODBC API calls that immediately follow. Some details of multiple calls to
the same ODBC API were removed to reduce length.
***SQLAllocEnv is used to make a request for an environment handle.***

MSQRY32 ba:c0 ENTER SQLAllocEnv


HENV * 0x004b0400

MSQRY32 ba:c0 EXIT SQLAllocEnv with return code 0 (SQL_SUCCESS)


HENV * 0x004b0400 ( 0x008308b0)

***SQLAllocConnect is used to make a request for a connection handle.***

MSQRY32 ba:c0 ENTER SQLAllocConnect


HENV 0x008308b0
HDBC * 0x0003f02c

MSQRY32 ba:c0 EXIT SQLAllocConnect with return code 0 (SQL_SUCCESS)


HENV 0x008308b0
HDBC * 0x0003f02c ( 0x00830ac0)

***SQLSetConnectOption is used to attempt to set a login timeout value. The Client Access Express
ODBC driver does not support this, but it will be noticed that an error is not returned on this until
SQLDriverConnect is called.***

MSQRY32 ba:c0 ENTER SQLSetConnectOption


HDBC 0x00830ac0
UWORD 103 <SQL_LOGIN_TIMEOUT>
UDWORD 45

MSQRY32 ba:c0 EXIT SQLSetConnectOption with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 103 <SQL_LOGIN_TIMEOUT>
UDWORD 45

***SQLDriverConnectW is used to connect to the Client Access Express ODBC driver. The return code is
SQL_SUCCESS_WITH_INFO because the driver connected successfully but does not support the
SQLSetConnectOption for SQL_LOGIN_TIMEOUT.***

MSQRY32 ba:c0 ENTER SQLDriverConnectW


HDBC 0x00830ac0
HWND 0x00290528
WCHAR * 0x64067284 [ -3] "******\ 0"
SWORD -3
WCHAR * 0x64067284
SWORD -3
SWORD * 0x00000000
UWORD 1 <SQL_DRIVER_COMPLETE>
MSQRY32 ba:c0 EXIT SQLDriverConnectW with return code 1 (SQL_SUCCESS_WITH_INFO)
HDBC 0x00830ac0
HWND 0x00290528
WCHAR * 0x64067284 [ -3] "******\ 0"
SWORD -3
WCHAR * 0x64067284
SWORD -3
SWORD * 0x00000000
UWORD 1 <SQL_DRIVER_COMPLETE>
DIAG [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr failed (0)

DIAG [IM006] [Microsoft][ODBC Driver Manager] Driver's SQLSetConnectAttr failed (0)

***SQLGetInfo is used to request specific driver information.***

MSQRY32 ba:c0 ENTER SQLGetInfo


HDBC 0x00830ac0
UWORD 2 <SQL_DATA_SOURCE_NAME>

166 Client Access Express Programming


PTR 0x0003eb54
SWORD 1024
SWORD * 0x0003f02a

MSQRY32 ba:c0 ENTER SQLGetInfoW


HDBC 0x00830ac0
UWORD 2 <SQL_DATA_SOURCE_NAME>
PTR 0x008224f0
SWORD 2048
SWORD * 0x0003f02a

MSQRY32 ba:c0 EXIT SQLGetInfoW with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 2 <SQL_DATA_SOURCE_NAME>
PTR 0x008224f0
SWORD 2048
SWORD * 0x0003f02a (0)

MSQRY32 ba:c0 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 2 <SQL_DATA_SOURCE_NAME>
PTR 0x0003eb54
SWORD 1024
SWORD * 0x0003f02a (0)

***SQLAllocStmt is used to request an instruction handle.***

MSQRY32 ba:c0 ENTER SQLAllocStmt


HDBC 0x00830ac0
HSTMT * 0x0003f024

MSQRY32 ba:c0 EXIT SQLAllocStmt with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
HSTMT * 0x0003f024 ( 0x00823420)

MSQRY32 ba:c0 ENTER SQLGetInfo


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0003efe8
SWORD 2
SWORD * 0x00000000

MSQRY32 ba:c0 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0003efe8 (0)
SWORD 2
SWORD * 0x00000000

***SQLTablesW is used to retrieve information on the list of catalog names stored in a specific da

MSQRY32 ba:c0 ENTER SQLTablesW


HSTMT 0x00823420
WCHAR * 0x008398c0 [ -3] "%"
SWORD -3
WCHAR * 0x008398d0
SWORD 0
WCHAR * 0x008398e0
SWORD 0
WCHAR * 0x008398f0
SWORD 0

MSQRY32 ba:c0 EXIT SQLTablesW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
WCHAR * 0x008398c0 [ -3] "%"
SWORD -3

Chapter 3. Express C/C++ APIs 167


WCHAR * 0x008398d0
SWORD 0
WCHAR * 0x008398e0
SWORD 0
WCHAR * 0x008398f0
SWORD 0

***SQLBindCol is used to allocate memory for a retrieved column.***

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65
SDWORD * 0x0003e6e0

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65
SDWORD * 0x0003e6e0 (8519680)

***SQLFetch is used to retrieve a row from the result set of a query.***

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

***SQLFreeStmt is used to close any conversations on a particular statement handle.***

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLGetInfo


HDBC 0x00830ac0
UWORD 32 <SQL_MAX_SCHEMA_NAME_LEN>
PTR 0x0003e6fc
SWORD 2
SWORD * 0x0003e6f2

MSQRY32 ba:c0 ENTER SQLGetInfoW


HDBC 0x00830ac0
UWORD 32 <SQL_MAX_SCHEMA_NAME_LEN>

168 Client Access Express Programming


PTR 0x0003e6fc
SWORD 2
SWORD * 0x0003e6f2

MSQRY32 ba:c0 EXIT SQLGetInfoW with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 32 <SQL_MAX_SCHEMA_NAME_LEN>
PTR 0x0003e6fc (10)
SWORD 2
SWORD * 0x0003e6f2 (2)

MSQRY32 ba:c0 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 32 <SQL_MAX_SCHEMA_NAME_LEN>
PTR 0x0003e6fc (10)
SWORD 2
SWORD * 0x0003e6f2 (2)

MSQRY32 ba:c0 ENTER SQLTablesW


HSTMT 0x00823420
WCHAR * 0x00839710
SWORD 0
WCHAR * 0x00839720 [ -3] "%"
SWORD -3
WCHAR * 0x00839730
SWORD 0
WCHAR * 0x00839740
SWORD 0

MSQRY32 ba:c0 EXIT SQLTablesW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
WCHAR * 0x00839710
SWORD 0
WCHAR * 0x00839720 [ -3] "%"
SWORD -3
WCHAR * 0x00839730
SWORD 0
WCHAR * 0x00839740
SWORD 0

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65
SDWORD * 0x0003e6f4

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65
SDWORD * 0x0003e6f4 (0)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

Chapter 3. Express C/C++ APIs 169


MSQRY32 ba:c0 ENTER SQLFreeStmt
HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLTablesW


HSTMT 0x00823420
WCHAR * 0x00839610 [ 8] "RCHA"
SWORD 8
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839630 [ 24] "'TABLE','VIE"
SWORD 24

MSQRY32 ba:c0 EXIT SQLTablesW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
WCHAR * 0x00839610 [ 8] "RCHA"
SWORD 8
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839630 [ 24] "'TABLE','VIE"
SWORD 24

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 3
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e604
SDWORD 65
SDWORD * 0x0003e6d4

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 3
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e604
SDWORD 65
SDWORD * 0x0003e6d4 (-1)

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65
SDWORD * 0x0003e6d0

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e180
SDWORD 65

170 Client Access Express Programming


SDWORD * 0x0003e6d0 (2012853328)

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e648
SDWORD 65
SDWORD * 0x0003e6f4

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e648
SDWORD 65
SDWORD * 0x0003e6f4 (8)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

***Multiple SQLFetches removed to improve readability***

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLGetInfo


HDBC 0x00830ac0
UWORD 29 <SQL_IDENTIFIER_QUOTE_CHAR>
PTR 0x0003e66c
SWORD 128
SWORD * 0x0003e6f6

MSQRY32 ba:c0 ENTER SQLGetInfoW


HDBC 0x00830ac0
UWORD 29 <SQL_IDENTIFIER_QUOTE_CHAR>
PTR 0x00839510
SWORD 256
SWORD * 0x0003e6f6

MSQRY32 ba:c0 EXIT SQLGetInfoW with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 29 <SQL_IDENTIFIER_QUOTE_CHAR>
PTR 0x00839510 [ 2] " "
SWORD 256

Chapter 3. Express C/C++ APIs 171


SWORD * 0x0003e6f6 (2)

MSQRY32 ba:c0 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 29 <SQL_IDENTIFIER_QUOTE_CHAR>
PTR 0x0003e66c [ 1] " "
SWORD 128
SWORD * 0x0003e6f6 (1)

MSQRY32 ba:c0 ENTER SQLGetTypeInfo


HSTMT 0x00823420
SWORD 0 <SQL_ALL_TYPES>

MSQRY32 ba:c0 EXIT SQLGetTypeInfo with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
SWORD 0 <SQL_ALL_TYPES>

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 2 <SQL_C_DEFAULT>
SWORD 99 PTR 0x0003e72e
SDWORD 2
SDWORD * 0x0003e6ec

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2
SWORD 99 <SQL_C_DEFAULT>
PTR 0x0003e72e
SDWORD 2
SDWORD * 0x0003e6ec (12976948)

***Multiple SQLFetches removed to improve readability***

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLGetInfo


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0007c015

172 Client Access Express Programming


SWORD 4
SWORD * 0x00000000

MSQRY32 ba:c0 ENTER SQLGetInfoW


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0007c015
SWORD 4
SWORD * 0x0003f730

MSQRY32 ba:c0 EXIT SQLGetInfoW with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0007c015 (0)
SWORD 4
SWORD * 0x0003f730 (2)

MSQRY32 ba:c0 EXIT SQLGetInfo with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
UWORD 1 <SQL_ACTIVE_STATEMENTS>
PTR 0x0007c015 (0)
SWORD 4
SWORD * 0x00000000

MSQRY32 ba:c0 ENTER SQLAllocStmt


HDBC 0x00830ac0
HSTMT * 0x0003f81c

MSQRY32 ba:c0 EXIT SQLAllocStmt with return code 0 (SQL_SUCCESS)


HDBC 0x00830ac0
HSTMT * 0x0003f81c ( 0x0082fc08)

***SQLColumns is used to retrieve the list of column names for a specified table.***

MSQRY32 ba:c0 ENTER SQLColumns


HSTMT 0x00823420
UCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
UCHAR * 0x00077200 [ -3] "BRENTLIB\ 0"
SWORD -3
UCHAR * 0x0003e520 [ -3] "MYTABLE\ 0"
SWORD -3
UCHAR * 0x00000000 [ -3] <empty string>
SWORD -3

MSQRY32 ba:c0 ENTER SQLColumnsW


HSTMT 0x00823420
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839cf0 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839e50 [ -3] "MYTA"
SWORD -3
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3

MSQRY32 ba:c0 EXIT SQLColumnsW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839cf0 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839e50 [ -3] "MYTA"
SWORD -3
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3

Chapter 3. Express C/C++ APIs 173


MSQRY32 ba:c0 EXIT SQLColumns with return code 0 (SQL_SUCCESS)
HSTMT 0x00823420
UCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
UCHAR * 0x00077200 [ -3] "BRENTLIB\ 0"
SWORD -3
UCHAR * 0x0003e520 [ -3] "MYTABLE\ 0"
SWORD -3
UCHAR * 0x00000000 [ -3] <empty string>
SWORD -3

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e564
SDWORD 65
SDWORD * 0x0003e4c0

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e564
SDWORD 65
SDWORD * 0x0003e4c0 (0)

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 5
SWORD -15 <SQL_C_SSHORT>
PTR 0x0003e4b6
SDWORD 2
SDWORD * 0x0003e4f4

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 5
SWORD -15 <SQL_C_SSHORT>
PTR 0x0003e4b6
SDWORD 2
SDWORD * 0x0003e4f4 (2011645749)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

174 Client Access Express Programming


MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)
HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

***SQLSpecialColumnsW is used to retrieve the columns that uniquely identify each row in the table

MSQRY32 ba:c0 ENTER SQLSpecialColumnsW


HSTMT 0x00823420
UWORD 1 <SQL_BEST_ROWID>
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839270 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839290 [ -3] "MYTA"
SWORD -3
UWORD 0 <SQL_SCOPE_CURROW>
UWORD 1 <SQL_NULLABLE>

MSQRY32 ba:c0 EXIT SQLSpecialColumnsW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 1 <SQL_BEST_ROWID>
WCHAR * 0x00000000 [ -3] <empty string>
SWORD -3
WCHAR * 0x00839270 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839290 [ -3] "MYTA"
SWORD -3
UWORD 0 <SQL_SCOPE_CURROW>
UWORD 1 <SQL_NULLABLE>

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e564
SDWORD 65
SDWORD * 0x0003e4c0

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e564
SDWORD 65
SDWORD * 0x0003e4c0 (4)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

Chapter 3. Express C/C++ APIs 175


MSQRY32 ba:c0 ENTER SQLColumns
HSTMT 0x00823420
UCHAR * 0x0003ea68 [ -3] "RCHASPTM\ 0"
SWORD -3
UCHAR * 0x0003eaec [ -3] "BRENTLIB\ 0"
SWORD -3
UCHAR * 0x0003e648 [ -3] "MYTABLE\ 0"
SWORD -3
UCHAR * 0x00000000
SWORD 0

MSQRY32 ba:c0 ENTER SQLColumnsW


HSTMT 0x00823420
WCHAR * 0x00839610 [ -3] "RCHA"
SWORD -3
WCHAR * 0x00839630 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839650 [ -3] "MYTA"
SWORD -3
WCHAR * 0x00000000
SWORD 0

MSQRY32 ba:c0 EXIT SQLColumnsW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
WCHAR * 0x00839610 [ -3] "RCHA"
SWORD -3
WCHAR * 0x00839630 [ -3] "BREN"
SWORD -3
WCHAR * 0x00839650 [ -3] "MYTA"
SWORD -3
WCHAR * 0x00000000
SWORD 0

MSQRY32 ba:c0 EXIT SQLColumns with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UCHAR * 0x0003ea68 [ -3] "RCHASPTM\ 0"
SWORD -3
UCHAR * 0x0003eaec [ -3] "BRENTLIB\ 0"
SWORD -3
UCHAR * 0x0003e648 [ -3] "MYTABLE\ 0"
SWORD -3
UCHAR * 0x00000000
SWORD 0

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e648
SDWORD 65
SDWORD * 0x0003e6cc

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 4
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e648
SDWORD 65
SDWORD * 0x0003e6cc (255708)

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 5
SWORD 99 <SQL_C_DEFAULT>
PTR 0x0003e6e2
SDWORD 2

176 Client Access Express Programming


SDWORD * 0x0003e6cc

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 5
SWORD 99 <SQL_C_DEFAULT>
PTR 0x0003e6e2
SDWORD 2
SDWORD * 0x0003e6cc (255708)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 3 <SQL_RESET_PARAMS>
MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)
HSTMT 0x00823420
UWORD 3 <SQL_RESET_PARAMS>

MSQRY32 ba:c0 ENTER SQLSpecialColumnsW


HSTMT 0x00823420
UWORD 1 <SQL_BEST_ROWID>
WCHAR * 0x00839610 [ 8] "RCHA"
SWORD 8
WCHAR * 0x00839630 [ 8] "BREN"
SWORD 8
WCHAR * 0x00839650 [ 7] "MYT"
SWORD 7
UWORD 0 <SQL_SCOPE_CURROW>
UWORD 1 <SQL_NULLABLE>

MSQRY32 ba:c0 EXIT SQLSpecialColumnsW with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 1 <SQL_BEST_ROWID>
WCHAR * 0x00839610 [ 8] "RCHA"
SWORD 8
WCHAR * 0x00839630 [ 8] "BREN"
SWORD 8
WCHAR * 0x00839650 [ 7] "MYT"
SWORD 7
UWORD 0 <SQL_SCOPE_CURROW>

Chapter 3. Express C/C++ APIs 177


UWORD 1 <SQL_NULLABLE>

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e1f0
SDWORD 1024
SDWORD * 0x0003e1e4

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2
SWORD 1 <SQL_C_CHAR>
PTR 0x0003e1f0
SDWORD 1024
SDWORD * 0x0003e1e4 (0)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x00823420

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x00823420

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x00823420
UWORD 3 <SQL_RESET_PARAMS>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x00823420
UWORD 3 <SQL_RESET_PARAMS>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x0082fc08
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x0082fc08
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x0082fc08
UWORD 3 <SQL_RESET_PARAMS>

178 Client Access Express Programming


MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)
HSTMT 0x0082fc08
UWORD 3 <SQL_RESET_PARAMS>

***SQLSetStmtOption is used in attempting to enable asynchronous support. However, the Client Acc
driver does not support this. This is why SQL_ERROR is returned.***

MSQRY32 ba:c0 ENTER SQLSetStmtOption


HSTMT 0x0082fc08
UWORD 4 <SQL_ASYNC_ENABLE>
UDWORD 1

MSQRY32 ba:c0 EXIT SQLSetStmtOption with return code -1 (SQL_ERROR)


HSTMT 0x0082fc08
UWORD 4 <SQL_ASYNC_ENABLE>
UDWORD 1

DIAG [S1C00] [IBM][Client Access Express ODBC Driver (32-bit)]Driver not capable. (0)

DIAG [S1C00] [IBM][Client Access Express ODBC Driver (32-bit)]Driver not capable. (0)

***SQLPrepare is used to prepare an SQL statement for execution.***

MSQRY32 ba:c0 ENTER SQLPrepare


HSTMT 0x0082fc08
UCHAR * 0x00085bc8 [ 59] "SELECT MYTABLE.COL1\ d\ aFROM RCHASPTM.BRENTLIB.MYTABLE
SDWORD 59

MSQRY32 ba:c0 EXIT SQLPrepare with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UCHAR * 0x00085bc8 [ 59] "SELECT MYTABLE.COL1\ d\ aFROM RCHASPTM.BRENTLIB.MYTABLE
SDWORD 59

***SQLExecute is used to execute the SQL statement that was prepared.***

MSQRY32 ba:c0 ENTER SQLExecute


HSTMT 0x0082fc08

MSQRY32 ba:c0 EXIT SQLExecute with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08

***SQLNumResultCols is used to return the number of columns in the result set.***

MSQRY32 ba:c0 ENTER SQLNumResultCols


HSTMT 0x0082fc08
SWORD * 0x0003ebfa

MSQRY32 ba:c0 EXIT SQLNumResultCols with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
SWORD * 0x0003ebfa (1)

***SQLDescribeCol is used to retrieve information about a column in the result set.***

MSQRY32 ba:c0 ENTER SQLDescribeCol


HSTMT 0x0082fc08
UWORD 1
UCHAR * 0x0003ea30
SWORD 256
SWORD * 0x0003ec16
SWORD * 0x0003ec32
UDWORD * 0x0003eb84
SWORD * 0x0003ebf6
SWORD * 0x0003ebf8

MSQRY32 ba:c0 EXIT SQLDescribeCol with return code 0 (SQL_SUCCESS)

Chapter 3. Express C/C++ APIs 179


HSTMT 0x0082fc08
UWORD 1
UCHAR * 0x0003ea30 [ 4] "COL1"
SWORD 256
SWORD * 0x0003ec16 (4)
SWORD * 0x0003ec32 (1)
UDWORD * 0x0003eb84 (10)
SWORD * 0x0003ebf6 (0)
SWORD * 0x0003ebf8 (1)

***SQLColAttributes is used to retrieve additional information about a column in the result set.***

MSQRY32 ba:c0 ENTER SQLColAttributes


HSTMT 0x0082fc08
UWORD 1
UWORD 6 <SQL_COLUMN_DISPLAY_SIZE>
PTR 0x00000000
SWORD 0
SWORD * 0x0003ec16
SDWORD * 0x0003ec20

MSQRY32 ba:c0 EXIT SQLColAttributes with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 1
UWORD 6 <SQL_COLUMN_DISPLAY_SIZE>
PTR 0x00000000
SWORD 0
SWORD * 0x0003ec16 (4)
SDWORD * 0x0003ec20 (10)

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861c8
SDWORD 11
SDWORD * 0x0003ea00

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861c8
SDWORD 11
SDWORD * 0x0003ea00 (4745629)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x0082fc08

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861d3
SDWORD 11
SDWORD * 0x0003ea00

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861d3
SDWORD 11
SDWORD * 0x0003ea00 (10)

180 Client Access Express Programming


MSQRY32 ba:c0 ENTER SQLFetch
HSTMT 0x0082fc08

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861de
SDWORD 11
SDWORD * 0x0003ea00

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861de
SDWORD 11
SDWORD * 0x0003ea00 (10)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x0082fc08

MSQRY32 ba:c0 EXIT SQLFetch with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08

MSQRY32 ba:c0 ENTER SQLBindCol


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861e9
SDWORD 11
SDWORD * 0x0003ea00

MSQRY32 ba:c0 EXIT SQLBindCol with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 1
SWORD 1 <SQL_C_CHAR>
PTR 0x000861e9
SDWORD 11
SDWORD * 0x0003ea00 (10)

MSQRY32 ba:c0 ENTER SQLFetch


HSTMT 0x0082fc08

MSQRY32 ba:c0 EXIT SQLFetch with return code 100 (SQL_NO_DATA_FOUND)


HSTMT 0x0082fc08

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x0082fc08
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 0 <SQL_CLOSE>

MSQRY32 ba:c0 ENTER SQLFreeStmt


HSTMT 0x0082fc08
UWORD 2 <SQL_UNBIND>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 2 <SQL_UNBIND>

Chapter 3. Express C/C++ APIs 181


MSQRY32 ba:c0 ENTER SQLFreeStmt
HSTMT 0x0082fc08
UWORD 3 <SQL_RESET_PARAMS>

MSQRY32 ba:c0 EXIT SQLFreeStmt with return code 0 (SQL_SUCCESS)


HSTMT 0x0082fc08
UWORD 3 <SQL_RESET_PARAMS>

Enabling table and file updates: ODBC enables for queries and reports, but
eventually you may need to update some of your data. Because the Client Access
Express ODBC driver is a read/write driver, table updates are possible. All that is
required is some setup work.
Enabling table and file updates topics:
v “Table update requirements”
v “PC application locking” on page 183
v “Creating a unique index” on page 184
v “Authorization for physical files” on page 184
v “Troubleshooting table update errors” on page 185

Table update requirements: Most PC applications require that a table have a unique
key to be updatable. It is important to note that it is not a requirement of the
Client Access ODBC driver, of the ODBC API, or of the AS/400 database. It is a
requirement of the PC applications. Many of these PC applications use a
keyset-driven cursor model to allow the application fast, easy, random access to all
rows in the table.

See “Types of unique key tables, files, and indexes” on page 183 for more
information.

The application queries the file once for data, and queries it a second time to
determine if there is a unique key over the table. If a unique key is identified, the
application opens the dataset in read/write mode. If it is not, the application opens
the dataset in read-only mode. The PC then reads the unique keys for ALL
RECORDS and stores the information on the PC. All further updates/deletes/reads
are done using the local copy of the keys.

An example of a database engine that uses the keyset-driven cursor model is the
Microsoft Jet database engine used by both MS Access and Microsoft Visual Basic.
Jet issues the ODBC API call SQLStatistics to return any unique keys that are
available for the table. If one or more unique index is available, Jet selects the first
index that is returned to be the primary key, and allows the table to be updatable.

Microsoft documents this along with the Jet Engine requirement for a unique key
in the Microsoft White Paper: Jet Database Engine 3.0: ODBC Connectivity. Other
types of PC database engines may have different criteria for selecting an index to
use.

Note: DB2 Universal Database (UDB) for AS/400 treats logical files similar to an
SQL view. At this time, the OS/400 database server does not return
information to a request for unique key, or return catalog information on the
constraints that a logical inherits from a physical file. Because no unique key
information is reported to the client, most applications do not consider a
logical file to be updatable. This capability is under consideration for future
releases. Newer versions of MS Access let you work around this.

“Types of unique key tables, files, and indexes” on page 183

182 Client Access Express Programming


Types of unique key tables, files, and indexes: The following files and indexes have
unique keys:
v SQL-defined tables built with a PRIMARY KEY or UNIQUE key. 4 SQL-defined
tables that have an SQL UNIQUE index built over them.
v DDS-described physical files with the keyword UNIQUE specified. DDS allows
only one unique key or compound key.
v DDS-described physical files that have a logical file built over them and that
logical contains the keyword UNIQUE.
DDS files must contain the keyword ″unique,″ which is a file-level identifier that is
used to indicate that duplicate key values are not allowed within the physical file.
If a unique key is specified in a logical file over a physical, the physical may not
have any duplicate key values.

If the DDS description does not contain the keyword ″unique,″ then it is not a
unique key. In SQL terms, a DDS key is similar to an index.

Example of DDS-described logical file with a unique primary key:


00010A*
00020A* SAMPLE LOGICAL FILE (CUSMSTL)
00030A*
00040A UNIQUE
00050A R CUSREC PFILE(CUSMSTP)
00060A TEXT('Logical FileÆ)

00070A CUST
00080A NAME
00090A ADDR
00100A K CUST

Example of a unique key created with SQL:


CREATE UNIQUE INDEX indexname ON library/tablename (fieldname1, fieldname2)

PC application locking: Most PC applications read data from the file that the user
has specified for read-only data. The application then queries the database to
determine if the file has a unique index defined over it. If there is a unique index
on the table, the application allows data editing because optimistic locking is
allowed. To lock a record with Optimistic locking so that it can be edited or
deleted later, the original record has to be refound in the table and then locked for
update.

To update a record, a program issues the following command:


UPDATE RASTEST.CUSTOMER SET CITY = 'Cartegena '
WHERE CUSTNUM = 20 AND CUSTNAME = 'Juan''s Coffee '
AND ADDRESS = '1 Mountainside Rd '
AND CITY = 'Bogata '
AND STATE = '' AND PHONE = '37-44-COFFEE '

If there was not a unique index on this table, this type of locking would not work.
It would not be able to query the database and update a single record.

Data versioning:

Another consideration of this style of locking is the problem of data versioning.


Data versioning refers to the process by which:
1. you read in the data you need to review
2. while you review the data, another user updates records in the table

Chapter 3. Express C/C++ APIs 183


3. you then realize that you need to correct some of the data, which happens to
be the same data that was changed by the other user

The update that you attempted would fail with a ″Record not found″ message. You
would not be informed that another user had updated that record. You would not
be prompted to display the new version of the record as it was updated by the
other user. You would be required to reread in the table to discover what might
have changed to cause the error.

Creating a unique index: To create a unique index on the AS/400, use interactive
SQL or the RUNSQLSTM command.
To use interactive SQL:
1. Type in STRSQL to start interactive SQL.
2. Type in the command
CREATE UNIQUE INDEX indexname ON libraryname/tablename
(fieldname).
To use the RUNSQLSTM command:
1. Create a source file.
2. Create a member that contains the command
CREATE UNIQUE INDEX indexname
ON libraryname/tablename (fieldname)
3. Run the RUNSQLSTM command against the source file and member
that you defined in the previous steps.

Once either of these methods is used to create a unique index, or if you create a
logical file with a unique key, you will be able to see and use the index from any
ODBC application. Once this index is visible to ODBC applications, optimistic
locking can occur, and your data can be edited.

Authorization for physical files: When querying data files, the authorization to a file
is checked only if the file is being directly used. Here is an example to illustrate:
You have a physical file that has authority of public *use. You have a logical over
that physical that has public *exclude. A user with public authority could
successfully run a query defined on the physical file since it requires authority to
the physical file only, even though all logicals would be reviewed to return the
results of the query. However, a user with public authority would get a not
authorized error on a query defined on the logical file described above.

In addition to querying data files, ODBC applications also query the DB2 Universal
Database (UDB) for AS/400 catalog tables and views for information on the tables
and columns available on the AS/400 system. Applications issue the ODBC API
calls SQLTables and SQLColumns to return listings of tables and columns on the
AS/400 system. For both calls, DB2 UDB for AS/400 returns information on
physicals files that the user has authority to, along with information on any
logicals or views over the physical. Here again, the user does not need to have
specific authority to these logicals, only to the physical files they are based on.

The exception to this is the ODBC API SQLStatistics. This call returns information
on the indexes or logicals available for a specific table. Applications use the
SQLStatistics call to determine whether there are unique indexes available for a
table to be updatable. The ODBC host code returns this information from the
OS/400 file descriptions. Here, the user does need to have authority to the indexes
or logicals over the file. If the user is not authorized, DB2 UDB for AS/400 issues a
CPF2207 Not authorized to use object xxxxLF in library xxxx.

184 Client Access Express Programming


Troubleshooting table update errors: The following techniques can help you to
troubleshoot table update errors, and to verify that there is a unique key or index
over tables:
1. First, check the physical file itself for a unique key using the AS/400 Display
File Description (DSPFD) command. Page down and note the values under the
Access Path Description section as noted:
Last journal start date/time . . . . . . . : 09/10/9
Access Path Description
Access path maintenance . . . . . . . . . . : MAINT *IMMED
Unique key values required . . . . . . . . : UNIQUE Yes
Access path journaled . . . . . . . . . . . : No
Access path . . . . . . . . . . . . . . . . : Keyed
Constraint Type . . . . . . . . . . . . . . : NONE
Number of key fields . . . . . . . . . . . : 1
Record format . . . . . . . . . . . . . . . : REC1
Key field . . . . . . . . . . . . . . . . : CUSNUM
Sequence . . . . . . . . . . . . . . . : Ascending

Determine if there are any logical files created over the physical by using the
AS/400 DSPDBR command and by checking under Files Dependent on
Specified File. Then do a DSPFD on each of these files to determine if any
contain a unique key.

ODBC retrieves this information from the AS/400 system catalog tables.
QSYS/QADBXREF stores the unique keyed and number of key fields
information. QSYS/QADBXFLD stores additional information on each key
field. QSYS/QADBFCST has unique and primary key information for SQL
Tables only.
2. Use the MS SDK ODBC Administrator’s tracing facility to trace your query, and
to view information about indexes that are returned by the ODBC API
SQLStatistics call.
3. Verify that the user is trying to update the physical file and not a logical file
over it.
4. Move the file that you are unable to update to a separate library along with the
unique index if it is a separate file. Then set this test library as your default
library in the ODBC datasource. This allows you to isolate the file from other
logicals that may be over the file, for testing purposes.

Express ODBC security: The following information is not intended to be a


comprehensive guide to security issues on the AS/400 or with Client Access
Express. It simply provides an overview of security issues that impact Client
Access Express and ODBC users. For more in-depth information, see the IBM
Security - Reference book.
Express ODBC security topics:
v “Object-level security”
v “Program-adopted authority” on page 186
v “Referential integrity” on page 186
v “Risky ODBC security strategies” on page 186
v “Client Access Express concepts” on page 187
v “ODBC program security strategies” on page 188
v “Other information resources for ODBC security” on page 190

Object-level security: Object-level security allows you to define who can use an
object and how that object can be used. Object-level security cannot be
circumvented. OS/400 checks authority every time that the object is accessed.
Here’s an example of the object security on a file:

Chapter 3. Express C/C++ APIs 185


Object secured by authorization list . . . . . . . . . . ORDENTRY

Object ----------Object-----------
User Group Authority Opr Mgt Exist Alter Ref
ADMIN1 *ALL X X X X X
*PUBLIC *USE X

Object ---------------Data---------------
User Authority Read Add Update Delete Execute
ADMIN1 *ALL X X X X X
*PUBLIC *USE X X

In this example, an authorization list named ORDENTRY is used to simplify


administration. User profile ADMIN1 has full access to the file, while *PUBLIC can
read but not update the file. In this example, user profiles running the order-entry
application would be entered into the ORDENTRY authorization list with
*CHANGE authority. For additional information see the Security - Reference
manual.

Program-adopted authority: System administrators may want to limit the methods


by which a user profile can access data. In the example provided in “Object-level
security” on page 185, they might specify that the order-entry user profiles have
NO access to the files except when running the order-entry application. OS/400
supports this concept by using program-adopted authority. With program-adopted
authority, the user profile that is running the application program adopts an
authorization level that is attached to the program. This technique commonly was
used before R310 to ensure the integrity of data.

The order-entry example in “Object-level security” on page 185 might be changed


so that the order entry PROGRAM has *CHANGE authority to the files, but the
order-entry user profiles have *NONE access to the files. The order-entry user
profiles have *USE authority to the PROGRAM. When running the program, the
order-entry profiles adopt the authority of the program, thereby gaining access to
the file. For additional information, see the Security - Reference book.

Referential integrity: In R310, DB2 Universal Database (UDB) for AS/400


introduced database support for referential integrity. Prior to R310, many
customers used program-adopted authority to protect the integrity of their
databases. Referencing the order-entry example in “Object-level security” on
page 185, you might want to ensure that no order detail entry could be made
without matching an existing order header. Using program-adopted authority,
every program that updates the order-entry files must contain this check.
Referential integrity allows the database rules to be coded directly in the database.
File updates no longer are restricted to certain programs to ensure integrity.

The SQL Reference book contains additional information. iew an HTML online
version of the book, or print a PDF version, from the DB2 Universal Database for
AS/400 books online AS/400 Information Center topic.

Risky ODBC security strategies: Some system administrators attempt to secure


access to the data, rather than securing the data itself. This is extremely risky, as it
requires that administrators understand ALL of the methods by which users can
access data. Some common ODBC security techniques to avoid include:
Limit capabilities - User profile parameter
Useful for ″green-screen″ or 5250 emulation-based applications, this
method assumes that if you prevent users from entering commands in a
5250 emulation session, they can access data only through the programs

186 Client Access Express Programming


and menus that the system administrator provides to them. This method is
secure only if all ″back-door″ methods of access are accounted for. These
include TCP/IP, Client Access and various OEM products. For additional
information, see the Security - Reference book.
User exit programs
A user exit program allows the system administrator to secure an
IBM-supplied host server program. System administrators often overlook
the DDM user exit, which is documented in the Distributed Data
Management book. The DDM server is used by some Client Access Express
functions such as the OLE DB provider and the older Remote
Command.For detailed information, see either of the following
publications:
v Client Access Express Host Servers in the IBM BookManager®
BookServer online library
v Distributed Data Management, which is available in viewable HTML
and printable PDF formats in the AS/400 Information Center
Audit logs (monitoring security)
OS/400 has several logs that can be used to monitor security. QHST, the
History Log, contains messages that relate to security changes that are
made to the system. For detailed monitoring of security-related functions,
QAUDJRN can be enabled. The *SECURITY value logs the following
functions:
v Changes to object authority
v Create, change, delete, display, and restore operations of user profiles
v Changes to object ownership
v Changes to programs (CHGPGM) that adopt the owner’s profile
v Changes to system values and network attributes
v Changes to subsystem routing
v When the QSECOFR password is reset to the shipped value by DST
v When the DST security officer password is requested to be defaulted
v Changes to the auditing attribute of an object
For additional information, see the Security - Reference book.
Journals
Journaling often is used with client/server applications to provide
commitment control. The journals contain detailed information on every
update made to a file that is being journaled. The journal information can
be formatted and queried to return specific information, including:
v The user profiles that updated the file
v The records that were updated
v The type of update
OS/400 also allows user-defined journal entries. When used with a user
exit program or trigger, this offers a relatively low-overhead method of
maintaining user-defined audits. For further information, see the following
IBM publications: Backup and Recovery and Security - Reference.

Client Access Express concepts:


Host server
Each client application on a PC is a program that communicates with a
corresponding server on the AS/400. This server processes a request and
returns data. OS/400 has several servers included in the base operating
system. These are documented in the Client Access Express Host Servers
book. Examples of host server programs include:

Chapter 3. Express C/C++ APIs 187


File server
Used by shared folders
Database server
Used by ODBC
Data queue server
Used by the data queue APIs and the Windows network driver

System administrators should be alert to changes or additions to these


servers.

Any communications program can act as a server. The system


administrator also must be aware of ANY OEM server or user-written
server that may reside on their system. Any of these can be used to access
AS/400 data.
Server program security
IBM server programs authenticate the user ID and password that are sent
by the client on the program allocate or connect. By default, this is the user
ID and password of the Client Access Express router. However, many
servers—including ODBC—allow you to override this, and pass a different
user ID and password. After verifying the security information, the server
program uses the authority of this user ID when attempting to access data.
User exit programs
Each server program has an associated user exit. A user exit program
allows an administrator to control what activities a client is allowed to
perform for each of the specific servers. Whenever a request is sent to the
server, the server first checks if a user exit program is registered. If it is, it
will pass to the user exit a block of data with the request information. The
user exit program can process this data and return a flag that allows or
prevents the server from processing the request.
User exit programs can have a significant impact on performance. See “Exit
programs” on page 237 for more information.
Common back doors
Several servers offer methods to submit AS/400 commands through the
client. Restricting command-line usage does not block this. Remote
Command uses either the DDM server or the Remote Command and
Distributed Program Call Server, depending on the client. Both remote SQL
and ODBC support a method of running AS/400 commands and programs
by a call to QCMDEXC.

ODBC program security strategies: Consider the following ODBC program security
strategies:
Restricting program access to the database
System administrators often need to limit access to particular files, to a
certain program, or to set of programs. A ″green-screen″ programmer
would carry out restrictions by using program-adopted authority. A similar
method can be used with ODBC.
Stored procedures allow ODBC programmers to implement
program-adopted authority. The programmer may not want users to be
able to manipulate database files by using desktop applications such as
Microsoft Access or Lotus 1-2-3®. Instead, the programmer may want to
limit database updates to only the programmer’s application. To implement
this, user access to the database must be restricted with object-level

188 Client Access Express Programming


security or with user exit programs. The application must be written to
send data requests to the stored procedure and have the stored procedure
update the database.
The SQL Reference book contains additional information. iew an HTML
online version of the book, or print a PDF version, from the DB2 Universal
Database for AS/400 books online AS/400 Information Center topic.
Restricting CPU utilization by user
ODBC has greatly eased the accessibility of AS/400 data. One negative
impact has been that users may accidentally create very CPU-intensive
queries without realizing it. ODBC runs at an interactive job priority and
this can severely affect system performance. The AS/400 supports a query
governor. ODBC can invoke the query governor (for example, through the
PC application) in a stored procedure call. Or the ODBC APIs can invoke
the governor by way of the query timeout parameter (R312 or later of
Client Access). Also, a user exit program can force the query governor on
the ODBC job. The time limit is specified on the QRYTIMLMT parameter
of the CHGQRYA CL command.
The SQL Reference book contains additional information. iew an HTML
online version of the book, or print a PDF version, from the DB2 Universal
Database for AS/400 books online AS/400 Information Center topic.
Also see the Client Access Express Host Servers book.
ODBC user exit (Database server user exit)
Client Access Express ODBC requests use one of four user exit points in
the IBM-supplied database server. To allow read only access to data,
QIBM_QZDA_NB1 and QIBM_QZDA_SQL1 or QIBM_QZDA_SQL2 must
be monitored. See“Exit programs” on page 237 for more information.
QIBM_QZDA_INIT
This is called once at server initialization, such as an ODBC
connect. Obviously, this is the ideal exit to use for a query
governor or to completely reject incoming requests.
QIBM_QZDA_NB1
This exit is called for native database requests. An exit program
should monitor this exit point to block or restrict database file
functions such as Delete file, Clear file (erase all data), certain
create file commands, and so forth.
QIBM_QZDA_SQL1 or QIBM_QZDA_SQL2
These exit points process the data related to SQL requests. The first
512 bytes of the SQL statement are passed to the exit program. NO
PARSING OR PREPROCESSING OF THE STATEMENT IS DONE.
The programmer writing the exit program must parse the
statement and interpret its content. For example, to limit certain
users to read-only access, the exit program would have to scan
each string for any SQL function that can update, delete, or insert
data into a file. There is significant overhead associated with using
this exit point because it is called for each SQL request. Object level
security should be considered first.
QIBM_QZDA_ROI1
This exit point is called for requests that retrieve information about
objects on the database server (catalog requests). Information only
can be retrieved.

Chapter 3. Express C/C++ APIs 189


Caution!:
1. Different ODBC drivers use different servers. You may secure the IBM
Database Server by means of a user exit, but other ODBC drivers may
not use this. Some of the AS/400 ODBC drivers use the remote SQL
server. Many OEM ODBC drivers supply their own server program on
the AS/400 or use DRDA® or DDM.
2. DRDA (a type of DDM request) uses the SQL Client Integration exit
point. See the AS/400 System API Reference, and review the chapter on
File APIs for additional information.
3. The Distributed Data Management book contains additional information
on DDM user exits. View an HTML online version of the book, or print
a PDF version, from the DB2 Universal Database for AS/400 books
online Information Center topic.
For detailed information, see the Client Access Express Host Servers book,
or refer to your OEM ODBC driver documentation.
ODBC INI file restrictions
ODBC supports a query timeout that can be set by way of an ODBC API
call. Release R311 or later of Client Access Express for Windows
implements this function.
Some ODBC drivers support a read-only ini file setting. Although not
secure, this setting can assist in preventing inadvertent delete or update
operations. The Client Access ODBC driver supports this function.

Other information resources for ODBC security: In-depth security reviews and
assistance to implement the strategies above is available through IBM Consultline
(1-800-274-0015). Please review the following IBM books for in-depth information
on specific topics:
v Client Access Express Host Servers
v OS/400 Security - Reference
v OS/400 Backup and Recovery

The DB2 Universal Database for AS/400 books online topic in the AS/400
Information Center contains additional database books that cover ODBC security,
including Distributed Data Management and Database Programming. Link to the topic
to view HTML online versions, or to print PDF versions, of the books.

The ODBC interface


ODBC is a standard application programming interface for accessing database
information by using Structured Query Language (SQL).
v ODBC core functions are based on call-level interface (CLI) specifications from
X/Open and ISO/IEC.
v ODBC extended functions include scrollable cursors.

Note: Scrollable cursors enable the ability to scroll forward and backward in a
result set. For example, with scrollable cursors, if you fetch two rows of
data, you can view row 1, row 2, and then scroll back to view row 1
again. With a forward-only cursor, if you viewed row 1, and then viewed
row 2, you could not scroll back to view row 1: you would have to
perform another data fetch.

The core functions provide sufficient functionality for most requirements of a


commercial application. However, some important performance-related capabilities,
such as cursor manipulation and row-set retrieval, require extended functions.

190 Client Access Express Programming


Producers of MIS applications, query tools and administration tools most likely
will benefit from a full exploitation of the advanced functions.

The database is capable of supporting the extended functionality (for example, DB2
for OS/400). However, the ODBC driver should support the highest level (current
level 2) of functionality.
ODBC interface topics:
v “ODBC requirements”
v “ODBC components”
v “ODBC APIs: General concepts” on page 192
v “ODBC API return codes” on page 193

ODBC requirements: Before an application can use ODBC to connect to a


database and its supporting database management system, a data source must be
created. The data source defines how to access the database and the database
management system. For more information on how to define a data source, see
“Setting up the Express ODBC driver” on page 138.

The ODBC interface defines a set of calls that are used for each of these application
steps. For example, SQLAllocEnv allocates the ODBC environment. Each of these

API calls is documented in the Microsoft ODBC Programmer’s Reference .


Many of the more common ODBC APIs are examined in this publication. It
includes programming examples that use the C and Visual Basic programming
languages.

For additional information, see “Coding directly to ODBC APIs” on page 216.

ODBC components: The following graphic illustrates the relationship between


the various ODBC components:

The primary components in the ODBC architecture are:


Application:
Performs processing and calls ODBC functions to run SQL statements.
Driver Manager
Loads drivers for an application. The driver manager, ODBC32.DLL,
typically resides in WINDOWS\SYSTEM directory. Configuration of ODBC
drivers is a joint effort between the driver and the Microsoft ODBC
Administrator; ODBCAD32.EXE.

Chapter 3. Express C/C++ APIs 191


Driver Processes ODBC function calls, submits SQL requests to a specific data
source, and returns results to the application.
Data source:
The data together with the OS, DBMS, and network (if remote) directory.
You can specify any of the following data sources:
User DSN:
These data sources are local to a computer, and may only be used
by the current user.
System DSN:
These data sources are local to a computer, rather than dedicated
to a user. The system, or any user having privileges, can use a data
source set up with a system DSN.
File DSN:
These are file-based data sources that may be shared between all
users that have the same drivers installed, so that they have access
to the database. These data sources do not need to be dedicated to
a user, or to be local to a computer.

ODBC APIs: General concepts: The following general concepts apply to ODBC
APIs:
Environments:
The environment in which Windows makes available some memory for
ODBC to monitor its run-time information. There only is one environment
per ODBC application.
Connections:
Within the environment there can be multiple connections, each to a data
source. The connections may be to different physical systems, to the same
system, or any combination of both.
Statements:
Within each connection, multiple statements can be run, in some cases in
parallel (if the database and driver supports asynchronous runs of
statements).
Handles:
Handles are identifiers for storage areas that are allocated by the Driver
Manager or individual drivers. The three types of handles are:
Environment handle:
Global information, that includes other handles. One handle is
allowed per application.
Connection handle:
Information about connection to a data source. Multiple connection
handles are allowed per environment.
Statement handle:
Information about a particular SQL statement. Multiple statement
handles are allowed per connection.

Essentially, a handle can be considered as an identifier for a resource that


is recognized by ODBC (an environment, connection or statement). ODBC
provides an identifier (the handle) for this resource that you can use in
your program. Exactly what ODBC stores in the handle (which is held as a
long integer) is not relevant. Be careful not to change the value, and to
assign unique names to the variables that hold the various handles.

192 Client Access Express Programming


Some APIs set the handle (for example, SQLAllocEnv), and you must pass
in a reference, or pointer to the variable. Some APIs refer to a handle that
previously was set (for example, SQLExecute), and you must pass in the
variable by value.

ODBC API return codes: Every ODBC API function returns a value of type
SQLRETURN (a short integer). There are seven possible return codes, and
associated with each is a manifest constant. The following list provides an
explanation of each particular code. Some return codes can be interpreted as an
error on the function call. Others indicate success. Still others indicate that more
information is needed or pending.

A particular function may not return all possible codes. See the Microsoft ODBC 3.0
Software Development Kit and Programmer’s Reference, Version 3.0 ISBN 1-57231-516-4.
for possible values, and for the precise interpretation for that function.

Pay close attention to return codes in your program, particularly those that are
associated with the processing of SQL statements processing and with data source
data access. In many instances the return code is the only reliable way of
determining the success of a function.
SQL_SUCCESS
Function has completed successfully; no additional information available.
SQL_SUCCESS_WITH_INFO
Function completed successfully; possibly with a nonfatal error. The
application can call “SQLError” on page 198 to retrieve additional
information.
SQL_NO_DATA_FOUND
All rows from the result set have been fetched.
SQL_ERROR
Function failed. The application can call “SQLError” on page 198 to retrieve
error information.
SQL_INVALID_HANDLE
Function failed due to an unusable environment, connection, or statement
handle. Programming error.
SQL_NEED_DATA
The driver is asking the application to send parameter data values.

Express ODBC APIs


ODBC APIs required files:

Header files Import library Dynamic Link Library


sql.h odbc32.lib odbc32.dll

sqlext.h

sqltypes.h

sqlucode.h

Express Toolkit:
The Client Access Express Toolkit provides ODBC documentation, and
links to sample programs and related information. To access this
information, open the Express Toolkit and select Database —> ODBC.

Chapter 3. Express C/C++ APIs 193


ODBC APIs topics:
v Express ODBC APIs listing
v “Client Access ODBC APIs implementation issues and requirements” on
page 200
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Express ODBC APIs listing: Client Access Express ODBC APIs are listed
according to their conformance level:
v “ODBC core conformance APIs”
v “ODBC level-1 conformance APIs” on page 195
v “ODBC level-2 conformance APIs” on page 196
Related topics:
v “Parameter markers” on page 197
v “SQLBindCol and SQLFetch” on page 198
v “SQLFetch and SQLGetData” on page 198
v “SQLError” on page 198

ODBC core conformance APIs: The following ODBC core conformance APIs allow
you to:
v Allocate and free environment, connection, and statement handles
v Connect to data sources and use multiple statements on a connection
v Prepare and run SQL statements, and run SQL statements immediately
v Assign storage for parameters in an SQL statement and result columns
v Retrieve data from a result set and retrieve information about a result set
v Commit or roll back transactions
v Retrieve error information
SQLAllocConnect
Obtains a connection handle.
SQLAllocEnv
Obtains an environment handle. One environment handle is used for one
or more connections.
SQLAllocStmt
Allocates a statement handle.
SQLBindCol
Assigns storage for a result column and specifies the data type. See
“SQLBindCol and SQLFetch” on page 198 for additional information.
SQLBindParameter
Assigns storage for a parameter in an SQL statement. See “Parameter
markers” on page 197 for additional information.
SQLCancel
Cancels an SQL statement.
SQLColAttributes
Describes attributes of a column in the result set.
SQLConnect
Connects to a specific driver by data source name, user ID, and password.
SQLDescribeCol
Describes a column in the result set.

194 Client Access Express Programming


SQLDisconnect
Closes the connection.
SQLError
Returns additional error or status information. See “SQLError” on page 198
for more information.
SQLExecDirect
Runs a statement.
SQLExecute
Runs a prepared statement.
SQLFetch
Returns a result row. See “SQLBindCol and SQLFetch” on page 198 and
“SQLFetch and SQLGetData” on page 198 for additional information.
SQLFreeConnect
Releases the connection handle.
SQLFreeEnv
Releases the environment handle.
SQLFreeStmt
Ends statement processing and closes the associated cursor, discards
pending results optionally freeing all resources associated with the
statement handle.
SQLGetCursorName
Returns the cursor name associated with a statement handle.
SQLNumResultCols
Returns the number of columns in the result set.
SQLPrepare
Prepares an SQL statement for later processing.
SQLRowCount
Returns the number of rows that are affected by an insert, update, or
delete request.
SQLSetCursorName
Specifies a cursor name.
SQLTransact
Commits or rolls back a transaction.

ODBC level-1 conformance APIs: ODBC level-1 conformance APIs allow you to:
v Manage core API functionality
v Connect to data sources with driver-specific dialog boxes
v Set and inquire values of statement and connection options
v Send part or all of a parameter value (useful for long data)
v Retrieve part or all of a result column value (useful for long data)
v Retrieve catalog information (columns, special columns, statistics, and tables)
v Retrieve information about driver and data source capabilities, such as
supported data types, scalar functions, and ODBC functions
SQLColumns
Returns the list of column names in specified tables.
SQLDriverConnect
Connects to a specific driver by connection string or requests that the

Chapter 3. Express C/C++ APIs 195


Driver Manager and driver display connection dialogs for the user. See
“ODBC connection strings and keywords” on page 159 for more
information.
SQLGetConnectOption
Returns the value of a connection option.
SQLGetData
Returns part or all of one column of one row of a result set (useful for long
data values). See “SQLFetch and SQLGetData” on page 198 for additional
information.
SQLGetFunctions
Returns supported driver functions.
SQLGetInfo
Returns information about a specific driver and data source.
SQLGetStmtOption
Returns the value of a statement option.
SQLGetTypeInfo
Returns information about supported data types.
SQLParamData
Returns the storage value assigned to a parameter for which data will be
sent at run time (useful for long data values).
SQLPutData
Send part or all of a data value for a parameter (useful for long data
values).
SQLSetConnectOption
Sets a connection option.
SQLSetStmtOption
Sets a statement option.
SQLSpecialColumns
Retrieves information about the optimal set of columns that uniquely
identifies a row in a specified table. It also retrieves information about the
columns that are automatically updated when any value in the row is
updated by a transaction.
SQLStatistics
Retrieves statistics about a single table and the list of indexes that are
associated with the table.
SQLTables
Returns the list of table names stored in a specific data source.

ODBC level-2 conformance APIs: ODBC level-2 conformance APIs allow you to:
v Control core and Level-1 API functionality
v Browse connection information and list available data sources
v Send arrays of parameter values. Retrieve arrays of result column values
v Retrieve the number of parameters and describe individual parameters
v Use a scrollable cursor
v Retrieve the original form of an SQL statement
v Retrieve catalog information (privileges, keys, and procedures)
v Call a translation DLL
SQLBrowseConnect
Returns successive levels of connection attributes and valid attribute

196 Client Access Express Programming


values. When a value has been specified for each connection attribute,
connects to the data source. See “ODBC connection strings and keywords”
on page 159 for more information.
SQLColumnPrivileges
Returns a list of columns and associated privileges for one or more tables.
SQLDataSources
Returns a list of available data sources.
SQLDescribeParam
Returns the description for a specific parameter in a statement.
SQLExtendedFetch
Returns multiple of result rows.
SQLForeignKeys
Returns a list of column names that comprise foreign keys, if they exist for
a specified table.
SQLMoreResults
Determines whether there are more result sets available and if so,
initializes processing for the next result set.
SQLNativeSql
Returns the text of an SQL statement as translated by the driver.
SQLNumParams
Returns the number of parameters in a statement.
SQLParamOptions
Specifies the use of multiple values for parameters.
SQLPrimaryKeys
Returns the list of column name or names that comprise the primary key
for a table.
SQLProcedureColumns
Returns the list of input and output parameters, as well as the columns
that make up the result set for the specified procedures.
SQLProcedures
Returns the list of procedure names stored in a specific data source.
SQLSetPos
Positions a cursor within a fetched block of data.
SQLTablePrivileges
Returns a list of tables and the privileges that are associated with each
table.

Parameter markers: Parameter markers act as place holders for values that are
supplied by the program when you instruct the data source to run the SQL
statement. When you use SQLPrepare, the statement that contains the parameter
markers is passed to the data source to be prepared by the SQL “Optimizer” on
page 214. The Optimizer builds a plan of the statement and holds it for later
reference. Each parameter marker must be associated with a program variable
(strictly, a pointer to a program variable), and SQLBindParameter is used for this
purpose.

SQLBindParameter is a complex function. Careful study of the relevant section in


the Microsoft ODBC Software Development Kit and Programmer’s Reference ISBN

Chapter 3. Express C/C++ APIs 197


1-57231-516-4 is strongly recommended. For most SQL statements, using
SQLBindParameter provides input information to the function, but with stored
procedures it also can receive data back.

After you have prepared the statement and bound the parameters, use
SQLExecute to set to the data source the current values of the associated variables.

SQLBindCol and SQLFetch: SQLBindCol provides a way of associating program


variables with the returned columns of a row resulting from the call to SQLFetch,
after an SQL select statement has been run at the data source.

SQLBindCol must be run before SQLFetch.

SQLFetch and SQLGetData: SQLGetData provides an alternative to SQLBindCol


to retrieve data from the columns of a retrieved row. It must be run after
SQLFetch.

As a general rule, SQLBindCol is preferable to SQLGetData. There is less


performance overhead; you need to run SQLBindCol only once rather than after
every fetch. However, there are special considerations for using SQLBindCol in
Visual Basic.

Visual Basic moves character strings to different locations to conserve memory. If a


string variable is bound to a column, the memory that is referenced by a
subsequent SQLFetch may not place the data in the desired variable. It is likely
that a General Protection Fault will result. A similar problem can occur with
SQLBindParameter.

Using strings in Visual Basic is not recommended. One way to avoid this problem
is to use byte arrays. Byte arrays are of a fixed size and are not subject to
movement in memory.

Another circumvention is to employ Windows memory allocation API functions


that are documented in the Microsoft Development Library Knowledge Base.
However, this method involves some difficult programming that is not totally
transportable between Windows 3.1 and later releases.

Using SQLGetData rather than SQLBindCol and SQLParamData and


SQLPutData in conjunction with SQLBindParameter produce software that is
more in keeping with Visual Basic.

SQLError: SQLError returns error or status information. An application typically


calls SQLError after a call to an ODBC function has returned SQL_ERROR or
SQL_SUCCESS_WITH_INFO. However, it is acceptable to call SQLError after any
return code. Some function calls may generate multiple errors, in which case
SQLError may be called repeatedly to retrieve information about each error.

As well as posting standard ODBC SQLSTATE information, SQLError also will


retrieve integrated error codes and messages from the data source.
Argument Use Description
henv Input Environment handle or SQL_NULL_HENV.
hdbc Input Connection handle or SQL_NULL_HDBC.
hstmt Input Statement handle or SQL_NULL_HSTMT.
szSqlState Output SQLSTATE as null-terminated string.
pfNativeError Output Native error code (specific to the data source).
szErrorMsg Output Pointer to storage for the error message text.
cbErrorMsgMax Input Maximum length of the szErrorMsg buffer.

198 Client Access Express Programming


This must be less than or equal to
SQL_MAX_MESSAGE_LENGTH - 1.
pcbErrorMsg Output Pointer to the total number of bytes
(excluding the null termination byte)
available to return in szErrorMsg.

Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA_FOUND, SQL_ERROR,
or SQL_INVALID_HANDLE.
v “Using SQLError”
v “Client Access ODBC error messages” on page 165
v “Sample use of SQLError with Visual Basic”
v “Example: Visual Basic general error handler” on page 200

Using SQLError:
v SQLError can be used after any ODBC function call:
v To obtain error information after a function returns
– SQL_ERROR
– SQL_SUCCESS_WITH_INFO
v Functions can post multiple errors
– Keep calling SQLError while it returns SQL_SUCCESS

The type of error information that is returned by SQLError depends on the


contents of the handle parameters. If the error occurs before the handles are all
allocated, it is still possible to call SQLError, but the handles have to be set as
follows:
v To retrieve errors that are associated with the environment, pass in the value of
henv, and set hdbc to SQL_NULL_HDBC and hstmt to SQL_NULL_HSTMT.
v To retrieve errors that are associated with a connection, pass in the value of
hdbc, and set hstmt to SQL_NULL_HSTMT. The value of henv is ignored.
v To retrieve errors that are associated with a particular statement, pass in hstmt.
The values of henv and hdbc are ignored.
v “Sample use of SQLError with Visual Basic”

Sample use of SQLError with Visual Basic: This is a simple example of using
SQLError to determine whether the attempt to insert a new row has been
successful. Note that SQLState of S1000 indicates a General Error. It may not be
the result of a duplicate key value being detected. An alternate method is to query
the data source for the number of rows that were affected by the previous function.
Do this by calling the function SQLRowCount.
Dim result As Integer
Dim SQLState As String * 5
Dim NativeErrorCode As Long
Dim ErrorMsg As String * SQL_MAX_MESSAGE_LENGTH
Dim pcbErrorMsg As Integer

' Run the SQL statement


rc = SQLExecDirect(hstmt, SQLStmt, Len(SQLStmt))
If rc <> SQL_SUCCESS Then
result = SQLError(henv, hdbc, hstmt, SQLState, NativeErrorCode, ErrorMsg,
SQL_MAX_MESSAGE_LENGTH - 1, pcbErrorMsg)
If SQLState = "S1000" Then
MsgBox "Cheque number already used!", MB_ICONEXCLAMATION, Cheque Entry"
End If
End If

Chapter 3. Express C/C++ APIs 199


Example: Visual Basic general error handler: This following example shows an
attempt to provide a general error handler for use in Visual Basic ODBC
applications. Similar C code can be found in the worked example.

The routine is designed to be called after any ODBC function has failed to return
SQL_SUCCESS. It will retrieve any stacked error information and display it in a
message box.

This is example represents a simple general error handler. It is less sophisticated


than those that are found in typical finished applications.
Sub DspSQLError (henv As Long, hdbc As Long, hstmt As Long, UserMsg As String)
' Uses SQLError() to return error or status message to the user via Msg Box
Dim rc As Integer
Dim SQLState As String * 5
Dim NativeErrorCode As Long
Dim ErrorMsg As String * SQL_MAX_MESSAGE_LENGTH
Dim pcbErrorMsg As Integer
Dim MsgBoxText As String
' A statement run may lead to several errors being posted
' SQLError will retrieve each one, itself returning SQL_SUCCESS
rc = SQLError(henv, hdbc, hstmt, SQLState, NativeErrorCode, ErrorMsg,
SQL_MAX_MESSAGE_LENGTH - 1, pcbErrorMsg)
If rc = SQL_NO_DATA_FOUND Then
MsgBox "Error information not available", MB_ICONEXCLAMATION, UserMsg
Else
If rc = SQL_ERROR Then
MsgBox "Error with SQLError", MB_ICONEXCLAMATION, UserMsg
End If
End If
While rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO
MsgBox Left$(ErrorMsg, pcbErrorMsg), MB_ICONEXCLAMATION, UserMsg
rc = SQLError(henv, hdbc, hstmt, SQLState, NativeErrorCode, ErrorMsg,
SQL_MAX_MESSAGE_LENGTH - 1, pcbErrorMsg)
If rc = SQL_ERROR Then
MsgBox "Error with SQLError", MB_ICONEXCLAMATION, UserMsg
End If
Wend
End Sub

Client Access ODBC APIs implementation issues and requirements: See the
following table for:
v Descriptions of how the Express ODBC Driver implements specific API functions
v API function requirements and options
Table 4. Implementation of ODBC API functions
Function Description
SQLConnect The data source name is required. Other values are optional.
SQLBrowseConnect Uses all keywords. See “ODBC connection strings and keywords”
on page 159. Only DSN is required. Other values are optional.
SQLDriverConnect Uses all keywords. See “ODBC connection strings and keywords”
on page 159. Only DSN is required. Other values are optional.
SQLSpecialColumns If called with the SQL_BEST_ROWID option, returns all indexed
columns of that table.

Related topic:
“ODBC API restrictions and unsupported functions”

ODBC API restrictions and unsupported functions: The way in which some functions
are implemented in the Client Access Express ODBC Driver does not meet the

200 Client Access Express Programming


specifications in the Microsoft ODBC Software Development Kit Programmer’s
Reference. The table below lists restrictions and unsupported functions:
Table 5. Limitations of ODBC API functions
Function Description
SQLCancel The Client Access ODBC driver does not support
asynchronous processing.
SQLCancel is equivalent to SQLFreeStmt
(hstmt,SQL_CLOSE).
SQLGetStmtOption SQLSetStmtOption with SQL_USE_BOOKMARKS is not supported.
and SQLSetStmtOption SQL_RETRIEVE_DATA always is set to SQL_RD_ON (default)
SQL_SIMULATE_CURSOR is not supported.
SQLExtendedFetch Open cursor for update then call SQLExtendedFetch is not
supported.
You cannot use SQLExtendedFetch in combination
with SQLSetPos and SQLGetdata.
SQL_FETCH_BOOKMARKS is not supported.
You cannot use SQLExtendedFetch to retrieve
result set for cataloging functions:
SQLTables, SQLSpecialColumns,
SQLStatistics, SQLColumns, SQLForeignKeys,
SQLPrimaryKeys
SQL_NOSCAN options are not supported.
SQLSetPos SQL_UPDATE, SQL_DELETE, SQL_ADD are not
supported.
SQL_LOCK_EXCLUSIVE, SQL_LOCK_UNLOCK are not
supported.
SQLSetScrollOption SQL_CONCUR_ROWVER, SQL_CONCUR_VALUES are not
supported.
SQL_SCROLL_KEYSET_DRIVEN will be changed to
SQL_SCROLL_DYNAMIC
SQLColumnPrivileges, Returns SQL_SUCCESS, then fetch returns
and SQLTablePrivileges SQL_NO_DATA_FOUND

Express ODBC performance


See any of the following ODBC performance topics:
v “Performance-tuning Client Access Express ODBC”
v “Performance considerations of common end-user tools” on page 205
v “SQL performance” on page 208
v “Coding directly to ODBC APIs” on page 216
v “ODBC blocked insert statement” on page 234
v “Catalog functions” on page 236
v “Exit programs” on page 237
v “Stored procedures” on page 253
v “Examples: Running CL commands using stored procedures” on page 265

Performance-tuning Client Access Express ODBC: A key consideration for


ODBC application developers is achieving maximum performance from
client/server applications. The following topics explore client/server performance
issues in general, and address the performance implications of ODBC with popular
query tools and development environments:
v “Introduction to system performance” on page 202
v “Introduction to client/server performance” on page 202
v “The performance architecture of the Client Access Express ODBC driver” on
page 203

Chapter 3. Express C/C++ APIs 201


Introduction to system performance: The performance characteristics of any
computing environment may be described in the following terms:
Response time
The amount of time that is required for a request to be processed
Utilization
The percentage of resources that are used when processing requests
Throughput
The volume of requests (per unit of time) that are being processed
Capacity
The maximum amount of throughput that is possible

Typically, response time is the critical performance issue for users of a system.
Utilization frequently is important to the administrators of a system. Maximum
throughput is indicative of the performance bottleneck, and may not be a concern.
While all of these characteristics are interrelated, the following summarizes system
performance:
v Every computing system has a bottleneck that governs performance:
throughput.
v When system utilization increases, response time degrades.

In many systems, capacity is considerable, and is not an issue with users. In others,
it is the primary performance concern. Response time is critical. One of the most
important questions for administrators is: How far can the system be degraded while
users are added, or utilization is increased, before users begin objecting?

Introduction to client/server performance: The performance characteristics of a


client/server environment are different than those of centralized environments.
This is because client/server applications are split between the client and the
server. The client and server communicate by sending and receiving requests and
messages. This model is far different than that for a centralized environment. In
that environment, a program calls the CPU, and the memory and disk drives are
fully dedicated.

Instead, when a client requests processing time and data from the server, it
transmits the request on the network. The request travels to the server and waits in
a queue until the server is able to process it. The performance characteristics of this
type of architecture degrade exponentially as the number of requests increase. In
other words, response times increase gradually as more requests are made, but
then increase dramatically at some point, which is known as the ″knee of the

202 Client Access Express Programming


curve.″ This concept is illustrated by the following graph:

It is important to determine this point at which performance begins to degrade


significantly. The point can vary with every client/server installation.

The following is a suggested guideline for client/server operations: Communicate


with the server only when necessary, and in as few data transmissions as possible.
Opening a file and reading one record at a time often results in problems for
client-server projects and tools.

The performance architecture of the Client Access Express ODBC driver: For the Client
Access Express ODBC driver, all of the internal data flows between the client and
the server are chained together, and transmit only when needed. This reduces
server utilization because communications-layer resources are allocated only once.
Response times improve correspondingly.

These types of enhancements are transparent to the user. But other enhancements
are externalized as configuration entries in the ODBC registry.
For additional information:
v “Setting up the Express ODBC driver” on page 138
v “ODBC registry settings”

ODBC registry settings: When you edit the configuration parameters in the ODBC
registry, the Client Access Express ODBC driver also is configured. This registry
file is in the directory where Windows is installed on your system. Do not edit the
registry directly. Instead, tune Client Access Express ODBC performance through
the Client Access Express ODBC Setup (32-bit) dialog.

For a description of these parameters and their allowed values, see “Setting up the
Express ODBC driver” on page 138. This topic explains the performance
implications of some of the more important parameters.
ODBC registry settings topics:
v “Selecting a stringent level of commitment control” on page 204
v “Fine-tuning record blocking” on page 204
v “Using Extended Dynamic SQL” on page 205

Chapter 3. Express C/C++ APIs 203


Selecting a stringent level of commitment control: Do not use commitment control
unnecessarily. The overhead that is associated with locking not only increases
utilization, but also reduces concurrency. However, if your application is not
read-only, commitment control may be required. A common alternative is to use
optimistic locking. Optimistic locking involves issuing explicit UPDATEs by using
a WHERE clause that uniquely determines a particular record. Optimistic locking
ensures that the record does not change after it is retrieved.

Many third-party tools use this approach, which is why they often require a
unique index to be defined for updatable tables. This allows the record update to
be made by fully qualifying the entire record contents. Consider the following
example:
UPDATE table SET C1=new_val1, C2=new_val2, C2=new_val3
WHERE C1=old_val1 AND C2=old_val2 AND C3=old_val3

This statement would guarantee that the desired row is accurately updated, but
only if the table contained only three columns, and each row was unique. A
better-performing alternative would be:
UPDATE table SET C1=new_val1, C2=new_val2, C3=CURRENT_TIMESTAMP
WHERE C3=old_timestamp

This only works, however, if the table has a timestamp column that holds
information on when the record was last updated. Set the new value for this
column to CURRENT_TIMESTAMP to guarantee row uniqueness.

Note: This technique does not work with any object model that uses automation
data types (for example, Visual Basic, Delphi, scripting languages). The
variant DATE data type has a timestamp precision of approximately one
millisecond. The AS/400 timestamp is either truncated or rounded off, and
the WHERE clause fails.

If commitment control is required, use the lowest level of record locking possible.
For example, use *CHG: over *CS when possible, and never use *ALL when *CS
provides what you require.
For more information on commitment control:
See the DB2 Universal Database for AS/400 and DB2 Universal Database
for AS/400 books online topics under the Database and File Systems
heading in the AS/400 Information Center.

Fine-tuning record blocking: Record blocking is a technique that significantly


reduces the number of network flows. It does this by returning a block of rows
from the server on the first FETCH request for a cursor. Subsequent FETCH
requests are retrieved from the local block of rows, rather then going to the server
each time. This technique dramatically increases performance when it is properly
used. The default settings should be sufficient for most situations.

A change to one of the record-blocking parameters can make a significant


difference when the performance of your environment is approaching the
exponential threshold that is illustrated in “Introduction to client/server
performance” on page 202. For example, assume that an environment has n
decision-support clients doing some amount of work with large queries, typically
returning 1 MB of data. When using the default BlockSizeKB parameter of 32 KB,
each time a user queries the database, it takes 32 trips between the server and the
client to return the data. Changing the BlockSizeKB value to 512 reduces the
number of server requests by a factor of 15. It might make the difference between
being under the exponential threshold or up against it.

204 Client Access Express Programming


At the opposite extreme is a scenario where users consistently ask for large
amounts of data, but typically never examine more than a few rows. The overhead
of returning 32KB of rows when only a few are needed could degrade
performance. Setting the BlockSizeKB parameter to a lower value, or even disabling
record blocking altogether, might actually increase performance.

It is important to note that, as always in client/server, performance results may


vary. You might make changes to these parameters and not realize any difference.
This may indicate that your performance bottleneck is not the client request queue
at the server. This parameter gives you one more tool to use when your users start
objecting.

Using Extended Dynamic SQL: Traditional SQL interfaces used an embedded SQL
approach. SQL statements were placed directly in an application’s source code,
along with high-level language statements written in C, COBOL, RPG, and other
programming languages. The source code then was precompiled, which translated
the SQL statements into code that the subsequent compile step could process. This
method sometimes was referred to as static SQL. One performance advantage to
this approach is that SQL statements were optimized in advance, rather than at
runtime while the user was waiting.

ODBC, however, is a call level interface (CLI) that uses a different approach.
Using a CLI, SQL statements are passed to the database management system
(DBMS) within a parameter of a runtime API. Because the text of the SQL
statement is never known until runtime, the optimization step must be performed
each time an SQL statement is run. This approach commonly is referred to as
dynamic SQL.

A good description of the ExtendedDynamic parameter in the Client Access


Express ODBC driver is in the “Configuring Package(s) options” on page 147 topic.
The use of this feature (which is enabled by default) not only can improve
response times, but can improve dramatically server utilization. This is because
optimizing SQL queries can be costly, and performing this step only once always is
advantageous. This works well with a unique feature of DB2 UDB for
AS/400.Unlike other DBMSs, it ensures that statements which are stored in
packages are kept up-to-date in terms of optimization, without administrator
intervention. Even if a statement was prepared for the first time weeks or months
ago, DB2 UDB for AS/400 automatically regenerates the access plan when it
determines that sufficient database changes require reoptimization.

Performance considerations of common end-user tools: Having an ODBC driver


that is optimally tuned is only part of the performance equation. The other part is
the tools that are used; whether they are used simply to query the data, or to build
complex programs.

Some of the more common tools include:


v Crystal Services Crystal Reports Professional
v Cognos Impromptu
v Gupta SQL Windows
v IBM Visualizer for Windows
v Lotus Approach
v Lotus Notes®
v Notes Pump
v Microsoft Access
v Microsoft Internet Information Server
v Microsoft SQL Server

Chapter 3. Express C/C++ APIs 205


v Microsoft Visual Basic
v Powersoft PowerBuilder

There are many more tools available than are on this list, and every tool in the
marketplace has its own strengths, weaknesses, and performance characteristics.
But most have one thing in common: support for ODBC database servers.
However, because ODBC serves as a common denominator for various database
management systems, and because there are subtle differences from one ODBC
driver to the next, many tool providers write to the more common ODBC and SQL
interfaces. By doing this, they avoid taking advantage of a unique characteristic of
a particular database server. This may ease programming efforts, but it often
degrades overall performance.
Examples of ODBC performance-degrading tools:
“Examples: Common tool behaviors that degrade ODBC performance”

Examples: Common tool behaviors that degrade ODBC performance: The following
examples demonstrate performance problems that are associated with writing SQL
and ODBC calls that do NOT take advantage of a unique feature of a particular
ODBC driver or the server database management system.
To view the examples:
v “Example: Query tool A”
v “Example: Query tool B” on page 207
v “Example: Query tool C” on page 207

Example: Query tool A: Query Tool A makes the following ODBC calls to process
SELECT statements:
SqlExecDirect("SELECT * FROM table_name")

WHILE there_are_rows_to_fetch DO

SqlFetch()
FOR every_column DO
SqlGetData( COLn )
END FOR
...process the data

END WHILE

This tool does not make use of ODBC bound columns, which can help
performance. A faster way to process this is as follows:
SqlExecDirect("SELECT * FROM table_name")
FOR every_column DO
SqlBindColumn( COLn )
END FOR

WHILE there_are_rows_to_fetch DO
SqlFetch()
...process the data
END WHILE

If a table contained one column, there would be little difference between the two
approaches. But for a table with a 100 columns, you end up with 100 times as
many ODBC calls in the first example, for every row fetched. You also can optimize
the second scenario because the target data types specified by the tool will not
change from one FETCH to the next, like they could change with each SqlGetData
call.

206 Client Access Express Programming


Example: Query tool B: Query tool B allows you to update a spreadsheet of rows
and then send the updates to the database. It makes the following ODBC calls:
FOR every_row_updated DO

SqlAllocStmt()
SqlExecDirect("UPDATE...SET COLn='literal'...WHERE COLn='oldval'...")
SqlFreeStmt( SQL_DROP )

END LOOP

The first thing to note is that the tool performs a statement allocation-and-drop for
every row. Only one allocate statement is needed, and the free-statement call could
be changed to SqlFreeStmt( SQL_CLOSE ) after each SqlExecDirect. This change
would save the overhead of creating and destroying a statement handle for every
operation. Another performance concern is the use of SQL with literals instead of
with parameter markers. The SqlExecDirect() call causes an SqlPrepare and
SqlExecute every time. Because the UPDATE uses only literals, ExtendedDynamic
will not help because the statement is discarded after the SQL_DROP. A faster way
to perform this operation would be as follows:
SqlAllocStmt()
SqlPrepare("UPDATE...SET COL1=?...WHERE COL1=?...")
SqlBindParameter( new_column_buffers )
SqlBindParameter( old_column_buffers )
FOR every_row_updated DO

...move each rows data into the SqlBindParameter buffers


SqlExecute()
SqlFreeStmt( SQL_CLOSE )

END LOOP

These sets of ODBC calls will outperform the original set by a large factor when
you are using the Client Access ODBC driver. The server CPU utilization will
decrease to 10 percent of what it was, which pushes the scaling threshold out a lot
farther.

Example: Query tool C: Worst-case scenario

Query tool C allows complex decision support-type queries to be made by defining


complex query criteria with a point-and-click interface. You might end up with
SQL that looks like this for a query:
SELECT A.COL1, B.COL2, C.COL3 , etc...
FROM A, B, C, etc...
WHERE many complex inner and outer joins are specified

That you did not have to write this complex query is advantageous, but beware
that your tool may not actually process this statement. For example, one tool might
pass this statement directly to the ODBC driver, while another splits up the query
into many individual queries, and processes the results at the client, like this:
SQLExecDirect("SELECT * FROM A")
SQLFetch() all rows from A
SQLExecDirect("SELECT * FROM B")
SQLFetch() all rows from B

Process the first join at the client

SQLExecDirect("SELECT * FROM C")


SQLFetch() all rows from C

Process the next join at the client

Chapter 3. Express C/C++ APIs 207


.
.
.
And so on...

This approach can lead to excessive amounts of data being passed to the client,
which will adversely affect performance. In one real-world example, a programmer
thought that a 10-way inner/outer join was being passed to ODBC, with four rows
being returned. What actually was passed, however, was 10 simple SELECT
statements and all the FETCHes associated with them. The net result of four rows
was achieved only after 81,000 ODBC calls were made by the tool. The
programmer initially thought that ODBC was responsible for the slow
performance, until the ODBC trace was revealed.

SQL performance: Good application design includes the efficient use of machine
resources. To run in a manner that is acceptable to the end user, an application
program must be efficient in operation, and must run with adequate response time.
“SQL performance general considerations”
Shows you when to consider performance, what resources to optimize, and
how to design for performance.
“Database design” on page 209
Describes general AS/400 database design and how it affects SQL
performance.
“Optimizer” on page 214
Optimizer is the facility that decides how to gather data that should be
returned to the program. This topic covers some of the techniques and
rules that are used by Optimizer.

SQL performance general considerations: Performance of SQL in application


programs is important to ALL system users, because inefficient usage of SQL can
waste system resources.

The primary goal in using SQL is to obtain the correct results for your database
request, and in a timely manner.

Before you start designing for performance, review the following considerations:
When to consider performance:
v Database with over 10,000 rows - Performance impact: noticeable
v Database with over 100,000 rows - Performance impact: concern
v When repetitively using complex queries
v When using multiple work stations with high transaction rates
What resource to optimize:
v I/O usage
v CPU usage
v Effective usage of indexes
v OPEN/CLOSE performance
v Concurrency (COMMIT)
How to design for performance:
Database design:
– Table structure
– Indexes

208 Client Access Express Programming


– Table data management
– Journal management
Application design:
– Structure of programs involved
Program design:
– Coding practices
– Performance monitoring

The SQL Reference book contains additional information. You can view an HTML
online version of the book, or print a PDF version, from the DB2 Universal
Database for AS/400 books online AS/400 Information Center topic.

Database design: The following topics help you to:


v Determine what tables you require in your database
v Understand the relationship between those tables
Database design topics:
v “Normalization”
v “Table size” on page 212
v “Using indexes” on page 212
v “Matching attributes of join fields” on page 213

Normalization: Several available design methods allow you to design technically


correct databases, and effective relational database structure. Some of these
methods are based on a design approach called normalization. Normalization
refers to the reduction or elimination of storing redundant data. The primary
objective of normalization is to avoid problems that are associated with updating
redundant data.

However, this design approach of normalization (for example, 3NF–3rd Normal


Form), may result in large numbers of tables. If there are numerous table join
operations, SQL performance may be reduced. Consider overall SQL performance
when you design databases. Balance the amount of redundant data with the
number of tables that are not fully normalized.

The following graphic illustrates that the proportion of redundant data to the
number of tables affects performance:

Chapter 3. Express C/C++ APIs 209


Minimize the use of code tables when little is gained from their use. For example,
an employee table contains a JOBCODE column, with data values 054, 057, and so
forth. This table must be joined with another table to translate the codes to
Programmer, Engineer, and so on. The cost of this join could be quite high
compared to the savings in storage and potential update errors resulting from
redundant data.

For example:

210 Client Access Express Programming


Normalized data form:

Chapter 3. Express C/C++ APIs 211


Redundant data form:

The set level (or mass operation) nature of SQL significantly lessens the danger of
a certain redundant data form. For example, the ability to update a set of rows
with a single SQL statement greatly reduces this risk. In the following example, the
job title Engineer must be changed to Technician for all rows that match this
condition.
Example: Use SQL to update JOBTITLE:
UPDATE EMPLOYEE
SET JOBTITLE = "Technician"
WHERE JOBTITLE = "Engineer"

Table size: The size of the tables that your application program accesses has a
significant impact on the performance of the application program. Consider the
following:
Large row length:
For sequenially accessed tables that have a large row length because of
many columns (100 or more), you may improve performance by dividing
the tables into several smaller ones, or by creating a view. This assumes
that your application is not accessing all of the columns. The main reason
for the better performance is that I/O may be reduced because you will get
more rows per page. Splitting the table will affect applications that access
all of the columns because they will incur the overhead of joining the table
back together again. You must decide where to split the table based on the
nature of the application and frequency of access to various columns.
Large number of rows:
If a table has a large number of rows, construct your SQL statements so
that the “Optimizer” on page 214 uses an index to access the table. The use
of indexes is very important for achieving the best possible performance.

Using indexes: The use of indexes can improve significantly the performance of
your applications. This is because the “Optimizer” on page 214 uses them for
performance optimization. Indexes are created in five different ways:

212 Client Access Express Programming


v CREATE INDEX (in SQL)
v CRTPF, with key
v CRTLF, with key
v CRTLF, as join logical file
v CRTLF, with select/omit specifications, without a key, and without dynamic
selection (DYNSLT).

Indexes are used to enable row selection by means of index-versus-table scanning,


which is usually slower. Table scanning sequentially processes all rows in a table. If
a permanent index is available, building a temporary index can be avoided.
Indexes are required for:
v Join tables
v ORDER BY
v GROUP BY

Indexes will be created, if no permanent index exists.

Manage the number of indexes to minimize the extra system cost of maintaining
the indexes during update operations. Below are general rules for particular types
of tables:
Primarily read-only tables:
Create indexes over columns as needed. Consider creating an index only if
a table is greater than approximately 1,000 rows or is going to be used
with ORDER BY, GROUP BY, or join processing. Index maintenance could
be costlier than occasionally scanning the entire table.
Primarily read-only table, with low update rate:
Create indexes over columns as needed. Avoid building indexes over
columns that are updated frequently. INSERT, UPDATE, and DELETE will
cause maintenance to all indexes related to the table.
High update-rate tables:
Avoid creating many indexes. An example of a table that has a high
update rate is a logging or a history table.

Matching attributes of join fields: Columns in tables that are joined should have
identical attributes: the same column length, same data type (character, numeric),
and so forth. Nonidentical attributes result in temporary indexes being built, even
though indexes over corresponding columns may exist.

In the following example, join will build a temporary index and ignore an existing
one:
SELECT EMPNO, LASTNAME, DEPTNAME
FROM TEMPL, TDEPT
WHERE TEMPL.DEPTNO = TDEPT.DEPTNO

Chapter 3. Express C/C++ APIs 213


Optimizer: Optimizer is an important module of the OS/400 Query component
because it makes the key decisions for good database performance. Its main
objective is to find the most efficient access path to the data.

Query optimization is a trade-off between the time spent to select a query


implementation and the time spent to run it. Query optimization must handle the
following distinct user needs:
v Quick interactive response
v Efficient use of total-machine resources

In deciding how to access data, Optimizer does the following:


v Determines possible implementations
v Picks the optimal implementation for the OS/400 Query component to execute
Optimizer topics:
v “Cost estimation”
v “Optimizer decision-making rules” on page 215

Cost estimation: At runtime, the Optimizer chooses an optimal access method for
the query by calculating an implementation cost based on the current state of the
database. The Optimizer models the access cost of each of the following:
v Reading rows directly from the table (dataspace scan processing)
v Reading rows through an access path (using either key selection or key
positioning)
v Creating an access path directly from the dataspace
v Creating an access path from an existing access path (index-from-index)
v Using the query sort routine (if conditions are satisfied)

The cost of a particular method is the sum of:


v The start-up cost
v The cost associated with the given optimization mode. The OPTIMIZE FOR n
ROWS clause indicates to the query Optimizer the optimization goal to be
achieved. The Optimizer can optimize SQL queries with one of two goals:
1. Minimize the time required to retrieve the first buffer of rows from the table.
This goal biases the optimization towards not creating an index.

Note: This is the default if you do not use OPTIMIZE FOR n ROWS.

Either a data scan or an existing index is preferred. This mode can be


specified by:
The OPTIMIZE FOR n ROWS allowing the users to specify the number of
rows they expect to retrieve from the query.

214 Client Access Express Programming


The Optimizer using this value to determine the percentage of rows that
will be returned and optimizes accordingly. A small value instructs the
Optimizer to minimize the time required to retrieve the first n rows.
2. Minimize the time to process the whole query assuming that all selected
rows are returned to the application. This does not bias the Optimizer to any
particular access method. Specify this mode by using OPTIMIZE FOR n
ROWS, which allows the users to specify the number of rows they expect to
retrieve from the query.
The Optimizer uses this value to determine the percentage of rows that will
be returned and optimizes accordingly. A value greater than or equal to the
expected number of resulting rows instructs the Optimizer to minimize the
time required to run the entire query.
v The cost of any access path creations.
v The cost of the expected number of page faults to read the rows and the cost of
processing the expected number of rows.
Page faults and number of rows processed may be predicted by statistics the
Optimizer obtains from the database objects, including:
– Table size
– Row size
– Index size
– Key size
A weighted measure of the expected number of rows to process. This is based
on what the relational operators in the row selection predicates (default filter
factors) are likely to retrieve:
– 10% for equal
– 33% for less-than, greater-than, less-than-equal-to, or greater-than-equal-to
– 90% for not equal
– 25% for BETWEEN range
– 10% for each IN list value
Key range estimate is a method that the Optimizer uses to gain more accurate
estimates of the number of expected rows that are selected from one or more
selection predicates. The Optimizer estimates by applying the selection
predicates against the left-most keys of an existing index. The default filter
factors then can be further refined by the estimate based on the key range. If the
left-most keys in an index match columns that are used in row-selection
predicates, use that index to estimate the number of keys that match the
selection criteria. The estimate of the number of keys is based on the number of
pages and key density of the machine index. It is performed without actually
accessing the keys. Full indexes over columns that are used in selection
predicates can significantly help optimization.

Optimizer decision-making rules: In performing its function, Optimizer uses a


general set of guidelines to choose the best method for accessing data. Optimizer
does the following:
v Determines the default filter factor for each predicate in the selection clause.
v Extracts attributes of the table from internally stored information.
v Performs an estimate key range to determine the true filter factor of the
predicates when the selection predicates match the left-most keys of an index.
v Determines the cost of creating an index over a table if an index is required.

Chapter 3. Express C/C++ APIs 215


v Determines the cost of using a sort routine if selection conditions apply and an
index is required.
v Determines the cost of dataspace scan processing if an index is not required.
v For each index available, in the order of most recently created to oldest,
Optimizer does the following until its time limit is exceeded:
– Extracts attributes of the index from internally stored statistics.
– Determines if the index meets the selection criteria.
– Determines the cost of using the index using the estimated page faults and
the predicate filter factors to help determine the cost.
– Compares the cost of using this index with the previous cost (current best).
– Selects the cheapest one.
– Continues to search for best index until time out or no more indexes.

The time limit factor controls how much time is spent choosing an implementation.
It is based on how much time has been spent and the current best implementation
cost found. Dynamic SQL queries are subject to Optimizer time restrictions. Static
SQL queries optimization time is not limited.

For small tables, the query Optimizer spends little time in query optimization. For
large tables, the query Optimizer considers more indexes. Generally, Optimizer
considers five or six indexes (for each table of a join) before running out of
optimization time.

Coding directly to ODBC APIs: Many PC applications make ODBC calls that
allow the user to seamlessly access data on different platforms. Before you begin
developing your own application with ODBC APIs, you should understand how
an ODBC application connects to and exchanges information with a database
server.

There are Express ODBC APIs that:


v Set up the ODBC environment
v Establish and end connections to data sources
v Execute SQL statements
v Clean up the ODBC environment
Coding directly to ODBC APIs topics:
v “Using large objects (LOBs) and DataLinks with Express ODBC”
v “Accessing a database server with an ODBC application” on page 218
v “Establishing ODBC connections” on page 218
v “Executing ODBC functions” on page 219
v “Executing prepared statements” on page 220
v “Retrieving results” on page 222
v “Calling stored procedures” on page 223
v “Calling stored procedures using result sets” on page 224
v “Extended fetch” on page 226
v “Block inserts” on page 227
v “Ending ODBC functions” on page 231
v “VB 5.0: The compromise between Jet and ODBC APIs” on page 232

Using large objects (LOBs) and DataLinks with Express ODBC:

216 Client Access Express Programming


Large objects (LOBs):
Large object (LOB) data types allow applications to store large (up to 15
megabytes) data objects as strings. Use LOBs with Express ODBC to store
and access large text documents and multimedia data types. LOBs are
available when connecting with a V4R4 or later AS/400.
LOB data types:
BLOB Binary large data objects
CLOB Single-byte large character data objects
DBCLOB
Double-byte character large data objects
To view an example that uses the BLOB data type:
See “Example: Using the BLOB data type”
For more information on LOBs:
See the Using Large Objects topic under the Using the
Object-Relational Capabilities heading in the SQL Programming
Concepts Information Center topic.
DataLinks:
DataLink data types allow you to store many types of data in a database.
Data is stored as a uniform resource locator (URL). The URL points to an
object, which might be an image file, sound file, text file, and so forth.
For more information on DataLinks:
See the Using DataLinks topic under the Using the
Object-Relational Capabilities heading in the SQL Programming
Concepts Information Center topic.
Related topic:
See “ODBC-to-AS/400 data mapping” on page 163

Example: Using the BLOB data type: The following is a partial C program that uses
the BLOB data type:
unsigned int blob_len = 20, char_len = 10;

// Create a table with a CHAR field and a BLOB field


rc = SQLExecDirect(hstmt, "CREATE TABLE TABBLOB(COL1 CHAR(100), COL2 BLOB(40000)", SQL_NTS);

strcpy(szCol1,"1234567890");
strcpy(szCol2, "abcdefghijklmnopqrst");

if (!parameter_markers) // no parameter markers


wsprintf(stmt, "INSERT INTO TABBLOB VALUES('%s', BLOB(x'%s'))", szCol1, szCol2);
else
strcpy(stmt, "INSERT INTO TABBLOB VALUES(?,?)");

// Prepare the 'Insert' statement


rc = SQLPrepare(hstmt, stmt, SQL_NTS);

// Bind the parameter markers


if (parameter_markers) // using parameter markers
{
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,SQL_CHAR, char_len, 0, szCol1, char

cbCol2 = 20;
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, blob_len, 0,
}

// Execute the 'Insert' statement to put a row of data into the table
rc = SQLExecute(hstmt);

Chapter 3. Express C/C++ APIs 217


// Prepare and Execute a 'Select' statement
rc = SQLExecDirect(hstmt,"SELECT * FROM TABBLOB",SQL_NTS);

// Bind the columns


rc = SQLBindCol(hstmt,1,SQL_C_CHAR,szRecCol1,char_len+1,&cbCol1);
rc = SQLBindCol(hstmt,2,SQL_C_BINARY,szRecCol2,blob_len,&cbCol2);

// Fetch the first row


rc = SQLFetch(hstmt);

// At this point szRecCol1 should contain the CHAR data and szRecCol2 should contain the BLOB data th

Accessing a database server with an ODBC application: An ODBC application needs


to follow a basic set of steps in order to access a database server:
1. Connect to the data source.
2. Place the SQL statement string to be executed in a buffer. This is a text string.
3. Submit the statement in order that it can be prepared or immediately run.
v Retrieve and process the results.
v If there are errors, retrieve the error information from the driver.
4. End each transaction with a commit or rollback operation (if necessary).
5. Terminate the connection.

Establishing ODBC connections:


SQLAllocEnv
v Allocates memory for an environment handle.
– Identifies storage for global information:
- Valid connection handles
- Current active connection handles
- Variable type HENV
- Application uses a single environment handle.
v Initializes the ODBC call level interface for use by an application.
v Must be called by application prior to calling any other ODBC function.
v Variable type HENV is defined by ODBC in the SQL.H header file
provided by the C programming language compiler or by the ODBC
Software Development Kit (SDK).
The header file contains a type definition for a far pointer:
typedef void far * HENV
v In C programming language this statement is coded:
HENV henv;
SQLAllocEnv(&henv);
v In Visual Basic, this statement is coded:
Dim henv As long
SQLAllocEnv(henv)
SQLAllocConnect
v Allocates memory for an connection handle within the environment.
– Identifies storage for information about a particular connection.
- Variable type HDBC
- Application can have multiple connection handles.
v Application must request a connection handle prior to connecting to the
data source.

218 Client Access Express Programming


v In C, this statement is coded:
HDBC hdbc;
SQLAllocConnect(henv,&hdbc);
v In Visual Basic, this statement is coded:
Dim hdbc As long
SQLAllocConnect(henv,hdbc)
SQLConnect
v Loads driver and establishes a connection.
v Connection handle references information about the connection.
v Data source is coded into application.
v In this example, user ID and password are blank because they are
supplied by the Client Access router.
UCHAR source[] = "DBFIL";
UCHAR uid[] = "";
UCHAR pwd[] = "";
SQLConnect(hdbc,source,SQL_NTS,uid,SQL_NTS,pwd,SQL_NTS);

Note: SQL_NTS indicates that the statement is ended with a


null-terminated string.
SQLDriverConnect
v Alternative to SQLConnect
v Allows driver manager to obtain login information from the user.
v Displays dialog boxes (optional).

Executing ODBC functions:


SQLAllocStmt
v Allocates memory for information about an SQL statement.
– Application must request a statement handle prior to submitting SQL
statements.
– Variable type HSTMT.
HSTMT s_create;
SQLAllocStmt(hdbc,&s_create);
SQLExecDirect
v Executes a preparable statement.
v Fastest way to submit an SQL string for one time execution.
v If rc is not equal to SQL_SUCCESS, an SQLError API call is used to find
the cause of the error condition.
UCHAR stmt[ ]
= "CREATE TABLE NAMEID (ID INTEGER,
NAME VARCHAR(50))";
rc = SQLExecDirect(s_create,stmt,SQL_NTS)
v Return code
– SQL_SUCCESS
– SQL_SUCCESS_WITH_INFO
– SQL_ERROR
– SQL_INVALID_HANDLE
SQLError
SQLError(henv,hdbc,s_create,szSqlState,&pfNativeError,
szErrorMsg,cbErrorMsg);

Chapter 3. Express C/C++ APIs 219


v szSqlState
– 5 character string
– 00000 = success
– 01004 = data truncated
– 07001 = wrong number of parameters
v pfNativeError - specific to data source
v szErrorMsg - Error Message text

Executing prepared statements: If an SQL statement is used more than once, it is


best to have the statement prepared and then executed. When a statement is
prepared, variable information can be passed as parameter markers, which are
denoted by question marks (?). When the statement is executed, the parameter
markers are replaced with the real variable information.

Preparing the statement is performed at the server. The SQL statements are
compiled and the access plans are built. This allows the statements to be executed
much more efficiently. When compared to using dynamic SQL to execute the
statements, the result is much closer to static SQL. When the database server
prepares the statements, it saves some of them in a special AS/400 object called a
package (*SQLPKG). This approach is called Extended Dynamic SQL. Packages
are created automatically by the driver; an option is provided to turn off Package
Support. This is covered in “The performance architecture of the Client Access
Express ODBC driver” on page 203.
SQLPrepare
Prepares an SQL statement for execution:
HSTMT s_insert;
SQLAllocStmt(hdbc,&s_insert);
UCHAR sqlstr[ ] "INSERT INTO NAMEID VALUES (?,?)";
SQLPrepare(s_insert,sqlstr,SQL_NTS);

Note: SQL_NTS indicates that the string is null-terminated.


SQLBindParameter
Allows application to specify storage, data type, and length associated with
a parameter marker in an SQL statement.
In the example, parameter 1 is found in a signed double word field called
id. Parameter 2 is found in an unsigned character array called name.
SDWORD id;
UCHAR name[51];
SQLBindParameter(s_insert,1,SQL_PARAM_INPUT,
SQL_C_LONG,SQL_INTEGER,
0,0,&id,0,NULL);
SQLBindParameter(s_insert,2,SQL_PARAM_INPUT,
SQL_C_CHAR,SQL_VARCHAR,
parmLength,0,
name,(UDWORD) sizeof(name), NULL);
SQLExecute
Executes a prepared statement, using current values of parameter markers:
id=500;
strcpy (name,"TEST");
SQLExecute(s_insert); // Insert a record with id = 500, name = "Test"
id=600;
strcpy (name,"ABCD");
SQLExecute(s_insert); // Insert a record with id = 600, name = "ABCD"

220 Client Access Express Programming


SQLParamData / SQLPutData
Visual Basic does not directly support pointers or fixed-location ANSI
character null-terminated strings. For this reason, it is best to use another
method to bind Character and Binary parameters. One method is to
convert Visual Basic String data types to/from an array of Byte data types
and bind the array of Byte. This method is demonstrated in “Converting
strings and arrays of byte”.
Another method, that should only be used for input parameters, is to
supply the parameters at processing time. This is done using
SQLParamData and SQLPutData APIs:
v They work together to supply parameters.
v SQLParamData moves the pointer to the next parameter.
v SQLPutData then supplies the data for that parameter.
's_parm is a character buffer to hold the parameters
's_parm(1) contains the first parameter
Static s_parm As string
s_parm(1) = "500"
s_parm(2) = "TEST"
cbvalue = SQL_DATA_AT_EXEC ' the parms will be supplied at run time

SQLBindParameter(s_insert,1,SQL_PARAM_INPUT,
SQL_C_CHAR,SQL_CHAR,
4,0,0,0&,4,cbvalue)
SQLBindParameter(s_insert,2,SQL_PARAM_INPUT,
SQL_C_CHAR,SQL_CHAR,
4,0,0,0&,4,cbvalue)

SQLExecute(s_insert)
SQLParamData(s_insert, &token) ' Param 1
SQLPutData(s_insert, Byval s_parm(1), Len (s_parm(1)))
SQLParamData(s_insert, &token) ' Param 2
SQLPutData(s_insert, Byval s_parm(2), Len (s_parm(2)))
SQLParamData(s_insert, &token) '* No more params, it will execute
Notes:
1. These two statements operate together to to supply unbound
parameter values when the statement is executed.
2. Each call to SQLParamData moves the internal pointer to the next
parameter for SQLPutData to supply data to. After the last
parameter is filled, SQLParamData must be called again for the
statement to be executed.
3. If SQLPutData supplies data for parameter markers, the parameter
must be bound. Use the cbValue parameter set to a variable whose
value is SQL_DATA_AT_EXEC when the statement is executed.

Converting strings and arrays of byte: The following Visual Basic functions can assist
in converting strings and arrays of byte:
Public Sub Byte2String(InByte() As Byte, OutString As String)
'Convert array of byte to string
OutString = StrConv(InByte(), vbUnicode)
End Sub

Public Function String2Byte(InString As String, OutByte() As Byte) As Boolean


'vb byte-array / string coercion assumes unicode string
'so must convert String to Byte one character at a time
'or by direct memory access

Dim I As Integer
Dim SizeOutByte As Integer

Chapter 3. Express C/C++ APIs 221


Dim SizeInString As Integer

SizeOutByte = UBound(OutByte)
SizeInString = Len(InString)
'Verify sizes if desired

'Convert the string


For I = 0 To SizeInString - 1
OutByte(I) = AscB(Mid(InString, I + 1, 1))
Next I
'If size byte array > len of string pad with Nulls for szString
If SizeOutByte > SizeInString Then 'Pad with Nulls
For I = SizeInString To SizeOutByte - 1
OutByte(I) = 0
Next I
End If

String2Byte = True
End Function

Public Sub ViewByteArray(Data() As Byte, Title As String)


'Display message box showing hex values of byte array

Dim S As String
Dim I As Integer
On Error GoTo VBANext

S = "Length: " & Str(UBound(Data)) & " Data (in hex):"


For I = 0 To UBound(Data) - 1
If (I Mod 8) = 0 Then
S = S & " " 'add extra space every 8th byte
End If
S = S & Hex(Data(I)) & " "
VBANext:
Next I
MsgBox S, , Title

End Sub

Retrieving results: Running some SQL statements returns results to the application
program. Running an SQL SELECT statement returns the selected rows in a result
set. The SQLFetch API then sequentially retrieves the selected rows from the result
set into the application program’s internal storage. In order to work with all of the
rows in a result set, call the SQLFetch API until no more rows are returned.

You also may issue a Select statement where you do not specify what columns you
want returned. For example, Select * from RWM.DBFIL selects all columns. You
may not know what columns or how many columns will be returned.
SQLNumResultCols
Returns the number of columns in a result set.
v A storage buffer that receives the information is passed as a parameter.
SQLNumResultCols(hstmt, &nresultcols);
SQLDescribeCol
Returns the result descriptor for one column in a result set.
v Column name
v Column type
v Column size
This is used with SQLNumResultCols to retrieve information about the
columns returned. Using this approach, as opposed to hard coding the
information in the program, makes for more flexible programs.

222 Client Access Express Programming


The programmer first uses SQLNumResultCols to find out how many
columns were returned in the result set by a select statement. Then a
loop is set up to use SQLDescribeCol to retrieve information about each
column.
SQLDescribeCol(hstmt, i + 1,colname,
(SWORD)sizeof(colname),
&colnamelen,&coltype,
&collen[i];, &scale, &nullable);
SQLBindCol
Assigns the storage and data type for a column in a result set:
v Storage buffer that receives the information.
v Length of storage buffer.
v Data type conversion.
SQLBindCol(hstmt, 1, SQL_C_LONG, &id, 0 ,Null);
SQLBindCol(hstmt, 2, SQL_C_CHAR, name,
(SDWORD) sizeof(name),
&namelen);

Note: If you use this with Visual Basic, it is recommended that you use an
array of Byte data type in place of String data types.
SQLFetch
Each time SQLFetch is called, the driver fetches the next row. Bound
columns are stored in the locations specified. Data for unbound columns
may be retrieved using SQLGetData.
SQLFetch(hstmt);

Visual Basic does not directly support pointers or fixed memory location
ANSI character null-terminated strings. For this reason, it is best to use
another method to bind Character and Binary parameters. One method is
to convert Visual Basic String data types to/from an array of Byte data
types and bind the array of Byte. Another method is to use the
SQLGetData function instead of SQLBindCol.
SQLGetData
Retrieves data for unbound columns after a fetch. In this example, four
columns are returned and SQLGetData is used to move them to the
correct storage location.
SQLFetch(s_Customer1)

SQLGetData(s_Customer1, 1, SQL_C_CHAR,
szName, 16, 0&)
SQLGetData(s_Customer1, 2, SQL_C_FLOAT,
&iDiscount, 0, 0&)
SQLGetData(s_Customer1, 3, SQL_C_CHAR,
szCredit, 2, 0&)
SQLGetData(s_Customer1, 4, SQL_C_FLOAT,
&iTax, 0, 0&)

Calling stored procedures: Use stored procedures to improve the performance and
function of an ODBC application. Any AS/400 program can act as a stored
procedure. AS/400 stored procedures support input, input/output and output
parameters. They also support returning result sets, both single and multiple. The
stored procedure program can return a result set by specifying a cursor to return
(from an embedded SQL statement) or by specifying an array of values. See
“Stored procedures” on page 253 for more information.

To call a stored procedure, complete the following steps:

Chapter 3. Express C/C++ APIs 223


1. Verify that the stored procedure has been declared by using the OS/400 SQL
statement CREATE PROCEDURE.

Detail: CREATE PROCEDURE should be executed only once for the life of the
stored procedure. DECLARE PROCEDURE also can be used, but this
method has several disadvantages. The Database Programming book
contains additional information about DECLARE PROCEDURE. View
an HTML online version of the book, or print a PDF version, from the
DB2 Universal Database for AS/400 books online topic in the AS/400
Information Center.
2. Prepare the call of the stored procedure by using SQLPrepare.
3. Bind the parameters for input and output parameters.
4. Execute the call to the stored procedure.
5. Retrieve the result set (if one is returned)

In this example, a COBOL program named NEWORD is called. A value in a


field named szCustId is passed, and it returns a value to a field named
szName.
HSTMT s_StoredProc;
char Query[320];
char szCustId[10];
char szName[30];
ret = SQLAllocStmt(hdbc,&s_StoredProc);

// Create the stored procedure definition.


// The create procedure could be moved to the application's
// install program so that it is only executed once.
strcpy(Query,"CREATE PROCEDURE NEWORD (:CID IN CHAR(10),
:NAME OUT CHAR(30) )");
strcat(Query," (EXTERNAL NAME NEWORD LANGUAGE
COBOL GENERAL WITH NULLS)");

// Create the stored procedure


ret=SQLExecDirect(s_StoredProc,(unsigned char *)Query,SQL_NTS);

strcpy(Query,"CALL NEWORD (?, ?)");

// Prepare the stored procedure call


ret=SQLPrepare(s_StoredProc,(unsigned char *)Query,SQL_NTS);

// Bind the parameters


ret=SQLBindParameter(s_StoredProc,1,SQL_PARAM_INPUT,
SQL_C_CHAR,SQL_VARCHAR, 10,0,
szCustId, 11, NULL);

ret=SQLBindParameter(s_StoredProc,2,SQL_PARAM_OUTPUT,
SQL_C_CHAR,SQL_VARCHAR, 30,0,
szName, 31, NULL);
strcpy (szCustId,"0000012345");
// Execute the stored procedure
ret=SQLExecute(s_StoredProc);

Calling stored procedures using result sets: Using result sets allows the client
program to easily retrieve large amounts of information returned by the stored
procedure. Instead of retrieving data from a large array of values in an output
parameter, the client can use the same methods that are used to retrieve data from
a SELECT statement. This results in a more SQL-like interface.

224 Client Access Express Programming


Note that the following examples contain the DROP PROCEDURE and CREATE
PROCEDURE statements for illustration purposes only. Once the procedure is
created, it can be called repeatedly.

This result sets example calls an RPG program and receives the data as a result set
array.

The program on the PC can issue the DROP PROCEDURE and CREATE
PROCEDURE statements before issuing a CALL procedure. After returning from
the call, do an ODBC SQLBindCol to set the variables to return data into. Then do
ODBC SQLFetch to get the data.

The following is a piece of code that shows the ODBC client calls:
#include "sql.h"
#include "sqlext.h"
#include "string.h"
/* declare the variables */
#define ROW_COUNT 20
UCHAR fetch_all[106];
SDWORD cbcol;
static HENV henv;
static HDBC hdbc;
static HSTMT hstmt;
char stmt[4000];
int ii;
RETCODE rc;
/* connect to a data source */
rc = SQLAllocEnv(&henv);
rc = SQLAllocConnect(henv, &hdbc);
rc = SQLConnect(hdbc, "SystemA", SQL_NTS,
"JohnB", SQL_NTS,
"Sesame", SQL_NTS);

/* allocate a statement handle */


SQLAllocStmt(hdbc,&hstmt);

/* drop the old procedure */


_fstrcpy(stmt,"DROP PROCEDURE RPGARY");
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);

/* create the procedure to call */


_fstrcpy(stmt,"CREATE PROCEDURE RPGARY RESULT SETS 1 EXTERNAL");
_fstrcat(stmt," NAME JMBLIB.RPGARY LANGUAGE RPG GENERAL");
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);

/* call stored procedure */


_fstrcpy(stmt,"CALL RPGARY()");
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
/* bind the columns to return variables */
SQLBindCol(hstmt, 1, SQL_C_CHAR, fetch_all, 106, &cbcol);

/* for each row fetch the data */


for(ii=0; ii<ROW_COUNT ;ii++)
{
rc = SQLFetch(hstmt);
/* process data */
}

/* get more results */


rc = SQLMoreResults(hstmt);

/* release the statement handle */


SQLFreeStmt(hstmt,SQL_DROP);

Chapter 3. Express C/C++ APIs 225


/* release the connection to the data source */
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);

The RPG program that is called by the procedure should declare an array to hold
the data. It then can open files and read the data into the array and do whatever
other processing needs to be done. Finally it can return the data in the array by
using the SQL SET RESULT SETS function.

The following is an example RPG program:


*-------------------------------------------------------------*
* *
* RPG PROGRAM: RPGARY *
* *
* PURPOSE: THIS RPG PROGRAM IS CALLED BY AN ODBC STORED *
* PROCEDURE. IT READS DATA INTO AN ARRAY AND *
* RETURNS THE RESULTS BY USING THE SET RESULT *
* SETS SQL FUNCTION *
* *
*-------------------------------------------------------------*
* FILE DESCRIPTION SPECIFICATIONS *
*-------------------------------------------------------------*
FPERF IF E DISK
*-------------------------------------------------------------*
* INPUT SPECIFICATIONS *
*-------------------------------------------------------------*
IPERFE E DSPERF
IARR DS 20
I 01 105 VAR1
ILCLVAR DS
I B 01 040L#
*-------------------------------------------------------------*
C* ** START OF PROGRAM ** *
*-------------------------------------------------------------*
C OPEN PERF
C Z-ADD0 L#
C LOOP TAG
C READ PERF 9999
C ADD 1 L#
C L# OCUR ARR
C MOVE PERFE ARR
C L# COMP 20 99 99
C N99 GOTO LOOP
*-------------------------------------------------------------*
*** EXECUTE SQL STATEMENT ***
C/EXEC SQL SET RESULT SETS ARRAY :ARR FOR :L# ROWS
C/END-EXEC
*-------------------------------------------------------------*
C CLOSEPERF
C RETRN

Extended fetch: Extended fetch and block inserts can be used to enhance the
performance of an ODBC application. They allow you to retrieve or insert entire
rows in blocks, rather than individually. This reduces the data flows and line
turnaround between the client and the server.
Extended fetch:
v Returns a block of data (one row set) in the form of an array for each
bound column.
v Scrolls through the result set according to the setting of a scroll type
argument; forward, backward, or by row number.
v Works in conjunction with the SQLSetStmtOption.

226 Client Access Express Programming


To fetch one row of data at a time in a forward direction, an application
should call SQLFetch:
HSTMT s_Item1;
char Query[320];
ret = SQLAllocStmt(hdbc,&s_Item1);
char ItemID[15][8] /*item return array*/
char ItemName[15][30] /*Name return array*/
float fItemPrice[15] /*price return array*/
char ItemData[15][60] /*data return array*/

ret = SQLAllocStmt(hdbc,&s_Item1);
strcpy(Query,"Select IID, INAME, IPRICE, IDATA from ITEM ");
strcat(Query,"where IID in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?)");
// For extended fetch
ret=SQLSetStmtOption(s_Item1,SQL_CONCURRRENCY,SQL_CONCUR_READ_ONLY);

Note: SQL_CONCUR_READ_ONLY is the default, so this statement could be


left out. However, if update was required then you would use
SQL_CONCUR_LOCK value as the last parameter.

ret=SQLSetStmtOption(s_Item1,SQL_CURSOR_TYPE,SQL_CURSOR_FORWARD_ONLY);

Note: SQL_CURSOR_FORWARD_ONLY is the default, so this statement could be


left out. However, if you wanted to scroll other then forward, you
could use this statement to set the option that you require.

ret=SQLSetStmtOption(s_Item1,SQL_ROWSET_SIZE,15);

Note: We will retrieve 15 rows.

// Prepares s_Item1 for use.


ret=SQLPrepare(s_Item1,(unsigned char *)Query,SQL_NTS);

// Sets the input parameters (the items to fetch).


// note s_parm is an array to hold items to be fetched

ret=SQLBindParameter(s_Item1, 1,SQL_PARAM_INPUT,SQL_C_CHAR,
SQL_CHAR,6,0,s_parm[ 1],6,NULL);
ret=SQLBindParameter(s_Item1, 2,SQL_PARAM_INPUT,SQL_C_CHAR,
SQL_CHAR,6,0,s_parm[ 2],6,NULL);
.
.
ret=SQLBindParameter(s_Item1,15,SQL_PARAM_INPUT,SQL_C_CHAR,
SQL_CHAR,6,0,s_parm[15],6,NULL);

// Bind the columns.


// Bind dependant of EFetch support.

ret=SQLBindCol(s_Item1, 1, SQL_C_CHAR, ItemID, 8, CheckID);


ret=SQLBindCol(s_Item1, 2, SQL_C_CHAR, ItemName, 30, CheckName);
ret=SQLBindCol(s_Item1, 3, SQL_C_FLOAT,fItemPrice, sizeof(float),
CheckPrice);
ret=SQLBindCol(s_Item1, 4, SQL_C_CHAR, ItemData, 60, CheckData);

//crow will show number of rows actually fetched


ret=SQLExtendedFetch(s_Item1,SQL_FETCH_FIRST,Ordercount,&crow,
fgrRowStatus);
// SQL_FETCH_NEXT
// SQL_FETCH_PREV
// SQL_FETCH_LAST

Block inserts: Block inserts allow you to:


v Insert blocks of records with one SQL call.
v Reduces the flows between the client and server.

Chapter 3. Express C/C++ APIs 227


See “ODBC blocked insert statement” on page 234 for additional information.
// Make ready for ORDLIN insert
strcpy(tmpbfr,"Insert into ORDLIN (OLOID, OLDID, OLWID, OLNBR,
OLSPWH, OLIID, OLQTY, OLAMNT, OLDLVD, OLDLVT, OLDSTI)
VALUES (?,?,?,?,?,?,?,?,?,?,?)");

ret= SQLPrepare(s_Ordlin1,(unsigned char far *)tmpbfr,SQL_NTS);

// Set the parameters.


//the storage areas that we are binding are arrays (lOrderNum,uiDistrict)
//we will fill these arrays with values before we execute
ret=SQLBindParameter(s_Ordlin1, 1,SQL_PARAM_INPUT,SQL_C_LONG ,
SQL_DECIMAL,9,0,&(lOrderNum);,9,NULL);
ret=SQLBindParameter(s_Ordlin1, 2,SQL_PARAM_INPUT,SQL_C_SHORT,
SQL_DECIMAL,3,0,&(uiDistrict);,3,NULL);
ret=SQLBindParameter(s_Ordlin1, 3,SQL_PARAM_INPUT,SQL_C_CHAR,
SQL_CHAR,4,0,szWid[0],4,NULL);

// Insert into ORDLIN


// m_OrderCount will contain the number of rows to insert
// rowcnt is a pointer to keep track of current row number
ret=SQLParamOptions(s_Ordlin1, m_OrderCount, &rowcnt);

// a loop is used to fill in the arrays with contain the data


// for the rows to be inserted
for(ol_ctr=1;ol_ctr<=NewOrd_IO->m_OrderCount;ol_ctr++){

// Fill parameters for block insert


lOrderNum[ol_ctr-1] = NewOrd_IO->m_OrderNum;
uiDistrict[ol_ctr-1] = NewOrd_IO->m_District;
strcpy(szWid[ol_ctr-1],s_parm[3]);
.
.
point to next order
}

ret=SQLExecute(s_Ordlin1); // Execute Order Line insert.

The next example is a Visual Basic block insert that is significantly faster than a
″parameterized″ insert.
Dim hStmt As Long
Dim cbNTS(BLKSIZE - 1) As Long 'NTS array

Dim lCustnum(BLKSIZE - 1) As Long

'2nd parm passed by actual length for demo purposes


Dim szLstNam(7, BLKSIZE - 1) As Byte 'NOT USING NULL ON THIS PARM
Dim cbLenLstNam(BLKSIZE - 1) As Long 'Actual length of string to pass
Dim cbMaxLenLstNam As Long 'Size of one array element

'These will be passed as sz string so size must include room for null
Dim szInit(3, BLKSIZE - 1) As Byte 'Size for field length + null
Dim szStreet(13, BLKSIZE - 1) As Byte 'Size for field length + null
Dim szCity(6, BLKSIZE - 1) As Byte 'Size for field length + null
Dim szState(2, BLKSIZE - 1) As Byte 'Size for field length + null
Dim szZipCod(5, BLKSIZE - 1) As Byte 'Size for field length + null

Dim fCdtLmt(BLKSIZE - 1) As Single


Dim fChgCod(BLKSIZE - 1) As Single
Dim fBalDue(BLKSIZE - 1) As Single
Dim fCdtDue(BLKSIZE - 1) As Single

Dim irow As Long '//row counter for block errors


Dim lTotalRows As Long '// ************ Total rows to send *************
Dim lNumRows As Long '// Rows to send in one block

228 Client Access Express Programming


Dim lRowsLeft As Long '// Number of rows left to send

Dim I As Long, j As Long


Dim S As String
Dim addr As Long 'check address of array element...

'************** Start *****************************************************


S = "Number of records to insert into QCUSTCDT. "
S = S & "Use menu option Table Mgmt, Create QCUSTCDT to "
S = S & "create the table. Use Misc, AS/400 Cmd and CLRPFM "
S = S & "command if you wish to clear it"
S = InputBox(S, gAppName, "500")
If Len(S) = 0 Then Exit Sub

lTotalRows = Val(S) 'Total number to insert

rc = SQLAllocStmt(ghDbc, hStmt)
If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert

rc = SQLPrepare(hStmt, _
"INSERT INTO QCUSTCDT ? ROWS VALUES (?,?,?,?,?,?,?,?,?,?,?)", _
SQL_NTS)
If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert

rc = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, _


10, 0, lCustnum(0), 0, ByVal 0)
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue

'Pass first parm w/o using a null


cbMaxLenLstNam = UBound(szLstNam, 1) - LBound(szLstNam, 1) + 1
rc = SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _
8, _
0, _
szLstNam(0, 0), _
cbMaxLenLstNam, _
cbLenLstNam(0))

rc = SQLBindParameter(hStmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _


3, 0, szInit(0, 0), _
UBound(szInit, 1) - LBound(szInit, 1) + 1, _
cbNTS(0))
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt)

rc = SQLBindParameter(hStmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _


13, 0, szStreet(0, 0), _
UBound(szStreet, 1) - LBound(szStreet, 1) + 1, _
cbNTS(0))
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt)

rc = SQLBindParameter(hStmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _


6, 0, szCity(0, 0), _
UBound(szCity, 1) - LBound(szCity, 1) + 1, _
cbNTS(0))
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue

rc = SQLBindParameter(hStmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _


2, 0, szState(0, 0), _
UBound(szState, 1) - LBound(szState, 1) + 1, _
cbNTS(0))
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue

rc = SQLBindParameter(hStmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, _


5, 0, szZipCod(0, 0), _
UBound(szZipCod, 1) - LBound(szZipCod, 1) + 1, _
cbNTS(0))
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue

Chapter 3. Express C/C++ APIs 229


rc = SQLBindParameter(hStmt, 8, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _
4, 0, fCdtLmt(0), 0, ByVal 0)
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue
rc = SQLBindParameter(hStmt, 9, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _
1, 0, fChgCod(0), 0, ByVal 0)
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue
rc = SQLBindParameter(hStmt, 10, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _
6, 2, fBalDue(0), 0, ByVal 0)
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue
rc = SQLBindParameter(hStmt, 11, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _
6, 2, fCdtDue(0), 0, ByVal 0)
If (rc = SQL_ERROR) Then Call PrintError(ghDbc, hStmt) '//report and continue

lRowsLeft = lTotalRows 'Initialize row counter


'Number of inserts to run = (Numrows -1)/BLKSIZE +1
For j = 0 To ((lTotalRows - 1) \ BLKSIZE)
'// set the values...
For I = 0 To BLKSIZE - 1
cbNTS(I) = SQL_NTS '// init array to NTS
lCustnum(I) = I + (j * BLKSIZE) 'Customer number = row number
S = "Nam" & Str(lCustnum(I)) 'Last Name
cbLenLstNam(I) = Len(S)
rc = String2Byte2D(S, szLstNam(), I)
'Debug info: Watch address to see layout
addr = VarPtr(szLstNam())
addr = CharNext(szLstNam(0, I)) 'address of 1,I
addr = CharPrev(szLstNam(0, I), szLstNam(1, I)) 'address of 0, I)
addr = CharNext(szLstNam(1, I))
addr = CharNext(szLstNam(6, I)) 'should point to null (if used)
addr = CharNext(szLstNam(7, I)) 'should also point to next row

rc = String2Byte2D("DXD", szInit, I)
'Vary the length of the street
S = Mid("1234567890123", 1, ((I Mod 13) + 1))
rc = String2Byte2D(S, szStreet, I)

rc = String2Byte2D("Roches", szCity, I)
rc = String2Byte2D("MN", szState, I)
rc = String2Byte2D("55902", szZipCod, I)
fCdtLmt(I) = I
fChgCod(I) = 1
fBalDue(I) = 2 * I
fCdtDue(I) = I / 2
Next I

lNumRows = lTotalRows Mod BLKSIZE '//Number of rows to send in this block


If (lRowsLeft >= BLKSIZE) Then _
lNumRows = BLKSIZE '//send remainder or full block
irow = 0
lRowsLeft = lRowsLeft - lNumRows
rc = SQLParamOptions(hStmt, lNumRows, irow)
If (rc = SQL_ERROR) Then GoTo errBlockInsert

rc = SQLExecute(hStmt)
If (rc = SQL_ERROR) Then
S = "Error on Row: " & Str(irow) & Chr(13) & Chr(10)
MsgBox S, , gAppName
GoTo errBlockInsert
End If
'// Only commit every 50000 records?
'//if ((lNumRows % 50000) == 0) {
'rc = SQLTransact(ghEnv, ghDbc, SQL_COMMIT )
'// if (Not (rc = SQL_SUCCESS OR rc = SQL_SUCCESS_WITH_INFO)) then goto
'// errBlockInsert;
'// S="Committed 50,000:"

230 Client Access Express Programming


'// S = S & " lCustnum = : " & Str(lCustnum)
'// MsgBox S, , gAppName
'//}
'//left over from win 3.1
'DoEvents
Next j '} // j loop (number of blocks)

rc = SQLTransact(ghEnv, ghDbc, SQL_COMMIT)


If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert
rc = SQLFreeStmt(hStmt, SQL_DROP)
Screen.MousePointer = 0
StatusBar1.Panels.Item(1).Text = "Block Insert Successfully Inserted " _
& Str(lTotalRows) & " Records"
Exit Sub

errBlockInsert:
Call PrintError(ghDbc, hStmt)
rc = SQLTransact(ghEnv, ghDbc, SQL_ROLLBACK)
rc = SQLFreeStmt(hStmt, SQL_DROP)
Screen.MousePointer = 0
StatusBar1.Panels.Item(1).Text = "Block Insert Failed"

Public Function String2Byte2D(InString As String, OutByte() As Byte, RowIdx As Long)


As Boolean
'VB byte arrays are layed out in memory opposite of C. The string would
'be by column instead of by row so must flip flop the string.
'ASSUMPTIONS:
' Byte array is sized before being passed
' Byte array is padded with nulls if > size of string

Dim I As Integer
Dim SizeOutByte As Integer
Dim SizeInString As Integer

SizeInString = Len(InString)
SizeOutByte = UBound(OutByte, 1)

'Convert the string


For I = 0 To SizeInString - 1
OutByte(I, RowIdx) = AscB(Mid(InString, I + 1, 1))
Next I
'If byte array > len of string pad
If SizeOutByte > SizeInString Then 'Pad with Nulls
For I = SizeInString To SizeOutByte - 1
OutByte(I, RowIdx) = 0
Next I
End If
'ViewByteArray OutByte, "String2Byte"
String2Byte2D = True
End Function

Ending ODBC functions: The last procedure that must be completed before ending
an ODBC application is to free the resources and memory allocated by the
application. This must be done so that they are available when the application is
run the next time.
SQLFreeStmt
Stops processing associated with a specific statement handle.
SQLFreeStmt(hstmt,option); // option can be SQL_CLOSE
SQL_DROP
SQL_UNBIND

Chapter 3. Express C/C++ APIs 231


SQL_CLOSE
Closes the cursor associated with the statement handle, and
discards all pending results.
SQL_DROP
Frees all the resources for the statement.
SQL_UNBIND
Releases all common buffers that are bound by SQLBindColumn.
SQLDisconnect
Closes the connection associated with a specific connection handle.
SQLDisconnect(hdbc);
SQLFreeConnect
Releases connection handle and frees all memory associated with a
connection handle.
SQLFreeConnect(hdbc);
SQLFreeEnv
Frees environment handle and releases all memory associated with the
environment handle.
SQLFreeEnv(henv);

VB 5.0: The compromise between Jet and ODBC APIs: While the database objects are
easy to code, they sometimes can adversely affect performance. Coding to the APIs
and to stored procedures can be a frustrating endeavor.

Fortunately, if you are using Visual Basic 5.0 Enterprise Edition in the Windows 95
environment, there are additional options. These options are a good compromise
between the usability of database objects and the high performance of APIs:
Remote Data Objects (RDO) and Remote Data Control (RDC).

RDO is a thin layer over the ODBC APIs. It provides a simple interface to
advanced ODBC functionality without requiring programming to the API level. It
does not have all of the overhead of the Jet Engine controlled Data Access Object
(DAO) or its SQL optimizer. Yet it maintains a nearly identical programming
interface as the DAOs. If you understand programming to the DAO, then
switching over to the RDO is relatively simple compared to trying to switch over
to API calls.

The following are differences between DAO and RDO:


v The DAO model is used for ISAM, Access and ODBC databases. The RDO
model is designed for ODBC databases only, and it has been optimized for
Microsoft SQL Server 6.0 and Oracle.
v The RDO model can have better performance, with the processing being done
by the server and not the local machine. Some processing is done locally with
the DAO model, so performance may not be as good.
v The DAO model uses the Jet Engine. The RDO model does not use Jet Engine, it
uses the ODBC backend engine.
v The RDO model has the capability to perform synchronous or asynchronous
queries. The DAO model has limitations in performing these type of queries.
v The RDO model can perform complex cursors, which are limited in the DAO
model.

The RDC is a data control similar to the standard data control. This means that
where ever you might have used a data control, and the Jet engine, you now can

232 Client Access Express Programming


use the RDC. You can drag a ″data aware″ control on your form. It can be bound
to an RDC, as it could be bound to a regular data control.

Some of the advanced ODBC functionality the RDO allows is prepared SQL
statements, multiple result sets, and stored procedures. When Jet executes a SQL
statement dynamically it is a two-step process on the AS/400. In the first step, the
AS/400 looks at the statement and determines the best plan to retrieve the data
requested based on the current database schema. In the second step, that plan is
used to actually retrieve the data. Creating that plan can be expensive in terms of
time because the AS/400 has to evaluate many alternatives and determine the best
way to access the data. There is an alternative to forcing the AS/400 to re-create
the access plan every time a SQL statement is run. The CreatePreparedStatement
method of the rdoConnection object allows you to compile a data access plan on
the AS/400 for an SQL statement without executing it. You can even include
parameters in prepared statements, so you can pass new selection criteria every
time you run the select statement.

The following sample Visual Basic code will show how to prepare a SQL statement
with a parameter marker and run it multiple times with different values.

Visual Basic 4.0 RDO sample code

Label A shows where the SQL statement is defined. Notice that the statement does
not include a specific for the CUSTNUM, but has a question mark for the value.
The question mark signifies that this value is a parameter of the prepared
statement. Before you can create a result set with the prepared statement, you must
set the value of any parameters in the statement.

Chapter 3. Express C/C++ APIs 233


Label B shows where the value for the parameter is defined. Notice that the first
parameter is defined as 0 not as 1. Once the value for the parameter is set you can
run the OpenResultSet method of the rdoPreapredStatement to return the
requested data.

Before you can requery a prepared statement on the AS/400, you have to make
sure that the cursor has been completely processed and closed. Label C shows the
MoreResults method of the rdoResultSet being used to do this. The MoreResults
method queries the database. It determines if there is any more data in the result
set to be processed, or if the result set has been processed completely. Once the
cursor has been fully processed you can reset the parameter value and run the
ReQuery method of the rdoResultSet to open a new result set.

ODBC blocked insert statement: The blocked INSERT statement provides a


means to insert multiple rows with a single SQLExecute request. For performance,
it provides the one of the best ways to populate a table, at times providing a
tenfold performance improvement over the next best method.

The three forms of INSERT statements that can be executed from ODBC are:
v INSERT with VALUES using constants
v INSERT with VALUES using parameter markers
v blocked INSERT

The INSERT with VALUES using constants statement is the least efficient method
of performing inserts. For each request, a single INSERT statement is sent to the
server where it is prepared, the underlying table is opened, and the record is
written.

Example:

INSERT INTO TEST.TABLE1 VALUES('ENGINEERING',10,'JONES','BOB')

The INSERT with VALUES using parameter markers statement performs better
than the statement that uses constants. This form of the INSERT statement allows
for the statement to be prepared only once and then reused on subsequent
executions of the statement. It also allows the table on the server to remain open,
thus removing the overhead of opening and closing the file for each insert.

Example:

INSERT INTO TEST.TABLE1 VALUES (?, ?, ?, ?)

The blocked INSERT statement most efficiently performs inserts into a table when
multiple records can be cached on the client and sent at once. The advantages with
blocked INSERT are:
v The data for multiple rows is sent in one communication request rather than one
request per row.
v The server has an optimized path built into the database support for blocked
INSERT statements.
Example:
INSERT INTO TEST.TABLE1 ? ROWS VALUES (?, ?, ?, ?)

234 Client Access Express Programming


The INSERT statement has additional syntax that identifies it as a blocked INSERT.
The ″? ROWS″ clause indicates that an additional parameter will be specified for
this INSERT statement. It also indicates that the parameter will contain a row
count that determines how many rows will be sent for that execution of the
statement. The number of rows must be specified by means of the
SQLParamOptions API.
To view examples of blocked insert calls from C:
See “Examples: Blocked insert calls from C”

Examples: Blocked insert calls from C:


// Block insert variables and statements
// variable declares
HSTMT s_Ordlin1; // Order Line Insert.
UDWORD rowcnt; // for Blocked insert.
long lOrderNum[15];
// array of order numbers for blocked insert
UINT uiDistrict[15];
// District Number (from TxnLeader).
char szWid[15][5]; // Warehouse id.
UINT uiOl_ctr[15]; // Order Line Counter.
char szSplyWid[15][5]; // Supply warehouse id.
char szIid[15][7]; // Item id
char szOlAmt[15][10];
// $ amount for ordered item (7,2)
UINT uiZero [15]; // delivery date & time
UINT uiOlQty[15]; // Quantity Ordered - for non-numeric.
char szDistrctInfo[15][25]; //District info.

UINT m_Warehouse; // Member copy of the warehouse #.


long m_OrderNum; // Order Number.
UINT m_District; // District Number (from TxnLeader).
Order_Line m_OrdLines[16];
// Array for interface

// Prepare the block insert statement


strcpy(tmpbfr,"Insert into library/ORDLIN ? ");
strcat(tmpbfr,"ROWS VALUES (?,?,?,?,?,?,?,?,?,?,?)");

ret= SQLPrepare(s_Ordlin1,(unsigned char far *)tmpbfr,SQL_NTS);


// Set the parameters. This table has 11 columns.

ret=SQLBindParameter(s_Ordlin1, 1,SQL_PARAM_INPUT,SQL_C_LONG,SQL_DECIMAL,
9,0,lOrderNum,0,NULL); //order id
ret=SQLBindParameter(s_Ordlin1, 2,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_DECIMAL,
3,0,uiDistrict,0,NULL); //district id

ret=SQLBindParameter(s_Ordlin1, 3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,4,0,
szWid[0],5,NULL); //warehouse id

ret=SQLBindParameter(s_Ordlin1, 4,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_DECIMAL,
3,0,&uiOI_ctr,0,NULL); //number of order lines

ret=SQLBindParameter(s_Ordlin1, 5,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,4,0,
szSplyWid,5,NULL); //supplying wrhs id

ret=SQLBindParameter(s_Ordlin1, 6,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,6,0,
szIid,7,NULL); //item id

ret=SQLBindParameter(s_Ordlin1, 7,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_NUMERIC,3,0,
uiOlQty,0,NULL); //quantity

ret=SQLBindParameter(s_Ordlin1, 8,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_NUMERIC,7,2,
szOlAmt,10,NULL); //A float for $ amount or purchase

Chapter 3. Express C/C++ APIs 235


ret=SQLBindParameter(s_Ordlin1, 9,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_NUMERIC,8,0,
uiZero,0,NULL); //Delivery date (set to zero)

ret=SQLBindParameter(s_Ordlin1,10,SQL_PARAM_INPUT,SQL_C_SHORT,SQL_NUMERIC,6,0,
uiZero,0,NULL); //Delivery time (set to zero)

ret=SQLBindParameter(s_Ordlin1,11,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,24,0,
szDistrctInfo,25,NULL); //District data waste space

//******************** Insert into ORDLIN ****************


rowcnt = 0;

// Use SQLParamOptions to set the row count for the Blocked Insert.
// The row count field is passed in a separate variable.

ret=SQLParamOptions(s_Ordlin1, NewOrd_IO->m_OrderCount, &rowcnt);

// Fill the parameters for the Blocked Insert by moving the data
// from the input array to the parameters.
for(ol_ctr=1;ol_ctr<=NewOrd_IO->m_OrderCount;ol_ctr++)
{
lOrderNum[ol_ctr-1] = NewOrd_IO->m_OrderNum;
uiDistrict[ol_ctr-1] = NewOrd_IO->m_District;
sprintf(s_parm[3],"%04u",NewOrd_IO->m_Warehouse);
strcpy(szWid[ol_ctr-1],s_parm[3]);
uiOl_ctr[ol_ctr-1] = ol_ctr;
sprintf(s_parm[5],"%04u",*NewOrd_IO->m_OrdLines
[ol_ctr].Supp_W);
strcpy(szSplyWid[ol_ctr-1], s_parm[5]);
sprintf(s_parm[6],"%06ld",*NewOrd_IO->m_OrdLines
[ol_ctr].Item_ID);
strcpy(szIid[ol_ctr-1], s_parm[6]);
uiOlQty[ol_ctr-1] = *NewOrd_IO->m_OrdLines
[ol_ctr].Qty;
sprintf(s_parm[8],"%+09.2f",*NewOrd_IO->m_OrdLines
[ol_ctr].Amount);
strcpy(szOlAmt[ol_ctr-1], s_parm[8]);
sprintf(s_parm[13],"%s",txttemp[
NewOrd_IO->m_District]);
strcpy(szDistrctInfo[ol_ctr-1], s_parm[13]);
} // end of for loop

ret=SQLExecute(s_Ordlin1); // Execute Order Line insert.

Catalog functions: Catalog functions return information about a data source’s


catalog.

To process ODBC SQLTable requests, logical files are built over the system cross
reference file QADBXREF in library QSYS. QADBXREF is a database file for
database-maintained cross-reference information that is part of the dictionary
function for the system.

The following are the actions for SQLTable when Table_Type is set to the
following:
NULL Selects all LOGICAL and PHYSICAL files and SQL TABLES and VIEWS.
TABLE
Selects all PHYSICAL files, and SQL TABLES that are not system files
(cross reference or data dictionary).
VIEW Selects all LOGICAL files and SQL VIEWS that are not system files (cross
reference or data dictionary).

236 Client Access Express Programming


SYSTEM TABLE
Selects all PHYSICAL and LOGICAL files and SQL views that are either
system files or data dictionary files.
TABLE, VIEW
Selects all LOGICAL and PHYSICAL files and all SQL TABLES and VIEWS
that are not system files or data dictionary files.

Non-relational files (files with more than one format) are not selected. Also not
selected are indexes, flat files and IDDU-defined files.

The result sets returned by the catalog functions are ordered by table type. In
addition to the TABLE and VIEW types, the AS/400 has the data source-specific
type identifiers of PHYSICAL and LOGICAL files. The PHYSICAL type is handled
as a TABLE, and the LOGICAL type is handled as a VIEW. Though they appear as
type TABLE or VIEW, PHYSICAL and LOGICAL are sorted on their true type. The
sort order is
1. Logical files
2. Physical files
3. Table
4. Views

The following system naming conventions are used:


System cross-reference file names all start with QADB.....
System data dictionary file names all start with QIDCT.....
System view names all start with SYS.....

To process ODBC SQLColumn requests, a logical file is built over the system
cross-reference file QADBIFLD in the QSYS library. This logical file selects all
relational database files except for indexes. QADBIFLD is a database file for
database-maintained cross-reference information that is part of the dictionary
function for the system. Specifically, this includes database file column and field
information.
For additional information:
Appendix G of the SQL Reference book contains additional information.
View an HTML online version of the book, or print a PDF version, from
the DB2 Universal Database for AS/400 books online AS/400 Information
Center topic.

Exit programs: When you specify an exit program, the servers pass the following
two parameters to the exit program before running your request:
v A 1-byte return code value.
v A structure containing information about your request. This structure is different
for each of the exit points.

These two parameters allow the exit program to determine whether your request is
allowed. If the exit program sets the return code to X'F0', the server rejects the
request. If the return code is set to anything else, the server allows the request.

The same program can be used for multiple exit points. The program can
determine what function is being called by looking at the data in the second
parameter structure.

Chapter 3. Express C/C++ APIs 237


Use the Work with Registration Information (WRKREGINF) command to add your
exit programs to the database exit points.

The database server has four different exit points defined:


QIBM_QZDA_INIT
called at server initiation
QIBM_QZDA_NDB1
called for native database requests
QIBM_QZDA_SQL1
called for SQL requests
QIBM_QZDA_ROI1
called for retrieving object information requests and SQL catalog functions
Exit programs-related topics:
v “Examples: User exit programs”
v “Exit program parameter formats” on page 244

Examples: User exit programs: The following examples do not show all of the
programming considerations or techniques. Review the examples before you begin
application design and coding.

See the Client Access Express Host Servers book for additional user exit program
examples.
v “Example: ILE C/400® user exit program for exit point QIBM_QZDA_INIT (part
1)”
v “Example: ILE C/400 user exit program for exit point QIBM_QZDA_INIT (part
2)” on page 239
v “Example: CL user exit program for exit point QIBM_QZDA_INIT (part 1)” on
page 239
v “Example: CL user exit program for exit point QIBM_QZDA_INIT (part 2)” on
page 240
v “Example: ILE C/400 Program for exit point QIBM_QZDA_SQL1 (part 1)” on
page 240
v “Example: ILE C/400 program for exit point QIBM_QZDA_SQL1 (part 2)” on
page 241
v “Example: ILE C/400 program for exit point QIBM_QZDA_ROI1 (part 1)” on
page 242
v “Example: ILE C/400 Program for exit point QIBM_QZDA_ROI1 (part 2)” on
page 242
v “Example: ILE C/400 program for exit point QIBM_QZDA_ROI1 (part 3)” on
page 243

Example: ILE C/400® user exit program for exit point QIBM_QZDA_INIT (part 1):
/*--------------------------------------------------------------------------
* OS/400 Servers - Sample Exit Program
*
* Exit Point Name : QIBM_QZDA_INIT
*
* Description : The following ILE C/400 program handles
* ODBC security by rejecting requests from
* certain users.
* It can be used as a shell for developing
* exit programs tailored for your
* operating environment.

238 Client Access Express Programming


*
* Input : A 1-byte return code value
* X'F0' server rejects the request
* anything else server allows the request
* Structure containing information about the
* request. The format used by this program
* is ZDAI0100.
*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
* Includes
*------------------------------------------------------------------------*/
#include <string.h> /* string functions */
/*------------------------------------------------------------------------
* User Types
*------------------------------------------------------------------------*/
typedef struct { /* Exit Point QIBM_QZDA_INIT format ZDAI0100 */
char User_profile_name[10]; /* Name of user profile calling server*/
char Server_identifier[10]; /* database server value (*SQL) */
char Exit_format_name[8]; /* User exit format name (ZDAI0100) */
long Requested_function; /* function being preformed (0) */
} ZDAI0100_fmt_t;
View part 2 of the ILE C/400 user exit program for exit point QIBM_QZDA_INIT
example:
“Example: ILE C/400 user exit program for exit point QIBM_QZDA_INIT
(part 2)”

Example: ILE C/400 user exit program for exit point QIBM_QZDA_INIT (part 2):
/*========================================================================
* Start of mainline executable code
*========================================================================*/
int main (int argc, char *argv[])
{
ZDAI0100_fmt_t input; /* input format record */

/* copy input parm into structure */


memcpy(&input, (ZDAI0100_fmt_t *)argv[2], 32);

if /* if user name is GUEST */


( memcmp(input.User_profile_name, "GUEST ", 10)==0 )
{
/* set return code to reject the request. */
memcpy( argv[1], "0", 1);
}
else /* else user is someone else */
{
/* set return code to allow the request. */
memcpy( argv[1], "1", 1);
}
} /* End of mainline executable code */

Example: CL user exit program for exit point QIBM_QZDA_INIT (part 1):
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* OS/400 Servers - Sample Exit Program */
/* */
/* Exit Point Name : QIBM_QZDA_INIT */
/* */
/* Description : The following Control Language program */
/* handles ODBC security by rejecting */
/* requests from certain users. */
/* It can be used as a shell for developing */
/* exit programs tailored for your */
/* operating environment. */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
PGM PARM(&STATUS &REQUEST)

Chapter 3. Express C/C++ APIs 239


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Program call parameter declarations */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DCL VAR(&STATUS) TYPE(*CHAR) LEN(1) /* Accept/Reject indicator */
DCL VAR(&REQUEST) TYPE(*CHAR) LEN(34) /* Parameter structure */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Parameter declares */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DCL VAR(&USER) TYPE(*CHAR) LEN(10) /* User profile name calling server*/
DCL VAR(&SRVID) TYPE(*CHAR) LEN(10) /* database server value (*SQL) */
DCL VAR(&FORMAT) TYPE(*CHAR) LEN(8) /* Format name (ZDAI0100) */
DCL VAR(&FUNC) TYPE(*CHAR) LEN(4) /* function being preformed (0) */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Extract the various parameters from the structure */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
CHGVAR VAR(&USER) VALUE(%SST(&REQUEST 1 10))
CHGVAR VAR(&SRVID) VALUE(%SST(&REQUEST 11 10))
CHGVAR VAR(&FORMAT) VALUE(%SST(&REQUEST 21 8))
CHGVAR VAR(&FUNC) VALUE(%SST(&REQUEST 28 4))
View part 2 of the CL user exit program for exit point QIBM_QZDA_INIT
example:
“Example: CL user exit program for exit point QIBM_QZDA_INIT (part 2)”

Example: CL user exit program for exit point QIBM_QZDA_INIT (part 2):
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Begin main program */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* set return code to allow the request. */


CHGVAR VAR(&STATUS) VALUE('1')

/* if user name is GUEST set return code to reject the request. */


IF (&USER *EQ 'GUEST') THEN( +
CHGVAR VAR(&STATUS) VALUE('0') )

EXIT:
ENDPGM

Example: ILE C/400 Program for exit point QIBM_QZDA_SQL1 (part 1):
/*--------------------------------------------------------------------------
* OS/400 Servers - Sample Exit Program
*
* Exit Point Name : QIBM_QZDA_SQL1
*
* Description : The following ILE C/400 program will
* reject any UPDATE request for user GUEST.
* It can be used as a shell for developing
* exit programs tailored for your
* operating environment.
*
* Input : A 1-byte return code value
* X'F0' server rejects the request
* anything else server allows the request
* Structure containing information about the
* request. The format used by this program
* is ZDAQ0100.
*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
* Includes
*------------------------------------------------------------------------*/
#include <string.h> /* string functions */
#include <stdio.h> /* standard IO functions */

240 Client Access Express Programming


#include <ctype.h> /* type conversion functions */
/*========================================================================
* Start of mainline executable code
*========================================================================*/
main(int argc, char *argv[])
{
long i;
_Packed struct zdaq0100 {
char name[10];
char servid[10];
char fmtid[8];
long funcid;
char stmtname[18];
char cursname[18];
char prepopt[2];
char opnattr[2];
char pkgname[10];
char pkglib[10];
short drdaind;
char commitf;
char stmttxt[512];
} *sptr, stx;
View part 2 of the ILE C/400 program for exit point QIBM_QZDA_SQL1
example:
“Example: ILE C/400 program for exit point QIBM_QZDA_SQL1 (part 2)”

Example: ILE C/400 program for exit point QIBM_QZDA_SQL1 (part 2):
/* initialize return variable to indicate ok status */
strncpy(argv[1],"1",1);

/**********************************************************************/
/* Address parameter structure for SQL exit program and move local */
/* parameters into local variables. */
/* (note : this is not necessary to evaluate the arguments passed in). */
/**********************************************************************/
sptr = (_Packed struct zdaq0100 *) argv[2];

strncpy(stx.name, sptr->name, 10);


strncpy(stx.servid, sptr->servid, 10);
strncpy(stx.fmtid, sptr->fmtid, 8);
stx.funcid = sptr->funcid;
strncpy(stx.stmtname, sptr->stmtname, 18);
strncpy(stx.cursname, sptr->cursname, 18);
strncpy(stx.opnattr, sptr->opnattr, 2);
strncpy(stx.prepopt, sptr->prepopt, 2);
strncpy(stx.pkglib, sptr->pkglib, 10);
strncpy(stx.pkgname, sptr->pkgname, 10);
stx.drdaind = sptr->drdaind;
stx.commitf = sptr->commitf;
strncpy(stx.stmttxt, sptr->stmttxt, 512);

/**********************************************************************/
/* check for user GUEST and an UPDATE statement */
/* if found return an error */
/**********************************************************************/
if (! (strncmp(stx.name, "GUEST ", 10)) )
{
for (i=0; i<6; i++)
stx.stmttxt[i] = toupper(stx.stmttxt[i]);

if (! strncmp(stx.stmttxt, "UPDATE", 6) )
/* Force error out of SQL user exit pgm */
strncpy(argv[1], "0", 1);
else;

Chapter 3. Express C/C++ APIs 241


}
return;
} /* End of mainline executable code */

Example: ILE C/400 program for exit point QIBM_QZDA_ROI1 (part 1):
/*--------------------------------------------------------------------------
* OS/400 Servers - Sample Exit Program
*
* Exit Point Name : QIBM_QZDA_ROI1
*
* Description : The following ILE C/400 program logs all
* requests for catalog functions to the
* ZDALOG file in QGPL.
* It can be used as a shell for developing
* exit programs tailored for your
* operating environment.
*
* Input : A 1-byte return code value
* X'F0' server rejects the request
* anything else server allows the request
* Structure containing information about the
* request. The format used by this program
* is ZDAR0100.
*
* Dependencies : The log file must be created using the
* following command:
* CRTPF FILE(QGPL/ZDALOG) RCDLEN(132)
*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
* Includes
*------------------------------------------------------------------------*/
#include <recio.h> /* record IO functions */
#include <string.h> /* string functions */
/*------------------------------------------------------------------------
* User Types
*------------------------------------------------------------------------*/
typedef struct { /* Exit Point QIBM_QZDA_ROI1 format ZDAR0100 */
char User_profile_name[10]; /* Name of user profile calling server*/
char Server_identifier[10]; /* database server value (*RTVOBJINF) */
char Exit_format_name[8]; /* User exit format name (ZDAR0100) */
long Requested_function; /* function being preformed */
char Library_name[20]; /* Name of library */
char Database_name[36]; /* Name of relational database */
char Package_name[20]; /* Name of package */
char File_name[256]; /* Name of file */
char Member_name[20]; /* Name of member */
char Format_name[20]; /* Name of format */
} ZDAR0100_fmt_t;
View part 2 of the ILE C/400 Program for exit point QIBM_QZDA_ROI1
example:
“Example: ILE C/400 Program for exit point QIBM_QZDA_ROI1 (part 2)”

Example: ILE C/400 Program for exit point QIBM_QZDA_ROI1 (part 2):
/*========================================================================
* Start of mainline executable code
*========================================================================*/
int main (int argc, char *argv[])
{
_RFILE *file_ptr; /* pointer to log file */
char output_record[132]; /* output log file record */
ZDAR0100_fmt_t input; /* input format record */
/* set return code to allow the request. */
memcpy( argv[1], "1", 1);

/* open the log file for writing to the end of the file */

242 Client Access Express Programming


if (( file_ptr = _Ropen("QGPL/ZDALOG", "ar") ) == NULL)
{
/* open failed */
return;
}

/* copy input parm into structure */


memcpy(&input, (ZDAR0100_fmt_t *)argv[2], 404);

switch /* Create the output record based on requested function */


(input.Requested_function)
{
case 0X1800: /* Retrieve library information */
sprintf(output_record,
"%10.10s retrieved library %20.20s",
input.User_profile_name, input.Library_name);
break;
case 0X1801: /* Retrieve relational database information */
sprintf(output_record,
"%10.10s retrieved database %36.36s",
input.User_profile_name, input.Database_name);
break;
case 0X1802: /* Retrieve SQL package information */
sprintf(output_record,
"%10.10s retrieved library %20.20s package %20.20s",
input.User_profile_name, input.Library_name,
input.Package_name);
break;
case 0X1803: /* Retrieve SQL package statement information */
sprintf(output_record,
"%10.10s retrieved library %20.20s package %20.20s statement info",
input.User_profile_name, input.Library_name,
input.Package_name);
break;
View part 3 of the ILE C/400 program for exit point QIBM_QZDA_ROI1
example:
“Example: ILE C/400 program for exit point QIBM_QZDA_ROI1 (part 3)”

Example: ILE C/400 program for exit point QIBM_QZDA_ROI1 (part 3):
case 0X1804: /* Retrieve file information */
sprintf(output_record,
"%10.10s retrieved library %20.20s file %40.40s",
input.User_profile_name, input.Library_name, input.File_name);
break;
case 0X1805: /* Retrieve file member information */
sprintf(output_record,
"%10.10s retrieved library %20.20s member %20.20s file %40.40s",
input.User_profile_name, input.Library_name,
input.Member_name, input.File_name);
break;
case 0X1806: /* Retrieve record format information */
sprintf(output_record,
"%10.10s retrieved library %20.20s format %20.20s file %40.40s",
input.User_profile_name, input.Library_name,
input.Format_name, input.File_name);
break;
case 0X1807: /* Retrieve field information */
sprintf(output_record,
"%10.10s retrieved field info library %20.20s file %40.40s",
input.User_profile_name, input.Library_name, input.File_name);
break;
case 0X1808: /* Retrieve index information */
sprintf(output_record,
"%10.10s retrieved index info library %20.20s file %40.40s",
input.User_profile_name, input.Library_name, input.File_name);

Chapter 3. Express C/C++ APIs 243


break;
case 0X180B: /* Retrieve special column information */
sprintf(output_record,
"%10.10s retrieved column info library %20.20s file %40.40s",
input.User_profile_name, input.Library_name, input.File_name);
break;
default : /* Unknown requested function */
sprintf(output_record, "Unknown requested function");
break;
} /* end switch statement */

/* write the output record to the file */


_Rwrite(file_ptr, &output_record, 132);

/* close the log file */


_Rclose ( file_ptr );

} /* End of mainline executable code */

Exit program parameter formats: The exit points for native database and retrieving
object information have two formats that are defined: QIBM_QZDA_SQL1 and
QIBM_QZDA_SQL2. Depending on the type of function that is requested, one of
the formats is used.

The QIBM_QZDA_SQL2 exit point is defined to run an exit point for certain SQL
requests that are received for the database server. This exit point takes precedence
over the QIBM_QZDA_SQL1 exit point. If a program is registered for the
QIBM_QZDA_SQL2 exit point, it will be called, and a program for the
QIBM_QZDA_SQL1 exit point will not be called.
Functions that cause the exit program to be called
v Prepare
v Open
v Execute
v Connect
v Create package
v Clear package
v Delete package
v Stream fetch
v Execute immediate
v Prepare and describe
v Prepare and execute or prepare and open
v Open and fetch
v Execute or open
Parameter fields and their descriptions for exit programs with different exit
points and formats:
v “Parameter fields for exit point QIBM_QZDA_SQL2 format ZDAQ0200”
on page 245
v “Parameter fields for exit point QIBM_QZDA_INIT format ZDAI0100”
on page 246
v “Parameter fields for exit point QIBM_QZDA_NDB1 format ZDAD0100”
on page 247
v “Parameter fields for exit point QIBM_QZDA_NDB1 format ZDAD0200”
on page 248
v “Parameter fields for exit point QIBM_QZDA_SQL1 format ZDAQ0100”
on page 249

244 Client Access Express Programming


v “Parameter fields for exit point QIBM_QZDA_ROI1 format ZDAR0100”
on page 250
v “Parameter fields for exit point QIBM_QZDA_ROI1 format ZDAR0200”
on page 252

Parameter fields for exit point QIBM_QZDA_SQL2 format ZDAQ0200: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_SQL2 with the ZDAQ0200 format:
Table 6. Exit point QIBM_QZDA_SQL2 format ZDAQ0200
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier The value is *SQLSRV for this exit
point.
20 14 CHAR(8) Format name The user exit format name being
used. For QIBM_QZDA_SQL1,
the format name is ZDAQ0100.
28 1C BINARY(4) Requested The function being performed.
function
This field contains one of the
following:
X’1800’ - Prepare
X’1803’ - Prepare and describe
X’1804’ - Open/describe
X’1805’ - Execute
X’1806’ - Execute immediate
X’1809’ - Connect
X’180C’ - Stream fetch
X’180D’ - Prepare and execute
X’180E’ - Open and fetch
X’180F’ - Create package
X’1810’ - Clear package
X’1811’ - Delete package
X’1812’ - Execute or open
32 20 CHAR(18) Statement name Name of the statement used for
the prepare or execute functions.
50 32 CHAR(18) Cursor name Name of the cursor used for the
open function.
68 44 CHAR(2) Prepare option Option used for the prepare
function.
70 46 CHAR(2) Open attributes Option used for the open
function.
72 48 CHAR(10) Extended Name of the extended dynamic
dynamic package.
package name
82 52 CHAR(10) Package library Name of the library for extended
name dyanmic SQL package.

Chapter 3. Express C/C++ APIs 245


Table 6. Exit point QIBM_QZDA_SQL2 format ZDAQ0200 (continued)
Offset
Dec Hex Type Field Description
92 5C BINARY(2) DRDA indicator 0 - Connected to local RDB
1 - Connected to remote RDB
94 5E CHAR(1) Commitment ’A’ - Commit *ALL
control level
’C’ - Commit *CHANGE
’N’ - Commit *NONE
’S’ - Commit *CS (cursor
stability)
95 5F CHAR(10) Default SQL Name of the default SQL
collection collection used by the AS/400
Database Server.
105 69 CHAR(129) Reserved Reserved for future parameters.
234 EA BINARY(4) SQL statement Length of SQL statement text in
text length the field that follows. The length
can be a maximum of 32K.
238 EE CHAR(*) SQL statement Entire SQL statement.
text
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

The QIBM_QZDA_INIT exit point is defined to run an exit program at server


initiation. If a program is defined for this exit point, it is called each time the
database server is initiated.

Parameter fields for exit point QIBM_QZDA_INIT format ZDAI0100: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_INIT using the ZDAI0100 format:
Table 7. Exit point QIBM_QZDA_INIT format ZDAI0100
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier The value is *SQL for this exit
point.
20 14 CHAR(8) Format name The user exit format name being
used. For QIBM_QZDA_INIT the
format name is ZDAI0100.
28 1C BINARY(4) Requested The function being performed.
function
The only valid value for this exit
point is 0.
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

The QIBM_QZDA_NDB1 exit point is defined to run an exit program for native
database requests for the database server. Two formats are defined for this exit
point.

246 Client Access Express Programming


Functions that use format ZDAD0100:
v Create source physical file
v Create database file, based on existing file
v Add, clear, delete database file member
v Override database file
v Delete database file override
v Delete file

Note: Format ZDAD0200 is used when a request is received to add libraries to the
library list.

Parameter fields for exit point QIBM_QZDA_NDB1 format ZDAD0100: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_NDB1 using the ZDAD0100 format:
Table 8. Exit point QIBM_QZDA_NDB1 format ZDAD0100
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier For this exit point the value is
*NDB.
20 14 CHAR(8) Format name The user exit format name being
used.

For the following functions, the


format name is ZDAD0100.
28 1C BINARY(4) Requested The function being performed.
function
This field contains one of the
following:
X’1800’ - Create source
physical file
X’1801’ - Create database file,
based on existing file
X’1802’ - Add database file
member
X’1803’ - Clear database file
member
X’1804’ - Delete database file
member
X’1805’ - Override database
file
X’1806’ - Delete database file
override
X’1807’ - Create save file
X’1808’ - Clear save file
X’1809’ - Delete file
32 20 CHAR(128) File name Name of the file used for the
requested function.
160 A0 CHAR(10) Library name Name of the library that contains
the file.

Chapter 3. Express C/C++ APIs 247


Table 8. Exit point QIBM_QZDA_NDB1 format ZDAD0100 (continued)
Offset
Dec Hex Type Field Description
170 AA CHAR(10) Member name Name of the member to be
added, cleared, or deleted.
180 B4 CHAR(10) Authority Authority to the created file
190 BE CHAR(128) Based on file Name of the file to use when
name creating a file based on an
existing file.
318 13E CHAR(10) Based on library Name of the library containing
name the based on file
328 148 CHAR(10) Override file Name of the file to be overridden
name
338 152 CHAR(10) Override library Name of the library that contains
name the file to be overridden
348 15C CHAR(10) Override Name of the member to be
member name overridden
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

Parameter fields for exit point QIBM_QZDA_NDB1 format ZDAD0200: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_NDB1 by using the ZDAD0200 format:
Table 9. Exit point QIBM_QZDA_NDB1 format ZDAD0200
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier For this exit point the value is
*NDB.
20 14 CHAR(8) Format name The user exit format name being
used. For the add to library list
function the format name is
ZDAD0200.
28 1C BINARY(4) Requested The function being performed.
function X’180C’ - Add library list
32 20 BINARY(4) Number of The number of libraries (the next
libraries field)
36 24 CHAR(10) Library name The library names for each library
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

The QIBM_QZDA_SQL1 exit point is defined to run an exit point for certain SQL
requests that are received for the database server. Only one format is defined for
this exit point.
Functions that use format ZDAD0200:
v Prepare
v Open

248 Client Access Express Programming


v Execute
v Connect
v Create package
v Clear package
v Delete package
v Execute immediate
v Prepare and describe
v Prepare and execute or prepare and open
v Open and fetch
v Execute or open

Parameter fields for exit point QIBM_QZDA_SQL1 format ZDAQ0100: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_SQL1 using the ZDAQ0100 format.
Table 10. Exit point QIBM_QZDA_SQL1 format ZDAQ0100
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier For this exit point the value is
*SQLSRV.
20 14 CHAR(8) Format name The user exit format name being
used. For QIBM_QZDA_SQL1 the
format name is ZDAQ0100.
28 1C BINARY(4) Requested The function being performed.
function
This field contains one of the
following:
X’1800’ - Prepare
X’1803’ - Prepare and describe
X’1804’ - Open/Describe
X’1805’ - Execute
X’1806’ - Execute immediate
X’1809’ - Connect
X’180D’ - Prepare and execute
or prepare and open
X’180E’ - Open and fetch
X’180F’ - Create package
X’1810’ - Clear package
X’1811’ - Delete package
X’1812’ - Execute or open
32 20 CHAR(18) Statement name Name of the statement used for
the prepare or execute functions.
50 32 CHAR(18) Cursor name Name of the cursor used for the
open function.
68 44 CHAR(2) Prepare option Option used for the prepare
function.
70 46 CHAR(2) Open attributes Option used for the open
function.

Chapter 3. Express C/C++ APIs 249


Table 10. Exit point QIBM_QZDA_SQL1 format ZDAQ0100 (continued)
Offset
Dec Hex Type Field Description
72 48 CHAR(10) Extended Name of the extended dynamic
dynamic SQL package.
package name
82 52 CHAR(10) Package library Name of the library for extended
name dynamic SQL package.
92 5C BINARY(2) DRDA indicator 0 - Connected to local RDB
1 - Connected to remote RDB
94 5E CHAR(1) Commitment ’A’ - Commit *ALL
control level
’C’ - Commit *CHANGE
’N’ - Commit *NONE
’S’ - Commit *CS (cursor
stability)
95 5F CHAR(512) First 512 bytes of First 512 bytes of the SQL
the SQL statement
statement text
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

The QIBM_QZDA_ROI1 exit point is defined to run an exit program for the
requests that retrieve information about certain objects for the database server. It is
also used for SQL catalog functions.

This exit point has two formats defined.


Objects for which format ZDAR0100 is used to retrieve information:
v Field (or column)
v File (or table)
v File member
v Index
v Library (or collection)
v Record format
v Relational database (or RDB)
v Special columns
v SQL package
v SQL package statement
Objects for which format ZDAR0200 is used to retrieve information:
v Foreign keys
v Primary keys

Parameter fields for exit point QIBM_QZDA_ROI1 format ZDAR0100: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_ROI1 using the ZDAR0100 format.

250 Client Access Express Programming


Table 11. Exit point QIBM_QZDA_ROI1 format ZDAR0100
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier For the database server the value
is *RTVOBJINF.
20 14 CHAR(8) Format name The user exit format name being
used. For the following functions,
the format name is ZDAR0100.
28 1C BINARY(4) Requested The function being performed.
function
This field contains one of the
following:
X’1800’ - Retrieve library
information
X’1801’ - Retrieve relational
database information
X’1802’ - Retrieve SQL
package information
X’1803’ - Retrieve SQL
package statement information
X’1804’ - Retrieve file
information
X’1805’ - Retrieve file member
information
X’1806’ - Retrieve record
format information
X’1807’ - Retrieve field
information
X’1808’ - Retrieve index
information
X’180B’ - Retrieve special
column information
32 20 CHAR(20) Library name The library or search pattern used
when retrieving information
about libraries, packages, package
statements, files, members, record
formats, fields, indexes, and
special columns.
52 34 CHAR(36) Relational The relational database name or
database name search pattern used to retrieve
RDB information.
88 58 CHAR(20) Package name The package name or search
pattern used to retrieve package
or package statement information.
108 6C CHAR(256) File name (SQL The file name or search pattern
alias name) used to retrieve file, member,
record format, field, index, or
special column information.
364 16C CHAR(20) Member name The member name or search
pattern used to retrieve file
member information.

Chapter 3. Express C/C++ APIs 251


Table 11. Exit point QIBM_QZDA_ROI1 format ZDAR0100 (continued)
Offset
Dec Hex Type Field Description
384 180 CHAR(20) Format name The format name or search
pattern used to retrieve record
format information.
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

Parameter fields for exit point QIBM_QZDA_ROI1 format ZDAR0200: The following
table shows parameter fields and their descriptions for the exit program called at
exit point QIBM_QZDA_ROI1 using the ZDAR0200 format.
Table 12. Exit point QIBM_QZDA_ROI1 format ZDAR0200
Offset
Dec Hex Type Field Description
0 0 CHAR(10) User profile The name of the user profile that
name is calling the server.
10 A CHAR(10) Server identifier For the database server the value
is *RTVOBJINF.
20 14 CHAR(8) Format name The user exit format name being
used. For the following functions,
the format name is ZDAR0200.
28 1C BINARY(4) Requested The function being performed.
function
This field contains one of the
following:
X’1809’ - Retrieve foreign key
information
X’180A’ - Retrieve primary
key information
32 20 CHAR(10) Primary key The name of the library that
table library contains the primary key table
name used when retrieving primary
and foreign key information.
42 2A CHAR(128) Primary key The name of the table that
table name (alias contains the primary key used
name) when retrieving primary or
foreign key information.
170 AA CHAR(10) Foreign key The name of the library that
table library contains the foreign key table
name used when retrieving foreign key
information.
180 64 CHAR(128) Foreign key The name of the table that
table name (alias contains the foreign key used
name) when retrieving foreign key
information.
Note: This format is defined by member EZDAEP in files H, QRPGSRC, QRPGLESRC,
QCBLSRC and QCBLLESRC in library QSYSINC.

252 Client Access Express Programming


Stored procedures: Stored procedures commonly are used in client/server
applications, especially in the area of online transaction processing (OLTP), since
they can provide performance, transaction-integrity and security benefits.

The illustration below shows an application where one transaction consists of four
separate I/O operations, each that requires an SQL statement to be processed. In
the client/server environment, this requires a minimum of eight messages between
the server and the client, as shown. This can represent significant overhead,
especially where the communication speed is slow (for example over a dial-up
line), or where the turnaround speed for the connection is slow (for example over
a satellite link).

The following illustration shows the same transaction by a stored procedure on the
server. As illustrated, the communications traffic has been reduced to a single
message pair. There are additional benefits. For example, the procedure can
arrange to send back only the data that is absolutely required (for example, just a
few characters from a long column). A DB2 for OS/400 stored procedure can be
any AS/400 program, and does not have to use SQL for data access.

Chapter 3. Express C/C++ APIs 253


View examples of stored procedures:
v “Examples: Stored procedures”
v “Example: Visual C++ - Accessing and returning data by calling a stored
procedure” on page 274
v “Example: Visual Basic - Accessing and returning data by calling a
stored procedure” on page 276
v “Examples: RPG - Host code for ODBC stored procedures” on page 277

Examples: Stored procedures: For information regarding specific SQL commands that
are used in the examples of stored procedures listed below, see the SQL Reference
book. View an HTML online version of the book, or print a PDF version, from the
DB2 Universal Database for AS/400 books online AS/400 Information Center topic.
Stored procedures examples:
v “Example: Stored procedure calls from C with return values”
v “Example: Stored procedure calls from C with result sets” on page 255
v “Example: Host RPG source” on page 256
v “Example: Running CL commands using SQL stored procedures and
ODBC” on page 257
v “Example: Stored procedure calls from Visual Basic with return values”
on page 258
v “Examples: Calling an AS/400 stored procedure by using Visual Basic”
on page 262
Additional resources for examples of calling stored procedures:
For more ODBC programming examples of calling stored procedures
(Visual Basic 4.0, Visual Basic 5.0, C++, and Lotus Script programming
environments), see:
v “Express ODBC programming examples” on page 265

v IBM ftp Web site (select the vbODBCT3.zip directory to download


the programming examples to your PC).

Example: Stored procedure calls from C with return values:

254 Client Access Express Programming


#define CHAR_COL_LEN 10 /* Character column length */

UCHAR col1[CHAR_COL_LEN+1];

/* Execute the CREATE PROCEDURE statement. This step creates an */


/* entry for the procedure in the system catalog. This Create */
/* only needs to be executed one time. */

_fstrcpy(stmt,"CREATE PROCEDURE P1 (:HV1 INOUT CHAR(10)) ");


_fstrcat(stmt,"(EXTERNAL NAME JMBLIB.P1 LANGUAGE PLI SIMPLE CALL)");
returncode = SQLExecuteDirect(hstmt,stmt,SQL_NTS);"
if (returncode != SQL_SUCCESS)
{
/* Handle error case here. */
}
_fstrcpy(stmt,"CALL P1 (?)");
returncode = SQLPrepare(hstmt,stmt,SQL_NTS);
if(returncode != SQL_SUCCESS)
{
/* Handle error here */
}
/**************************************/
/* Perform set param for argument and */
/* initialize argument */
/**************************************/
SQLBindParameter(hstmt,1,SQL_PARAM_INPUT_OUTPUT,SQL_C_CHAR,
SQL_CHAR,CHAR_COL_LEN,0,col1,sizeof(col1),NULL);
_fstrcpy(col1,CHAR_CONST1);

/*************************************/
/* Execute the CALL statement */
/*************************************/

returncode = SQLExecute(hstmt);
if(returncode != SQL_SUCCESS)
{
/* Handle error here */
}
else
{
/* Process returned value here */
}

Example: Stored procedure calls from C with result sets: This result-sets example calls
an RPG program and receives the data as a result-set array. The program on the
PC can issue the DROP PROCEDURE and CREATE PROCEDURE statements
before issuing a CALL procedure. After returning from the call, execute ODBC
SQLBindCol to set the variables into which to return data. Then execute ODBC
SQLFetch to get the data.

The following is an example of code showing the ODBC calls:


#include "sql.h"
#include "sqlext.h"
#include "string.h"
/* declare the variables */
#define ROW_COUNT 20
UCHAR fetch_all[106];
SDWORD cbcol;
static HENV henv;
static HDBC hdbc;
static HSTMT hstmt;
char stmt[4000];
int ii;
RETCODE rc;
/* connect to a data source */

Chapter 3. Express C/C++ APIs 255


rc = SQLAllocEnv(&henv);
rc = SQLAllocConnect(henv, &hdbc);
rc = SQLConnect(hdbc, "SystemA", SQL_NTS,
"JohnB", SQL_NTS,
"Sesame", SQL_NTS);
/* allocate a statement handle */
SQLAllocStmt(hdbc,&hstmt);
/* drop the old procedure */
_fstrcpy(stmt,"DROP PROCEDURE RPGARY");
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
/* create the procedure to call */
_fstrcpy(stmt,"CREATE PROCEDURE RPGARY RESULT SETS 1 EXTERNAL");
_fstrcat(stmt," NAME JMBLIB.RPGARY LANGUAGE RPG GENERAL");
rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
/* call stored procedure */
_fstrcpy(stmt,"CALL RPGARY()");

rc = SQLExecDirect(hstmt, stmt, SQL_NTS);


/* bind the columns to return variables */
SQLBindCol(hstmt, 1, SQL_C_CHAR, fetch_all, 106, &cbcol);
/* for each row fetch the data */
for(ii=0; ii<ROW_COUNT ;ii++)
{
rc = SQLFetch(hstmt);
/* process data */
}
/* get more results */
rc = SQLMoreResults(hstmt);
/* release the statement handle */
SQLFreeStmt(hstmt,SQL_DROP);
/* release the connection to the data source */
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);

Example: Host RPG source: The RPG program that is called by the procedure
should declare an array to hold the data. It then can open files and read the data
in to the array and perform necessary processing. The SQL SET RESULT SETS
statement identifies the number of rows and attributes of the array result set.
*-------------------------------------------------------------*
* *
* RPG PROGRAM: RPGARY *
* *
* PURPOSE: THIS RPG PROGRAM IS CALLED BY AN ODBC STORED *
* PROCEDURE. IT READS DATA INTO AN ARRAY AND *
* RETURNS THE RESULTS BY USING THE SET RESULT *
* SETS SQL FUNCTION *
* *
*-------------------------------------------------------------*
* FILE DESCRIPTION SPECIFICATIONS *
*-------------------------------------------------------------*
FPERF IF E DISK
*-------------------------------------------------------------*
* INPUT SPECIFICATIONS *
*-------------------------------------------------------------*
IPERFE E DSPERF
IARR DS 20
I 01 105 VAR1
ILCLVAR DS
I B 01 040L#
*-------------------------------------------------------------*
C* ** START OF PROGRAM ** *

*-------------------------------------------------------------*

256 Client Access Express Programming


C OPEN PERF
C Z-ADD0 L#
C LOOP TAG
C READ PERF 9999
C ADD 1 L#
C L# OCUR ARR
C MOVE PERFE ARR
C L# COMP 20 99 99
C N99 GOTO LOOP
*-------------------------------------------------------------*
* *** EXECUTE SQL STATEMENT ***
C/EXEC SQL SET RESULT SETS ARRAY :ARR FOR :L# ROWS
C/END-EXEC
*-------------------------------------------------------------*
C CLOSEPERF
C RETRN
================================================================

Example: Running CL commands using SQL stored procedures and ODBC: Stored
procedure support provides a means to run AS/400 Control Language (CL)
commands by using the SQL CALL statement.
Use CL commands when:
v Performing an override for files
v Initiating debug
v Using other commands that can affect the performance of subsequent
SQL statements

The following examples show cases where a CL command is run on the AS/400 by
using the CALL statement, which calls the program that processes CL commands.
That program (QCMDEXC in library QSYS) expects two parameters:
1. A string that contains the command text to execute
2. A decimal (15,5) field that contains the length of the command text
The parameters must include these attributes for the command to be interpreted
properly. The second parameter on the CALL statement must have characters
explicitly specified for all places of the decimal (15,5) field.

In the following example, a C program on the PC is going to run an OVRDBF


command that is 65 characters long (including embedded blanks). The text of the
OVRDBF command is as follows:
OVRDBF FILE(TESTER) TOFILE(JMBLIB/TESTER) MBR(NO2) OVRSCOPE(*JOB)

The code for performing this command by using ODBC APIs is as follows:
SQLAllocStmt(hdbc,&hstmt);
strcpy(stmt,"call qsys.qcmdexc('OVRDBF FILE(TESTER) TOFILE(JMBLIB/");
strcat(stmt,"TESTER) MBR(NO2) OVRSCOPE(*JOB)',0000000065.00000)");
SQLExecDirect(hstmt,stmt,SQL_NTS);

Statements now run against file jmblib/tester will reference member number 2
rather than the first member.

Another CL command that you might find useful to run against a database server
job is the STRDBG command. This command forces SQL to generate completion
messages for all SQL statements run. In addition, the query Optimizer generates
messages indicating how the queries run in the job were optimized. This
information can be used to troubleshoot queries that are performing poorly. All of
the messages are written to the joblog of the server job running on the AS/400.
This joblog can then be studied to identify problem queries or operations.

Chapter 3. Express C/C++ APIs 257


In the example below, a C program on the PC is going to run a STRDBG command
that is 20 characters long (including embedded blanks). The text of the STRDBG
command is as follows:
STRDBG UPDPROD(*YES)

The code for performing this command by using ODBC APIs is as follows:
SQLAllocStmt(hdbc,&hstmt);
strcpy(stmt,"call qsys.qcmdexc('STRDBG UPDPROD(*YES)',");
strcat(stmt,"0000000020.00000)");
SQLExecDirect(hstmt,stmt,SQL_NTS);

SQL statements run in the job will generate completion messages and Optimizer
debug messages.

Example: Stored procedure calls from Visual Basic with return values: Visual Basic is
able to call external functions that are found in a DLL. Since all ODBC drivers are
DLLs, Visual Basic can be used to code directly to the ODBC APIs. By coding
directly to the ODBC APIs a Visual Basic application can call an AS/400 stored
procedure and return result values. See “Coding directly to ODBC APIs” on
page 216 for more information.

The following example of Visual Basic source code shows how to call an AS/400
stored procedure and then retrieve the returned values into Visual Basic variables.
'***********************************************************************
'* *
'* Because of the way Visual Basic stores and manages the String data *
'* type, it is recommended that you use an array of Byte data type *
'* instead of a String variable on the SQLBindParameter API. *
'* *
'***********************************************************************

Dim sTemp As String


Custnum As Integer
Dim abCustname(34) As Byte
Dim abAddress(34) As Byte
Dim abCity(24) As Byte
Dim abState(1) As Byte
Dim abPhone(14) As Byte
Dim abStatus As Byte
Dim RC As Integer
Dim nullx As Long 'Used to pass null pointer, not pointer to null
Dim lpSQL_NTS As Long 'Used to pass far pointer to SQL_NTS
Static link(7) As Long 'Used as an array of long pointers to the size
'each parameter which will be bound

'***********************************************************************
'* *
'* Initialize the variables needed on the API calls *
'* *
'***********************************************************************

link(1) = 6
link(2) = Ubound(abCustname) +1
link(3) = Ubound(abAddress) +1
link(4) = Ubound(abCity) +1
link(5) = Ubound(abState) +1
link(6) = Ubound(abPhone) +1
link(7) = 1

RC = 0
nullx = 0
lpSQL_NTS = SQL_NTS ' -3 means passed as sz string

258 Client Access Express Programming


'***********************************************************************
'* *
'* Create the procedure on the AS/400. This will define the *
'* procedure's name, parameters, and how each parameter is passed. *
'* Note: This information is stored in the system catalog tables and *
'* and only needs to be executed one time for the life of the stored *
'* procedure. It normally would not be run in the client application. *
'* *
'***********************************************************************

sTemp = "Create Procedure Storedp2 (:Custnum in integer, "


sTemp = sTemp & ":Custname out char(35), :Address out char(35),"
sTemp = sTemp & ":City out char(25), :State out char(2),"
sTemp = sTemp & ":Phone out char(15), :Status out char(1))
sTemp = sTemp & "(External name rastest.storedp2 language cobol General)"

RC = SQLExecDirect(Connection.hstmt, sTemp, Len(sTemp))

'Ignore error assuming that any error would be from procedure already
'created.

'***********************************************************************
'* *
'* Prepare the call of the procedure to the AS/400. *
'* For best performance, prepare the statement only one time and
'* execute many times.
'* *
'***********************************************************************

sTemp = "Call storedp2(?, ?, ?, ?, ?, ?, ?)"


RC = SQLPrepare(Connection.hstmt, sTemp, Len(sTemp))

If (RC <> SQL_SUCCESS) Then


DescribeError Connection.hdbc, Connection.hstmt
frmMain.Status.Caption = "Error on SQL_Prepare " & RTrim$(Tag)
End If

'***********************************************************************
'* *
'* Bind all of the columns passed to the stored procedure. This will *
'* set up the variable's data type, input/output characteristics, *
'* length, and initial value. *
'* The SQLDescribeParam API can optionally be used to retrieve the
'* parameter types.
'* *
'* To properly pass an array of byte to a stored procedure and receive *
'* an output value back, you must pass the first byte ByRef. *
'* *
'***********************************************************************

RC = SQLBindParameter(Connection.hstmt, 1, SQL_PARAM_INPUT, SQL_C_SHORT, _


SQL_NUMERIC, 6, 0, Custnum, 6, link(1))

RC = SQLBindParameter(Connection.hstmt, 2, SQL_PARAM_OUTPUT, SQL_C_CHAR, _


SQL_CHAR, 35, 0, abCustname(0), UBound(abCustname)+1, link(2))
RC = SQLBindParameter(Connection.hstmt, 3, SQL_PARAM_OUTPUT, SQL_C_CHAR, _
SQL_CHAR, 35, 0, abAddress(0), UBound(abAddress)+1, link(3))
RC = SQLBindParameter(Connection.hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, _
SQL_CHAR, 25, 0, abCity(0), UBound(abCity)+1, link(4))
RC = SQLBindParameter(Connection.hstmt, 5, SQL_PARAM_OUTPUT, SQL_C_CHAR, _
SQL_CHAR, 2, 0, abState(0), UBound(abState)+1, link(5))
RC = SQLBindParameter(Connection.hstmt, 6, SQL_PARAM_OUTPUT, SQL_C_CHAR, _
SQL_CHAR, 15, 0, abPhone(0), UBound(abPhone)+1, link(6))
RC = SQLBindParameter(Connection.hstmt, 7, SQL_PARAM_OUTPUT, SQL_C_CHAR, _

Chapter 3. Express C/C++ APIs 259


SQL_CHAR, 1, 0, abStatus, 1, link(7))

'***********************************************************************
'* *
'* The Prepare and Bind only needs to be execute once. The Stored
'* procedure can now be called multiple times by just changing the data
'* *
'***********************************************************************
Do While

'***********************************************************************
'* Read in a customer number *
'* *
'***********************************************************************

Custnum = Val(input.text)

'***********************************************************************
'* *
'* Execute the call of the procedure to the AS/400. *
'* *
'***********************************************************************

RC = SQLExecute(Connection.hstmt)
frmMain.Status.Caption = "Ran Stored Proc" & RTrim$(Tag)

If (RC <> SQL_SUCCESS) Then


DescribeError Connection.hdbc, Connection.hstmt
frmMain.Status.Caption = "Error on Stored Proc Execute " & RTrim$(Tag
End If

'***********************************************************************
'* *
'* Set text labels to display the output data *
'* You must convert the array of Byte back to a String
'* *
'***********************************************************************

lblCustname = StrConv(abCustname(), vbUnicode)


lblAddress = StrConv(abAddress(), vbUnicode)
lblCity = StrConv(abCity(), vbUnicode)
lblState = StrConv(abState(), vbUnicode)
lblPhone = StrConv(abPhone(), vbUnicode)
lblStatus = StrConv(abStatus(), vbUnicode)

Loop
View the COBOL stored procedures source code:
“Example: COBOL source code”

Example: COBOL source code: The following is the COBOL source code to the
stored procedures that are used in “Example: Stored procedure calls from Visual
Basic with return values” on page 258:
0031.00
0032.00 IDENTIFICATION DIVISION.
0033.00
0034.00 PROGRAM-ID. STOREDP2.
0035.00 ENVIRONMENT DIVISION.
0036.00 CONFIGURATION SECTION.
0037.00 SOURCE-COMPUTER. IBM-AS400.
0038.00 OBJECT-COMPUTER. IBM-AS400.
0039.00
0040.00 INPUT-OUTPUT SECTION.

260 Client Access Express Programming


0041.00
0042.00 FILE-CONTROL.
0043.00
0044.00 DATA DIVISION.
0045.00
0046.00 FILE SECTION.
0047.00
0048.00 ****************************************************************
0049.00 ****************************************************************
0050.00
0051.00 WORKING-STORAGE SECTION.
0052.00
SQL EXEC SQL INCLUDE SQLCA
SQL END-EXEC.
0055.00
0055.01 01 INDIC1 PIC S9(4) COMP-4.
0055.02 01 INDIC2 PIC S9(4) COMP-4.
0055.03 01 INDIC3 PIC S9(4) COMP-4.
0055.04 01 INDIC4 PIC S9(4) COMP-4.
0055.05 01 INDIC5 PIC S9(4) COMP-4.
0055.06 01 INDIC6 PIC S9(4) COMP-4.
0056.00
0088.00
0089.00 ****************************************************************
0090.00 ****************************************************************
0091.00
0092.00 LINKAGE SECTION.
0093.00
0094.00 01 CUSTNUM PIC S9(9) COMP-4.
0095.00 01 CUSTNAME PIC X(35).
0096.00 01 CUSTADDR PIC X(35).
0097.00 01 CITY PIC X(25).
0098.00 01 STATE PIC X(2).
0099.00 01 PHONE PIC X(15).
0099.01 01 STATF PIC X.
0104.00
0105.00 ****************************************************************
0106.00 ****************************************************************
0107.00 ****************************************************************
0108.00 ****************************************************************
0109.00
0110.00 PROCEDURE DIVISION
0111.00 USING CUSTNUM
0112.00 CUSTNAME
0113.00 CUSTADDR
0114.00 CITY
0115.00 STATE
0116.00 PHONE
0117.00 STATF.
0121.00
SQL EXEC SQL WHENEVER SQLERROR GO TO 60-SQLERRTAG
SQL END-EXEC.
SQL EXEC SQL WHENEVER SQLWARNING GO TO 70-SQLWARNTAG
SQL END-EXEC.
SQL EXEC SQL WHENEVER NOT FOUND GO TO 80-SQLNOTFND
SQL END-EXEC.
0123.05
0124.00 PERFORM 10-RUN-SELECT.
0127.00 GO TO 999-END-PGM.
0128.00
0129.00 10-RUN-SELECT.
0129.01 MOVE "A" TO STATF.
SQL EXEC SQL SELECT CUSTNUM,CUSTNAME,ADDRESS,CITY,STATE,PHONE
SQL INTO :CUSTNUM :INDIC1, :CUSTNAME
SQL :INDIC2, :CUSTADDR :INDIC3,
SQL :CITY :INDIC4, :STATE
SQL :INDIC5, :PHONE :INDIC6

Chapter 3. Express C/C++ APIs 261


SQL FROM RASTEST.CUSTOMER WHERE CUSTNUM = :CUSTNUM
SQL END-EXEC.
0362.00
0371.00
0372.00 60-SQLERRTAG.
0374.00 MOVE "B" TO STATF.
0374.01 GO TO 999-END-PGM.
0374.03 70-SQLWARNTAG.
0374.04 MOVE "C" TO STATF.
0374.05 GO TO 999-END-PGM.
0374.06 80-SQLNOTFND.
0374.07 MOVE "D" TO STATF.
0379.00
0380.00 999-END-PGM.
0381.00 EXIT.

Examples: Calling an AS/400 stored procedure by using Visual Basic: The Visual Basic
programming examples listed below show a stored procedure call being prepared.
Two statements are shown:
1. A statement for the creation of the stored procedure
2. A statement to prepare the call
Create the stored procedure only once. The definition that it provides is available
to ODBC applications, as well as to integrated OS/400 applications.
Read this topic first for useful information:
“Tips: Running and calling AS/400 stored procedures by using Visual
Basic”
View the Visual Basic stored procedures examples:
v “Example: Visual Basic - Calling an AS/400 stored procedure (1 of 2)” on
page 263
v “Example: Using arrays of byte” on page 263
v “Example: Visual Basic - Calling an AS/400 stored procedure (2 of 2)” on
page 264

Tips: Running and calling AS/400 stored procedures by using Visual Basic:
Running a stored procedure on the AS/400:
ODBC provides a standard interface for calling stored procedures. The
implementation of stored procedures differs significantly across various
databases. This simple example follows the recommended approach for
running a stored procedure on the AS/400:
1. Set up a create procedure statement for the stored procedure and create
it. The creation of the stored procedure only needs to be done once it
does not have to done through ODBC. The definition that it provides is
available to all ODBC as well as integrated OS/400 applications. This
step can also help performance, as the Optimizer knows in advance the
data type, the direction of the parameters, and the language of the
procedure.
2. Prepare the stored procedure call.
3. Bind the parameters of the procedure, indicating whether each
parameter is to be used for input to the procedure, output from the
procedure, or input/output.
4. Call the stored procedure.
Calling AS/400 stored procedures using Visual Basic:
Use care in coding the SQLBindParameter functions. Never use Visual
Basic strings as a buffer when binding either columns (SQLBindCol) or
parameters (SQLBindParameter). Instead, use byte arrays, which–unlike

262 Client Access Express Programming


strings–will not be moved around in memory. See “Example: Using arrays
of byte” for more information.
Pay careful attention to the data types that are involved. There may be
subtle differences with those that you use with, for instance, a select
statement. Also, ensure that you have an adequately sized buffer for
output and input/output parameters. The way that you code the stored
procedure on the AS/400 can affect performance significantly. Whenever
possible, avoid closing the program with exit() in C language and with
SETON LR in RPG language. Preferably, use RETRN or return, but you
may need to re-initialize variables on each call, and by-pass file opens.

Example: Visual Basic - Calling an AS/400 stored procedure (1 of 2):


Dim rc As Integer
Dim Response As Integer
Dim StoredProc As String * 256
Dim DeclareProc As String * 256
Dim Parm1() as Byte

' Set up the creation of the SP


DeclareProc = "CREATE PROCEDURE p1 (:hv in char(10))
(external name apilib.p1 language rpg simple call)"

' Prepare the create statement


rc = SQLPrepare(ghstmt, DeclareProc, SQL_NTS)
If rc <> SQL_SUCCESS Then
Call DspSQLError(ghenv, ghdbc, ghstmt, "SQLPrepare Error")
End
End If

StoredProc = "call p1(?)"

' Prepare the stored procedure call


rc = SQLPrepare(ghstmt, StoredProc, SQL_NTS)
If rc <> SQL_SUCCESS Then
Call DspSQLError(ghenv, ghdbc, ghstmt, "SQLPrepare Error")
End
End If
Related topic:
“Example: Using arrays of byte”
View part 2 of the Visual Basic - Calling an AS/400 stored procedure example:
“Example: Visual Basic - Calling an AS/400 stored procedure (2 of 2)” on
page 264

Example: Using arrays of byte: Because of the way Visual Basic stores and manages
the String data type, using an array of Byte data type instead of a String variable is
recommended for the following parameter types:
v Input/output parameters
v Output parameters
v Any parameter that contains binary data (rather then standard ANSI characters)
v Any input parameter that has a variable address which is set once, but refered
to many times
The last case would be true for the “Example: Visual Basic - Calling an AS/400
stored procedure (2 of 2)” on page 264 sample if the application made multiple
calls to SQLExecute, while modifying Parm1 between each call. The following
Visual Basic functions assist in converting strings and arrays of byte:
Public Sub Byte2String(InByte() As Byte, OutString As String)
'Convert array of byte to string
OutString = StrConv(InByte(), vbUnicode)

Chapter 3. Express C/C++ APIs 263


End Sub

Public Function String2Byte(InString As String, OutByte() As Byte) As Boolean


'vb byte-array / string coercion assumes unicode string
'so must convert String to Byte one character at a time
'or by direct memory access
'This function assumes Lower Bound of array is 0

Dim I As Integer
Dim SizeOutByte As Integer
Dim SizeInString As Integer

SizeOutByte = UBound(OutByte) + 1
SizeInString = Len(InString)

'Verify sizes if desired

'Convert the string


For I = 0 To SizeInString - 1
OutByte(I) = AscB(Mid(InString, I + 1, 1))
Next I
'If size byte array > len of string pad with Nulls for szString
If SizeOutByte > SizeInString Then 'Pad with Nulls
For I = SizeInString To UBound(OutByte)
OutByte(I) = 0
Next I
End If

String2Byte = True
End Function

Public Sub ViewByteArray(Data() As Byte, Title As String)


'Display message box showing hex values of byte array

Dim S As String
Dim I As Integer
On Error GoTo VBANext

S = "Length: " & Str(UBound(Data) - LBound(Data) + 1) & " Data (in hex):"
For I = LBound(Data) To UBound(Data)
If (I Mod 8) = 0 Then
S = S & " " 'add extra space every 8th byte
End If
S = S & Hex(Data(I)) & " "
VBANext:
Next I
MsgBox S, , Title

End Sub

Example: Visual Basic - Calling an AS/400 stored procedure (2 of 2):


Redim Parm1(10) 'Resize to String length(10) + 1 byte for null
Call String2Byte(Trim$(tParm1.Text), Parm1)

' Bind the (single) parameter


rc = SQLBindParameter(ghstmt, 1, SQL_PARAM_INPUT, SQL_CHAR, SQL_CHAR,
10, 0, Parm1(0), 11, SQL_NTS)
If rc <> SQL_SUCCESS Then
Call DspSQLError(ghenv, ghdbc, ghstmt, "SQLBindParameter Error")
End
End If

' Run the stored procedure


rc = SQLExecute(ghstmt)
If rc <> SQL_SUCCESS Then

264 Client Access Express Programming


Call DspSQLError(ghenv, ghdbc, ghstmt, "SQLExecDirect Error")
End
End If

Examples: Running CL commands using stored procedures: It is possible to run


AS/400 commands by using stored procedures. Simply call Execute Command
(QCMDEXC) to run the command. The process is relatively simple, but ensure that
you include all of the zeros in the length parameter. Use the Remote Command
API as an alternative.

The two examples that are provided here apply to ODBC programs. The first
example enables the powerful SQL tracing facility that writes data into the joblog
for the job running the SQL (in this case, the OS/400 server job). This feature is
described in “Collecting an SQL.LOG (ODBC Trace)” on page 288.

The second example overcomes a restriction in SQL: its limited ability to work
with multi-member files. You cannot create a multi-member file through CREATE
TABLE. However, the following example shows you how to access with ODBC
anything but the first member of a file that is created through DDS:

Example 1: CL commands using stored procedures


' Put the AS/400 job in debug mode
rc = SQLAllocStmt(hdbc, dbghstmt)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, dbghstmt, "File Override")
End If

cmd = "call qsys.qcmdexc('STRDBG UPDPROD(*YES)',0000000020.00000)"


rc = SQLExecDirect(dbghstmt, cmd, SQL_NTS)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, dbghstmt, "Start Debug")
End If

' Override the AS/400 file to point to the 'france' member


rc = SQLAllocStmt(hdbc, ovrhstmt)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT, "File Override")
End If

Example 2: CL commands using stored procedures


' Put the AS/400 job in debug mode
rc = SQLAllocStmt(hdbc, dbghstmt)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, dbghstmt, "File Override")
End If

cmd = "call qsys.qcmdexc('OVRDBF FILE(BRANCH) TOFILE(APILIB/BRANCH)


MBR(FRANCE) OVRSCOPE(*JOB)',0000000068.00000)"
rc = SQLExecDirect(ovrhstmt, cmd, SQL_NTS)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, ovrhstmt, "File Override")
End If

Express ODBC programming examples


The following ODBC programming examples demonstrate simple queries, and
accessing and returning data by calling stored procedures. C++, Visual Basic and
RPG programming language versions are provided.

Chapter 3. Express C/C++ APIs 265


View more examples of ODBC stored procedures in the “Examples: Stored
procedures” on page 254 topic.

Note: To access ODBC programming samples (Visual Basic 4.0, Visual Basic 5.0,
C++, and Lotus Script programming environments), link to the IBM ftp site

on the
Express ODBC Web. Select examples:
programming vbODBCT3.zip to download the samples.
v “C++ Example: ODBC simple query”
v “Visual Basic example: ODBC simple query” on page 271
v “Example: Visual C++ - Accessing and returning data by calling a stored
procedure” on page 274
v “Example: Visual Basic - Accessing and returning data by calling a
stored procedure” on page 276
v “Examples: RPG - Host code for ODBC stored procedures” on page 277

C++ Example: ODBC simple query: This sample code that follows uses ODBC in
a Visual C++ V 4.0 project to perform simple inquiry operations on a database file
that is called PARTS.

Only part of the code is shown: the ODBC calls that relate to a single-part inquiry.
C++ Example: ODBC simple query topics:
v “ODBC query C++ example: Prompting for the data source”
v “ODBC query C++ example: Data declarations”
v “ODBC query C++ example: The Part Record class” on page 267
v “ODBC query C++ example: Making the AS/400 connection” on
page 267
v “ODBC query C++ example: Preparing the statements” on page 268
v “ODBC query C++ example: Binding columns and parameters” on
page 269
v “ODBC query C++ example: Getting a row” on page 269
v “ODBC query C++ example: Mapping the data” on page 270
v “ODBC query C++ example: Ending the connection” on page 270

ODBC query C++ example: Prompting for the data source: When the program starts, it
prompts for the data source name. All of the available ODBC data sources display.
To run this program, you must set up a data source to access the server AS/400
system. Set the default library to APILIB, and the *SQL naming convention that is
used.

Note: SQLDriverConnect can be used as an alternative to SQLConnect. It has the


advantage of automatically prompting the user for a data source, if
requested to do so.

ODBC query C++ example: Data declarations: This example shows the declarations
for the ODBC functions and buffers that are used for input, output, and data
storage:
// Parameters for ODBC function calls
HENV m_henv; // ODBC environment handle
HDBC m_hdbc; // ODBC connection handle
HSTMT m_Shstmt; // ODBC statement handle for single record request
HSTMT m_Mhstmt; // ODBC statement handle for multi-record request
RETCODE rc; // Return code

266 Client Access Express Programming


// Buffers for input parameters and returned columns
long m_lInPartNo;
// Single record request returned columns
long m_lSPartNo;
char m_szSPartDesc[26];
long m_lSPartQty;
double m_dSPartPrice;
DATE_STRUCT m_dsSPartDate;
// Multi-record request returned columns
long m_lMPartNo;
char m_szMPartDesc[26];
long m_lMPartQty;
double m_dMPartPrice;
DATE_STRUCT m_dsMPartDate;
// Character strings for formatted date fields
char m_szSPartDate[11];
char m_szMPartDate[11];

ODBC query C++ example: The Part Record class: The CPartRecord class is used in
this example to create part objects. Getters and Setters are used to retrieve or set
information from the part object.
class CPartRecord : public CObject {
public:
CPartRecord();
// Attributes
protected:
long m_lPartNo;
CString m_szPartDesc;
long m_lPartQty;
double m_dPartPrice;
CString m_szPartDate;
// Operations
public:
// Getters
long GetPartNo() const;
CString GetPartDesc() const;
long GetPartQty() const;
double GetPartPrice() const;
CString GetPartDate() const;
// Setters
void SetPartNo(long lPartNo);
void SetPartDesc(CString szPartDesc);
void SetPartQty(long lPartQty);
void SetPartPrice(double dPartPrice);
void SetPartDate(CString szPartDate);
};

ODBC query C++ example: Making the AS/400 connection: The following code
example uses ODBC calls to connect to an ODBC data source. The examples use
SQLDriverConnect to prompt for the data source name. The function that is
shown, MakeAS400Connection, is called from within the C++ example.
/***********************************************************
* Function: MakeAS400Connection
* Arguments: None
* Return: Unsigned integer
* Notes: Initialize the connection with the AS/400
**************************************************************/

UINT CAPISampDoc::MakeAS400Connection()
{
// Initialize the ODBC environment
SQLCHAR szConnStrIn[] = ""; // Input connection string
SQLSMALLINT cbConnStrIn = 0; // Length of input connection string
SQLCHAR szConnStrOut[257]; // Buffer for ODBC connection string
SQLSMALLINT cbConnStrOut; // Number of bytes ConnStrOut

Chapter 3. Express C/C++ APIs 267


SQLSMALLINT cbConnStrOutMax = 256; // Max length of ConnStrOut buffer

SDWORD lc bBuffer = 0;
// Allocate an environment handle
rc = SQLAllocEnv(&m_henv);;
if(rc != SQL_SUCCESS) {
DisplayError(rc, "Unable to allocate ODBC environment");
return APIS_INIT_ERROR;
}

// Allocate a connection handle


rc = SQLAllocConnect(m_henv, &m_hdbc);;
if(rc != SQL_SUCCESS) {
DspSQLError(m_henv, SQL_NULL_HDBC, SQL_NULL_HSTMT);
return APIS_INIT_ERROR;
}

// Connect to the data source, prompting for its name


rc = SQLDriverConnect(m_hdbc, m_hWnd, szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, &cbConnStrOut,; SQL_DRIVER_COMPLETE);
if (rc == SQL_NO_DATA_FOUND) {
// User pressed 'cancel' or there was an error so tidy up and return
rc = SQLFreeConnect(m_hdbc);
rc = SQLFreeEnv(m_henv);
return APIS_NO_MORE_DATA;
}

ODBC query C++ example: Preparing the statements: This section of code shows how
to allocate statement handles and prepare statements for later processing. For any
ODBC statement that will be runmore than once, this technique provides enhanced
performance. The statement is prepared once, but runs multiple times.

// SQL stsements to run on the server


UCHAR szSSQLStmt[] = "select * from parts where partno = ?";
UCHAR szMSQLStmt[] = "select * from parts";

// Allocate statement handles


rc = SQLAllocStmt(m_hdbc, &m_Shstmt);;
if(rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_INIT_ERROR;
}

rc = SQLAllocStmt(m_hdbc, &m_Mhstmt);;
if(rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_INIT_ERROR;
}

// Prepare the select statements


// Note: This statement contains "?" where the part number
// would be in an actual SQL statement. This called
// a parameter marker. Its value will be supplied at run
// time.
//
rc = SQLPrepare(m_Shstmt, szSSQLStmt, strlen((const char *) szSSQLStmt));
if(rc != SQL_SUCCESS &&; rc != SQL_SUCCESS_WITH_INFO) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_INIT_ERROR;
}

rc = SQLPrepare(m_Mhstmt, szMSQLStmt, sizeof(szMSQLStmt));


if(rc != SQL_SUCCESS &&; rc != SQL_SUCCESS_WITH_INFO) {
DspSQLError(m_henv, m_hdbc, m_Mhstmt);
return APIS_INIT_ERROR;
}

268 Client Access Express Programming


ODBC query C++ example: Binding columns and parameters: In this example,
SQLBindParameter is used to connect parameter 1 (the only parameter) for
statement m_Shstmt to a storage variable called &m_lInPartNo. Whenever ODBC
statement m_Shstmt is run, the value for parameter 1 will be the current value of
m_lInPartNo.
rc = SQLBindParameter(m_Shstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG,
SQL_INTEGER, 0, 0, &m_lInPartNo,; 0, &lcbBuffer);;
if(rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_INIT_ERROR;
}

// Bind the Columns for first SQL statement


// Note: Binding the columns is used to control the
// location of where information that is returned by the
// successful run of an ODBC statement will be placed.
// In this example, we are expecting five columns to
// be returned from the SQL select statements.
// For example, column one will be placed in
// storage location m_lSPartNo.
rc = SQLBindCol(m_Shstmt, 1, SQL_C_SLONG, &m_lSPartNo,;
sizeof(m_lSPartNo), &lcbBuffer);;
rc |= SQLBindCol(m_Shstmt, 2, SQL_C_CHAR, &m_szSPartDesc,;
26, &lcbBuffer);;
rc |= SQLBindCol(m_Shstmt, 3, SQL_C_SLONG, &m_lSPartQty,;
sizeof(m_lSPartQty), &lcbBuffer);;
rc |= SQLBindCol(m_Shstmt, 4, SQL_C_DOUBLE, &m_dSPartPrice,;
sizeof(m_dSPartPrice), &lcbBuffer);;
rc |= SQLBindCol(m_Shstmt, 5, SQL_C_DATE, &m_dsSPartDate,;
10, &lcbBuffer);;
if(rc != SQL_SUCCESS) {
DisplayError(rc, "Problem binding a column for first statement");
return APIS_INIT_ERROR;
}

ODBC query C++ example: Getting a row: This example shows how to set the input
parameter value and run the statement. If the processing of the select is successful,
the result will be placed in an SQL result set.SQLFetch is used to retrieve the
selected rows from the result set. The column values for each row that are
retrieved from the result set will be placed in the storage area to which the
columns are bound.
m_lInPartNo = PartNo;

// Run the prepared SQL select statement


rc = SQLExecute(m_Shstmt);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_SEND_ERROR;
}

// (Try to) fetch a record


rc = SQLFetch(m_Shstmt);
if (rc == SQL_NO_DATA_FOUND) {
// Free the statement handle for repeated processing
rc = SQLFreeStmt(m_Shstmt, SQL_CLOSE);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_RECEIVE_ERROR;
}
return APIS_PART_NOT_FOUND;
}

Chapter 3. Express C/C++ APIs 269


else if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_RECEIVE_ERROR;
}

ODBC query C++ example: Mapping the data: The following example uses the
Setters to map the data to the part object. The statement handle then is freed, so
that it can be run again.
// First format the data to a character string
sprintf(m_szSPartDate, "%4d-%02d-%02d", m_dsSPartDate.year,
m_dsSPartDate.month, m_dsSPartDate.day);

// Map the data into the part object


pRec->SetPartNo(m_lSPartNo);
pRec->SetPartDesc(m_szSPartDesc);
pRec->SetPartQty(m_lSPartQty);
pRec->SetPartPrice(m_dSPartPrice);
pRec->SetPartDate(m_szSPartDate);

// Free the statement handle for repeated processing


rc = SQLFreeStmt(m_Shstmt, SQL_CLOSE);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_Shstmt);
return APIS_RECEIVE_ERROR;
}

ODBC query C++ example: Ending the connection: This example demonstrates
ending the ODBC connection. First the ODBC statements are freed (by using
SQL_Drop). Next, the ODBC data source is disconnected and the connection
handle and ODBC environment handle are freed .
/***********************************************************
* Function: EndAS400Connection
* Arguments: None
* Return: Unsigned integer
* Notes: End the connection with the AS/400
**************************************************************/

UINT CAPISampDoc::EndAS400Connection()
{
// End the ODBC connections and free environment
RETCODE rc;

// Drop the statement handles


rc = SQLFreeStmt(m_Shstmt, SQL_DROP);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_END_ERROR;
}

rc = SQLFreeStmt(m_Mhstmt, SQL_DROP);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_END_ERROR;
}

// Disconnect from the data source


rc = SQLDisconnect(m_hdbc);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_END_ERROR;
}

// Free the connection handle

270 Client Access Express Programming


rc = SQLFreeConnect(m_hdbc);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, SQL_NULL_HDBC, SQL_NULL_HSTMT);
return APIS_END_ERROR;
}

// Free the environment handle


rc = SQLFreeEnv(m_henv);
if (rc != SQL_SUCCESS) {
DisplayError(rc, "Unable to free ODBC environment");
return APIS_END_ERROR;
}
return APIS_SUCCESS;
}

Visual Basic example: ODBC simple query: The sample code in the example that
follows uses ODBC in a Visual Basic V 4.0 project to perform simple enquiry
operations on a database file that is called PARTS.

Only part of the code is shown here: the ODBC calls that relate to a single part
inquiry.
Example: Visual Basic - ODBC simple query topics:
v “ODBC query Visual Basic example: Prompting for the data source”
v “ODBC query Visual Basic example: Making the connection (1 of 2)”
v “ODBC query Visual Basic example: Making the connection (2 of 2)” on
page 272
v “ODBC query Visual Basic example: Preparing the statements” on
page 272
v “ODBC query Visual Basic example: Binding the parameter” on page 272
v “ODBC query Visual Basic example: Getting a row” on page 273
v “ODBC query Visual Basic example: Ending the connection” on page 274

ODBC query Visual Basic example: Prompting for the data source: When starting the
application, select the System menu option and then select Connect from the
pulldown menu. All the available ODBC data sources display. To run this program,
you must set up a data source to access the server AS/400 system. Set the default
library to APILIB and use the *SQL naming convention. This is the standard
dialog box that is displayed with SQLDriverConnect.

Note: SQLDriverConnect can be used as an alternative to SQLConnect. It has the


advantage of automatically prompting the user for a data source, when
requested.

ODBC query Visual Basic example: Making the connection (1 of 2): This section shows
the declaration for the ODBC functions and buffers that are used for input, output,
and data storage.
Dim szConnStrIn As String 'Input connection string
Dim cbConnStrIn As Integer 'Length of input connection string
Dim szConnStrOut As String * 257 'Buffer for ODBC connection string
Dim cbConnStrOut As Integer 'Number of bytes ConnStrOut
Dim cbConnStrOutMax As Integer 'Max length of ConnStrOut buffer
Dim szSSQLStmt As String 'SQL stmt to select single record
Dim szMSQLStmt As String 'SQL stmt to select all parts
Dim lcbBuffer As Long 'pcbValue
Dim rc As Integer 'Return code
'***********************************

'* Allocate an environment handle


rc = SQLAllocEnv(henv)
If rc <> SQL_SUCCESS Then

Chapter 3. Express C/C++ APIs 271


Call DisplayError(rc, " Unable to allocate ODBC environment")
End If

'* Allocate a connection handle


rc = SQLAllocConnect(henv, hdbc)
If rc <> SQL_SUCCESS Then
Call DisplayError(rc, " Unable to allocate ODBC connection")
Call DspSQLError(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT)
End If

ODBC query Visual Basic example: Making the connection (2 of 2): This section
demonstrates an example of using ODBC calls to connect to an ODBC data source.
The examples use SQLDriverConnect to prompt for the data source name.
'* Connect to the data source, prompting for its name

szConnStrIn = "" 'Initialize connection string


cbConnStrIn = Len(szConnStrIn) 'Get length
cbConnStrOutMax = 256 'Max output buffer length

rc = SQLDriverConnect(hdbc, frmMain.hwnd, szConnStrIn, cbConnStrIn,_


szConnStrOut, cbConnStrOutMax, cbConnStrOut, SQL_DRIVER_COMPLETE)
If rc = SQL_NO_DATA_FOUND Then
'* User pressed 'cancel' or there was an error so tidy up and return
rc = SQLFreeConnect(hdbc)
rc = SQLFreeEnv(henv)
End If

If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then


Call DisplayError(rc, "SQLDriverConnect failed.")
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT)
End If

ODBC query Visual Basic example: Preparing the statements: This section of code
shows how to allocate statement handles and prepare statements for later
processing. For any ODBC statement that will be run more than once, this
technique provides more enhanced performance. The statement is prepared once,
but runs multiple times.
'* Allocate statement handles
rc = SQLAllocStmt(hdbc, lShstmt)
If rc <> SQL_SUCCESS Then
Call DisplayError(rc, "SQLAllocStmt failed.")
Call DspSQLError(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT)
End If
rc = SQLAllocStmt(hdbc, lMhstmt)
If rc <> SQL_SUCCESS Then
Call DisplayError(rc, "SQLAllocStmt failed.")
Call DspSQLError(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT)
End If
'* Prepare the select statements
szSSQLStmt = "select * from parts where partno = ?"
rc = SQLPrepare(lShstmt, szSSQLStmt, SQL_NTS)
If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then
Call DisplayError(rc, "SQLPrepare failed.")
Call DspSQLError(henv, hdbc, lShstmt)
End If
szMSQLStmt = "select * from parts"
rc = SQLPrepare(lMhstmt, szMSQLStmt, SQL_NTS)
If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then
Call DisplayError(rc, "SQLPrepare failed.")
Call DspSQLError(henv, hdbc, lShstmt)
End If

ODBC query Visual Basic example: Binding the parameter: In this example,
SQLBindParameter is used to connect parameter 1 (the only parameter) for

272 Client Access Express Programming


statement m_Shstmt to a storage variable that is called lSPartNumber. Whatever
ODBC statement lShstmt runs, the value for parameter 1 will be the current value
of lSPartNumber.

Since lSPartNumber is defined as an integer, there is no concern about Visual Basic


moving its location.
lcbBuffer = 0

'Bind the input parameter for the first SQL statement


rc = SQLBindParameter(lShstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, _
SQL_INTEGER, 0, 0, lSPartNumber, 0, lcbBuffer)
If rc <> SQL_SUCCESS Then
Call DisplayError(rc, "Problem binding parameter for first statement")
End If

ODBC query Visual Basic example: Getting a row: This example shows how to set the
input parameter value and run the statement. If the processing of the select is
successful, the result will be placed in an SQL result set. SQLFetch is used to
retrieve the selected rows from the result set.

SQLGetData is used to move the information from the result set to the storage
areas.
Dim rc As Integer 'Return code
Dim lcbBuffer As Long
Dim sSDescription As String * 25 'Description for single record
Dim lSQuantity As Long 'Quantity for single record
Dim dSPrice As Double 'Price for single record
Dim sSReceivedDate As String * 10 'Received date for single record
'*****************************************

If Len(txtPartNumber.Text) = 0 Then
Beep
MsgBox "A Part# must be specified", vbOK, "Send Data Queue"
Else
lSPartNumber = Val(txtPartNumber)
txtStartTime = Time 'Record start time

' Run the SQL statement


rc = SQLExecute(lShstmt)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, lShstmt)
End If
'Fetch the result
rc = SQLFetch(lShstmt)
If rc = SQL_NO_DATA_FOUND Then
mnuClear_Click 'Clear screen
txtPartNumber = lSPartNumber 'Show the part number not found
Call DisplayMessage("RECORD NOT FOUND")
txtEndTime = Time 'Record end time
' Free the statement handle for repeated processing
rc = SQLFreeStmt(lShstmt, SQL_CLOSE)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, lShstmt)
End If
Else
lcbBuffer = 0
'Get Description
rc = SQLGetData(lShstmt, 2, SQL_C_CHAR, sSDescription, _
25, lcbBuffer)
'Get Quantity. SQLGetLongData uses alias SQLGetData
rc = SQLGetLongData(lShstmt, 3, SQL_C_SLONG, lSQuantity, _
Len(lSQuantity), lcbBuffer)
'Get Price. SQLGetDoubleData uses alias SQLGetData
rc = SQLGetDoubleData(lShstmt, 4, SQL_C_DOUBLE, dSPrice, _

Chapter 3. Express C/C++ APIs 273


Len(dSPrice), lcbBuffer)
'Get Received date
rc = SQLGetData(lShstmt, 5, SQL_C_CHAR, sSReceivedDate, _
10, lcbBuffer)
If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT)
Call DisplayError(rc, "Problem getting a column for 1st statement")
End If

txtDescription = sSDescription 'Show description


txtQuantity = lSQuantity 'Show quantity
txtPrice = Format(dSPrice, "currency") 'Convert dSPrice to currency
txtReceivedDate = CDate(sSReceivedDate) 'Convert string to date
Call DisplayMessage("Record found")
' Free the statement handle for repeated processing
rc = SQLFreeStmt(lShstmt, SQL_CLOSE)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, lShstmt)
End If
txtEndTime = Time 'Record end time
End If
End If

ODBC query Visual Basic example: Ending the connection: This programming
example shows how to end the ODBC connection. First the ODBC statements are
freed (by using SQL_Drop). Next, you disconnect from the ODBC data source and
then free the connection handle and ODBC environment handle.
If hdbc <> SQL_NULL_HDBC Then
' Drop the statement handles
rc = SQLFreeStmt(lShstmt, SQL_DROP)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT)
End If

rc = SQLFreeStmt(lMhstmt, SQL_DROP)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT)
End If
' Disconnect from the data source
rc = SQLDisconnect(hdbc)
If rc <> SQL_SUCCESS Then
Call DspSQLError(henv, hdbc, SQL_NULL_HSTMT)
End
End If

Example: Visual C++ - Accessing and returning data by calling a stored


procedure: This example works in a similar manner to the one in “C++ Example:
ODBC simple query” on page 266, except that a stored procedure is used to access
the data and return it to the PC rather than select and fetch statements.

Only the code relevant to the stored procedure call has been included, as the
connect/disconnect routines are identical to the earlier example

Creating the stored procedure


//* Drop the old Procedure
strcpy(szDropProc,"drop procedure apilib.partqry2");

rc = SQLExecDirect(m_hstmt, (unsigned char *)szDropProc, SQL_NTS);

// This statement is used to create a stored procedure


// Unless the
// procedure is destroyed, this statement need never be re-created
strcpy(szCreateProc,"CREATE PROCEDURE APILIB.PARTQRY2 (INOUT P1 INTEGER," );
strcat(szCreateProc,"INOUT P2 INTEGER)");

274 Client Access Express Programming


strcat(szCreateProc,"EXTERNAL NAME APILIB.SPROC2 LANGUAGE RPG GENERAL")

//' Create the new Procedure


rc = SQLExecDirect(m_hstmt, (unsigned char *)szCreateProc, SQL_NTS);
if (rc != SQL_SUCCESS &&; rc != SQL_SUCCESS_WITH_INFO) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_INIT_ERROR;
}
if(rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, SQL_NULL_HSTMT);
return APIS_INIT_ERROR;
}

Preparing the statements


// Prepare the procedure call
strcpy(szStoredProc, "call partqry2(?, ?)");
// Prepare the stored procedure statement
rc = SQLPrepare(m_hstmt, (unsigned char *) szStoredProc, strlen(szStoredProc));
if(rc != SQL_SUCCESS &&; rc != SQL_SUCCESS_WITH_INFO) {
DspSQLError(m_henv, m_hdbc, m_hstmt);
return APIS_INIT_ERROR;
}

Binding the parameters


// Bind the parameters for the stored procedure

rc = SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG,


SQL_INTEGER, sizeof(m_lOption), 0, &m_lOption, sizeof(m_lOption), &lcbon),
&lcbOption);
rc |= SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG,
SQL_INTEGER, sizeof(m_lPartNo), 0, &m_lPartNo, sizeof(m_lPartNo), &lcbon),
&lcbOption);

// Bind the Columns


rc = SQLBindCol(m_hstmt, 1, SQL_C_SLONG, &m_lSPartNo,
sizeof(m_lSPartNo), &lcbBuffer);
rc |= SQLBindCol(m_hstmt, 2, SQL_C_CHAR, &m_szSPartDesc,
26, &lcbBuffer);
rc |= SQLBindCol(m_hstmt, 3, SQL_C_SLONG, &m_lSPartQty,
sizeof(m_lSPartQty), &lcbBuffer);
rc |= SQLBindCol(m_hstmt, 4, SQL_C_DOUBLE, &m_dSPartPrice,
sizeof(m_dSPartPrice), &lcbBuffer);
rc |= SQLBindCol(m_hstmt, 5, SQL_C_DATE, &m_dsSPartDate,
10, &lcbBuffer);

Calling the stored procedure


// Request a single record
m_lOption = ONE_RECORD;
m_lPartNo = PartNo;

// Run the stored procedure


rc = SQLExecute(m_hstmt);
if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_hstmt);
return APIS_SEND_ERROR;
}

// (Try to) fetch a record


rc = SQLFetch(m_hstmt);
if (rc == SQL_NO_DATA_FOUND) {
// Free the statement handle for repeated processing
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
return APIS_PART_NOT_FOUND;
}

Chapter 3. Express C/C++ APIs 275


else if (rc != SQL_SUCCESS) {
DspSQLError(m_henv, m_hdbc, m_hstmt);
return APIS_RECEIVE_ERROR;
}

// If we are still here we have some data, so map it back


// Format and display the data
.
.
.

Example: Visual Basic - Accessing and returning data by calling a stored


procedure: Creating the stored procedure
' This statement will drop an existing stored procedure
szDropProc = "drop procedure apilib.partqry2"

'* This statement is used to create a stored procedure


'* Unless the
'* procedure is destroyed, this statement need never be re-created
szCreateProc = "CREATE PROCEDURE APILIB.PARTQRY2 (INOUT P1 INTEGER,"
szCreateProc = szCreateProc & "INOUT P2 INTEGER)"
szCreateProc = szCreateProc & "EXTERNAL NAME APILIB.SPROC2 LANGUAGE RPG GENERAL"

'* Allocate statement handle


rc = SQLAllocStmt(hdbc, hstmt)
If rc <> SQL_SUCCESS Then
Call DisplayError(rc, "SQLAllocStmt failed.")
Call DspSQLError(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT)
End If
'* Drop the old Procedure
rc = SQLExecDirect(hstmt, szDropProc, SQL_NTS)

' Create the new Procedure


rc = SQLExecDirect(hstmt, szCreateProc, SQL_NTS)
If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then
Call DisplayError(rc, "SQLCreate failed.")
Call DspSQLError(henv, hdbc, hstmt)
End If

Preparing the statements


'* This statement will be used to call the stored procedure
szStoredProc = "call partqry2(?, ?)"
'* Prepare the stored procedure call statement

rc = SQLPrepare(hstmt, szStoredProc, Len(szStoredProc))


If rc <> SQL_SUCCESS And rc <> SQL_SUCCESS_WITH_INFO Then
Call DisplayError(rc, "SQLPrepare failed.")
Call DspSQLError(henv, hdbc, hstmt)
End If

Binding the parameters

'Bind the parameters for the stored procedure


rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, _
SQL_INTEGER, lLen1, 0, sFlag, lLen1, lCbValue)

If rc <> SQL_SUCCESS Then


Call DisplayError(rc, "Problem binding parameter ")
End If

rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, _


SQL_INTEGER, 4, 0, lPartNumber, lLen2, lCbValue)

276 Client Access Express Programming


If rc <> SQL_SUCCESS Then
Call DisplayError(rc, "Problem binding parameter ")
End If

Calling the stored procedure


rc = SQLExecute(hstmt)
If lRc <> SQL_SUCCESS Then
' Free the statement handle for repeated processing
rc = SQLFreeStmt(hstmt, SQL_CLOSE)
Call DspSQLError(henv, hdbc, hstmt)
End If
rc = SQLFetch(hstmt)
If rc = SQL_NO_DATA_FOUND Then
mnuClear_Click 'Clear screen
txtPartNumber = lPartNumber 'Show the part number not found
Call DisplayMessage("RECORD NOT FOUND")
.
.
Else
'Get Description
rc = SQLGetData(hstmt, 2, SQL_C_CHAR, sSDescription, _
25, lcbBuffer)
'Get Quantity. SQLGetLongData uses alias SQLGetData
rc = SQLGetLongData(hstmt, 3, SQL_C_SLONG, lSQuantity, _
Len(lSQuantity), lcbBuffer)
'Get Price. SQLGetDoubleData uses alias SQLGetData
rc = SQLGetDoubleData(hstmt, 4, SQL_C_DOUBLE, dSPrice, _
Len(dSPrice), lcbBuffer)
'Get Received date
rc = SQLGetData(hstmt, 5, SQL_C_CHAR, sSReceivedDate, _
10, lcbBuffer)
txtDescription = sSDescription 'Show description
txtQuantity = lSQuantity 'Show quantity
txtPrice = Format(dSPrice, "currency") 'Convert dSPrice to
txtReceivedDate = CDate(sSReceivedDate) 'Convert string to d
Call DisplayMessage("Record found")
End If

Examples: RPG - Host code for ODBC stored procedures: This program,
SPROC2, is called from the client as a stored procedure via ODBC. It returns data
to the client from the PARTS database file.

RPG/400® (non-ILE) example:


* THIS EXAMPLE IS WRITTEN IN RPG/400 (NON-ILE)
*
* DEFINES PART AS AN INTEGER (BINARY 4.0)
*
I#OPTDS DS
I B 1 40#OPT
I#PRTDS DS
I B 1 40#PART
C *ENTRY PLIST
C PARM #OPTDS
C PARM #PRTDS
* COPY PART NUMBER TO RPG NATIVE VARIABLE WITH SAME
* ATTRIBUTES OF FIELD IN PARTS MASTER FILE (PACKED DECIMAL 5,0)
C Z-ADD#PART PART 50
C #OPT CASEQ1 ONEREC
C #OPT CASEQ2 ALLREC
C ENDCS
C SETON LR
C RETRN
*
****************************

Chapter 3. Express C/C++ APIs 277


C ONEREC BEGSR
****************************
* PROCESS REQUEST FOR A SINGLE RECORD.
C/EXEC SQL DECLARE C1 CURSOR FOR
C+ SELECT
C+ PARTNO,
C+ PARTDS,
C+ PARTQY,
C+ PARTPR,
C+ PARTDT
C+
C+ FROM PARTS -- FROM PART MASTER FILE
C+
C+ WHERE PARTNO = :PART
C+
C+
C+ FOR FETCH ONLY -- READ ONLY CURSOR
C/END-EXEC
C*
C/EXEC SQL
C+ OPEN C1
C/END-EXEC
C*
C/EXEC SQL
C+ SET RESULT SETS CURSOR C1
C/END-EXEC
C ENDSR
****************************
C ALLREC BEGSR
****************************
* PROCESS REQUEST TO RETURN ALL RECORDS
C/EXEC SQL DECLARE C2 CURSOR FOR
C+ SELECT
C+ PARTNO,
C+ PARTDS,
C+ PARTQY,
C+ PARTPR,
C+ PARTDT
C+
C+ FROM PARTS -- FROM PART MASTER FILE
C+
C+
C+ ORDER BY PARTNO -- SORT BY PARTNO
C+
C+ FOR FETCH ONLY -- READ ONLY CURSOR
C/END-EXEC
C*
C/EXEC SQL
C+ OPEN C2
C/END-EXEC
C*
C/EXEC SQL
C+ SET RESULT SETS CURSOR C2
C/END-EXEC
C ENDSR

ILE-RPG example:
* This example is written in ILE-RPG
*
* Define option and part as integer
D#opt s 10i 0
D#part s 10i 0
* Define part as packed 5/0
Dpart s 5p 0

C *entry plist

278 Client Access Express Programming


C parm #opt
C part parm #part

C #opt caseq 1 onerec


C #opt caseq 2 allrec
C endcs

C eval *inlr = *on


C return
*
****************************
C onerec begsr
****************************
* Process request for a single record.
C/EXEC SQL DECLARE C1 CURSOR FOR
C+ SELECT
C+ PARTNO,
C+ PARTDS,
C+ PARTQY,
C+ PARTPR,
C+ PARTDT
C+
C+ FROM PARTS -- FROM PART MASTER FILE
C+
C+ WHERE PARTNO = :PART
C+
C+
C+ FOR FETCH ONLY -- READ ONLY CURSOR
C/END-EXEC
C*
C/EXEC SQL
C+ OPEN C1
C/END-EXEC
C*
C/EXEC SQL
C+ SET RESULT SETS CURSOR C1
C/END-EXEC
C endsr
****************************
C allrec begsr
****************************
* Process request to return all records
C/EXEC SQL DECLARE C2 CURSOR FOR
C+ SELECT
C+ PARTNO,
C+ PARTDS,
C+ PARTQY,
C+ PARTPR,
C+ PARTDT
C+
C+ FROM PARTS -- FROM PART MASTER FILE
C+
C+
C+ ORDER BY PARTNO -- SORT BY PARTNO
C+
C+ FOR FETCH ONLY -- READ ONLY CURSOR
C/END-EXEC
C*
C/EXEC SQL
C+ OPEN C2
C/END-EXEC
C*
C/EXEC SQL
C+ SET RESULT SETS CURSOR C2
C/END-EXEC
C endsr

Chapter 3. Express C/C++ APIs 279


Express ODBC troubleshooting
The following topics provide general guidelines for finding and resolving Client
Access Express ODBC errors:
v “When ODBC is unable to connect to the AS/400”
v “Collecting the QZDASOINIT joblog” on page 282
v “Common errors” on page 282
v “Gathering information for IBM Support” on page 286
v “ODBC diagnostic and performance tools” on page 289

When ODBC is unable to connect to the AS/400: Each ODBC connection


communicates with one database server program that runs on the AS/400. This
program is referred to as the host server program. The name of the Database
Server program used with TCP/IP is QIWS/QZDASOINIT.

Under normal conditions, the program is evoked transparently, and the user is not
required to take action except to verify that the proper subsystems and
communication protocols are running. See the Client Access Express Host Servers
book in the IBM BookManager BookServer online library for details on
administration of host server jobs.

If ODBC is unable to connect to the AS/400, perform the following troubleshooting


tasks:
v Check the server status
v Verify that the host server program is installed
v Verify that the proper subsystems are running
v Verify that the proper prestart jobs are running
“Additional TCP/IP considerations” on page 281

Checking the server status: The Client Access Express for Windows product has a
special command to verify status of host servers:
CWBPING systemname

where systemname is the name of the AS/400 system.

The command should return the following:


To cancel the CWBPING request, press CTRL-C or CTRL=BREAK
I - Verifying connection to system BMNELSON1...
I - Successfully connected to server application: Central Client
I - Successfully connected to server application: Network File
I - Successfully connected to server application: Network Print
I - Successfully connected to server application: Data Access
I - Successfully connected to server application: Data Queues
I - Successfully connected to server application: Remote Command
I - Successfully connected to server application: Security
I - Successfully connected to server application: Telnet
I - Connection verified to system MYAS400

If the servers are not active, continue to “Verifying that host server program is
installed”.

Verifying that host server program is installed: The Database Server is installed as
part of the operating system. If all PCs are still unable to connect to the server or
the QSERVER subsystem is not on the system, then verify that product xxxxSS1,
option Host Servers is installed where xxxx is the OS/400 lpp (license program
product) for the version current version of OS/400.

280 Client Access Express Programming


Verifying that subsystems are active: TCP/IP-connected ODBC jobs (QZDASOINIT)
will run in the QSERVER subsystem. Verify that this subsystem is running.

Because of changes made to subsystem descriptions in V3R1 and later, the


QSERVER subsystem may need to be manually started. To do this, simply issue the
following command:
STRSBS QSERVER

To have the subsystem start automatically at IPL, then modify the AS/400 IPL Start
up procedure (the default is QSYS/QSTRUP) to include the STRSBS QSERVER
command.

In addition to subsystem QSERVER, subsystem QSYSWRK must be running.

“Verifying that prestart jobs are running”

Verifying that prestart jobs are running: IBM ships the QSERVER subsystem
configured to use prestart jobs to improve performance at job initialization/start
up. When prestart jobs are configured in the subsystem, the job MUST be active to
connect. The prestart job used for a TCP/IP connection is:
v QZDASOINIT - Server program
v QZDASRVSD - Server Daemon program

To verify a prestart job is running:


WRKSBSJOB QSERVER

The appropriate prestart jobs should be active:


Job User Type -----Status-----
QZDASOINIT QUSER PJ ACTIVE (socket connection)
QZDASRVSD QUSER PJ ACTIVE (socket connection)

Prestart jobs do not display in WRKACTJOB unless a connection is already active.


You must use F14 - Include from the WRKACTJOB panel for prestart jobs to
display.

“Additional TCP/IP considerations”

Additional TCP/IP considerations: Verify that TCP/IP is started with the following
command:
NETSTAT *CNN

Use the command STRTCP to start the desired protocol if it is not running.

Verify the necessary daemons are running by browsing the information returned
from the NETSTAT *CNN command:
Remote Remote Local
Address Port Port Idle Time State
* * as-cent > 000:09:31 Listen
* * as-signon 000:09:41 Listen
* * as-svrmap 002:57:45 Listen
* * as-data > 002:57:45 Listen

Use the command STRHOSTSVR SERVER(*ALL) to start them if necessary.


v Verify QZDASRVSD, the ODBC socket daemon, is running.
– as-database should be in the Listen State

Chapter 3. Express C/C++ APIs 281


– WRKJOB QZDASRVSD should be used to check the joblog of the daemon for
any error messages.
v Verify that socket daemon QZSOMAPD is running in QSYSWRK subsystem.
– as-svrmap should be in the Listen State as shown by NETSTAT *CNN.
– WRKJOB QZSOMAPD should be used to check the joblog of the daemon for
any error messages.

The PC locates the socket used by the database server by connecting to the server
mapper socket. It retrieves the socket used by as-database. It then connects to the
proper socket which is being monitored by the file server daemon, QZDASRVSD.
The server daemon will attach the client’s connection to a QZDASOINIT prestart
job in QSERVER. After validating the user profile and password and swapping the
user profile into the prestart job, the job will run similar to the QZDAINIT job. If
this is the first connection made to the AS/400 for this PC, then two other servers
are used: Central server for licensing and Signon server for userid/password
validation.

Collecting the QZDASOINIT joblog: To receive optimal support, generate, locate


and retrieve the QZDASOINIT joblog. The joblog may contain messages that can
help you to determine and resolve errors that are returned through ODBC.
v “Generating a joblog”
v “Finding the joblog”

Generating a joblog: Some internal errors cause the job to immediately end. To
isolate these types of errors, use the CHGJOB command to modify the existing
database server job and to generate a joblog. Modify the job description to change
all new jobs. To modify the default job description, enter the following command
prior to recreating the error:
CHGJOBD JOBD(QDFTJOBD) LOG(4 00 *SECLVL)

When it is finished, execute this command to change it back:


CHGJOBD JOBD(QDFTJOBD) LOG(4 00 *NOLIST)

If the job description is not changed back, other jobs on the system will force
joblogs to be written, and system storage will fill up rapidly.

Finding the joblog: Follow these steps to find the joblog:


1. Type the following command and prompt for parameters using F4:
CHGPRTF FILE(QPJOBLOG)
2. Press F10 and Page down to a field called Spooled Output Queue. This is the
OUTQ to which the joblog will be written. By default it is QEZJOBLOG in
library QUSRSYS.
3. Record the file and library name of the output queue, and then run the
following command to work with all of the entries in the output queue:
WRKOUTQ QEZJOBLOG
4. Press F16 to move to the bottom of the list.

An alternative way of finding the joblog is to use the WRKSPLF command. Use
the following command:
WRKSPLF USERID

where USERID is QUSER or your USERID.

Common errors:

282 Client Access Express Programming


v “Communication errors”
v “SQL errors”
v “Delphi and PowerBuilder errors” on page 285
v “Stored procedure errors” on page 285
v “ODBC incorrect output and unpredictable errors” on page 286

Communication errors: Communications errors are returned with the following


syntax:
[IBM][Client Access Express ODBC Driver (32-bit)][DB2 UDB for AS/400]Communications link failure.

where xxxx is the error number in decimal—not hexadecimal—format. Message


text describing the nature of your error appears with the error number.

Communication errors will cause the ODBC connection to be disconnected


immediately so that no additional problems occur.

SQL errors:
v “MSGSQL0113 - Name &1 not allowed.”
v “MSGSQL0114 - Relational database &1 not the same as current &2 server”
v “MSGSQL0122 - Column &1 or function specified in SELECT...”
v “MSGSQL0204 - MYSYSCONF not found” on page 284
v “MSGSQL0900 - Application process not in a connected state” on page 284
v “MSGSQL5001 - Column qualifier or table &2 undefined.” on page 284
v “MSGSQL5016 - Object name &1 not valid for naming convention” on page 284
v “MSGSQL0104 - Token &1 was not valid. Valid tokens: &2” on page 284
v “MSGSQL7008 &1 in &2 not valid for operation. The reason code is 3” on
page 285

MSGSQL0113 - Name &1 not allowed.: See “MSGSQL0114 - Relational database &1
not the same as current &2 server”.

MSGSQL0114 - Relational database &1 not the same as current &2 server: It is likely
that the system name is not in the Remote Database Directory. Run the Add
Relational Database Directory Entry command:
ADDRDBDIRE RDB(SYSNAME) RMTLOCNAME(*LOCAL)

Where SYSNAME is the name of your system’s Default Local Location name (as
specified in the DSPNETA command).

Another common cause for this error is a period (.) in a table or library name.
Although valid in AS/400 naming conventions, in order to use it within an SQL
statement, enclose the name within double quotes. A short term circumvention
may be to build a logical file over the desired physical file, using the SQL naming
syntax.

MSGSQL0122 - Column &1 or function specified in SELECT...: When using a GROUP


BY clause, all of the columns in the SELECT list must be in the GROUP BY clause
or within a column function. This use is different than in a scalar function. The
Database Management book contains an explanation:

If GROUP BY or HAVING is used:


v Each column-name in the select list must either identify a grouping column or
be specified within a column function.
v The RRN, PARTITION, NODENAME, and NODENUMBER functions cannot be
specified in the select list.

Chapter 3. Express C/C++ APIs 283


v The select list is applied to each group of R. The result contains as many rows as
there are groups in R. When the select list is applied to a group of R, that group
is the source of the arguments of the column functions in the select list.

Note: You can view an HTML online version of the Database Management book, or
print a PDF version, from the DB2 Universal Database for AS/400 books
online topic in the AS/400 Information Center.

For example:
″SELECT workdept, salary from employee GROUP BY workdept″ files because
salary is not in the GROUP BY.
″SELECT field1, DATE(field2) from T1 GROUP BY field1″ fails because field2 is
not in a column function or the GROUP BY.
″SELECT workdept, AVG(salary) from employee GROUP BY workdept order by
2″ completes because workdept is a grouping column and salary is specified in
a column function (AVG).

MSGSQL0204 - MYSYSCONF not found: Usually only joblogs for jobs using the
Microsoft Jet Engine (MS ACCESS or MS Visual Basic applications) contain this
message. The MS Jet Engine always checks for an optional table on the server that
is called MSYSCONF. The applications ignore this warning. For further information
see the MS Jet Database Engine Connectivity white paper or contact Microsoft.

MSGSQL0900 - Application process not in a connected state: See “MSGSQL5016 -


Object name &1 not valid for naming convention” and “MSGSQL0114 - Relational
database &1 not the same as current &2 server” on page 283.

MSGSQL5001 - Column qualifier or table &2 undefined.: See “MSGSQL5016 - Object


name &1 not valid for naming convention”.

MSGSQL5016 - Object name &1 not valid for naming convention: Your ODBC Data
Source Name (DSN) configuration uses the wrong naming convention. Use the
ODBC Administrator to change your DSN to use the proper (*SQL or *SYS)
naming convention. Always use *SQL unless your application design specifically
expects *SYS.

MSGSQL0104 - Token &1 was not valid. Valid tokens: &2:


v The application generated an SQL statement with incorrect syntax.
v See “MSGSQL0114 - Relational database &1 not the same as current &2 server”
on page 283 if ″*″ is the token.
v The SQL statement exceeded the 32K size limitation of the AS/400. If this error
occurs because of a very large literal in the SQL statement, such as a large
CHAR or VARCHAR field, consider using a parameter marker instead. This
reduces the size of the SQL statement while allowing you to pass the maximum
field size allowed.
v The application is using incorrect syntax for left outer join. Some applications
default to a proprietary left outer join syntax of *= in the WHERE clause
(PowerBuilder 3.0 & 4.0, Crystal Reports). Check with your application vendor.
Most provide an ini setting or a configuration value to use ODBC left outer join
syntax.
v Your ODBC Data Source Name (DSN) configuration uses the wrong decimal
separator character. Some users have set the decimal separator parameter of the
ODBC connection to a comma instead of a period.

284 Client Access Express Programming


MSGSQL7008 &1 in &2 not valid for operation. The reason code is 3: The AS/400
performs commitment control by journaling. Any ODBC application that takes
advantage of commitment control will require journaling the files that are used.

Delphi and PowerBuilder errors:


Incorrect number of rows (or no rows) returned on SELECT
Your ODBC Data Source Name (DSN) may be configured to use prefetch.
Prefetch can not be used with applications that use extended fetch and
change the rowset size after issuing the EXECUTE.

Stored procedure errors: The following are typical stored procedure errors:
v “Internal driver error (DB2 UDB for AS/400 SQL)”
v “SQL0444 - External program &A in &B not found (DB2 UDB for AS/400 SQL)”
v “No data returned on OUTPUT and INPUT_OUTPUT parameters”
v “MSGSQL0501 - Cursor CRSR000x not open” on page 286
v “No data returned on result set” on page 286

Internal driver error (DB2 UDB for AS/400 SQL): Preparing or executing a stored
procedure when the server is unable to find a valid declaration of the stored
procedure generates this error. Stored procedures should be defined to DB2
Universal Database (UDB) for AS/400 by using either the DECLARE PROCEDURE
or CREATE PROCEDURE SQL statement. The internal driver error occurs during
the prepare when the SQL statement contains parameter markers and the database
server is unable to locate the definition of the parameters.

When using CREATE PROCEDURE, run a query over QSYS2/SYSPROCS to verify


that the CREATE PROCEDURE was run correctly. SPECIFIC_SCHEMA and
ROUTINE_SCHEMA must match the library that is used on the call in the PC
application. EXTERNAL_NAME must resolve to the actual program name. The
parameter descriptions must also be correct. You can also use the SQLProcedures
and SQLProcedureColumns ODBC APIs to retrieve the catalog information.

When using the older DECLARE PROCEDURE, you must use extended dynamic
support to return output or input/output parameters. You must also store the call
of the stored procedure in the active package. Use PRTSQLINF on the package to
verify the package contents. Delete the SQL package after making any change to
DECLARE PROCEDURE. Parameter descriptions are stored in the package as part
of the call entry, not the declare entry.

DECLARE PROCEDURE takes precedence over CREATE PROCEDURE. Delete the


package if the problem persists.

SQL0444 - External program &A in &B not found (DB2 UDB for AS/400 SQL): The
SQL0444 is generated on an execute or execute direct when the database server is
unable to locate the program. Remember that SQL does not perform a library list
search. The stored procedure name (the procedure name parameter that is used on
the CREATE PROCEDURE statement) must be in the default collection.

No data returned on OUTPUT and INPUT_OUTPUT parameters: An ODBC Spy


utility is useful for trouble-shooting problems that involve parameter markers.
Most spys will show the value of the parameter when it was entered and returned.
v The ODBC SQLBindParameter API incorrectly specified fParamType as
SQL_PARAM_INPUT.
v DECLARE PROCEDURE was used instead of CREATE PROCEDURE, and
extended dynamic support is disabled.

Chapter 3. Express C/C++ APIs 285


v The programmer incorrectly declared a parameter as IN on the CREATE or
DECLARE PROCEDURE.
v The stored procedure program incorrectly returned the parameter.
v An application error damageed the output. This is a common error with Visual
Basic (all versions) and PowerBuilder (3.0 and 4.0).

PowerBuilder (3.0 and 4.0) only supports input parameters on store procedures.
You must use the PowerBuilder Remote Program Call (RPC) to work with
input/output or output parameters. See the ODBC User’s Guide for an example.
When using Visual Basic to make direct ODBC API calls, verify that Visual Basic
has not changed the address of the parameter that was set on the
SQLBindParameter API. This usually occurs when binding a String data type and
results in damageed data or an irrecoverable exception.

MSGSQL0501 - Cursor CRSR000x not open: To return data when using embedded
SQL in ILE programs, you must specify the compile option ACTGRP(*CALLER)
and not the default of *NEW.

Verify that the program executes a return instead of an exit.

When the stored procedure program executes an exit instead of a return, you must
set the Close SQL Cursor option to *ENDACTGRP. If the Close SQL Cursor option
is set to *ENDMOD, the cursor will be closed before data is retrieved.

Also verify that the CREATE PROCEDURE specifies the correct number of result
sets. This is especially important when using array result sets.

No data returned on result set: See “MSGSQL0501 - Cursor CRSR000x not open”.

ODBC incorrect output and unpredictable errors: Ensure that the Client Access
Express ODBC driver and the database server program are at matching code
levels. Check for PTF corequisite requirements on any PTF that you order or in the
readme.txt file of the Client Access Service Pack. If problems continue, verify that
you have disabled the prefetch option in the ODBC Data Source. The prefetch
option should be used only with applications that use the Fetch API, not the
Extended Fetch API.

Note that stored procedure result set cursors are forward only, read only.
Binary or hexadecimal data instead of ASCII characters
The default value of the Translation parameter is Do Not Translate
CCSID 65535. The AS/400 attaches a character set identifier (CCSID) to files, tables and even
Translate CCSID 65535 ensures that the raw data is not damaged.
Setting the Translation parameter to Translate CCSID 65535 updates the
CCSID that is attached to the data to the CCSID of the job. This parameter
setting can cause damage to the data, if the data is truly binary.

Gathering information for IBM Support: So the IBM Support staff can offer you
the best service, please have certain information available when you open a
problem record to IBM Support. To gather this information, complete the following
tasks:
1. Record the OS/400 version and cumulative PTF level.
2. Record the version of the Client Access ODBC driver.
3. Record the version of the ODBC driver manager.
4. Collect an ODBC trace (SQL.log)

286 Client Access Express Programming


5. Gather the QZDASOINIT joblog
6. Record additional information about other components, such as the PC
application, error description, and ODBC log.

Recording the OS/400 version and cumulative PTF level: To receive optimal support,
you will need to record the OS/400 version and cumulative PTF level for your
AS/400 system. Record this information by completing the following steps:
1. Issue the display PTF command on an AS/400 terminal emulation command
line:
DSPPTF
2. Record the OS/400 release information that has the format VxRxMx.
3. Verify that the IPL source is ##MACH#B.
4. Press F5 to display the PTF details.
5. Record the first PTF ID in the list. It will have the format Tzxxyyy where xx is
the year, yyy the Julian date and z is either L or C.

Recording the version of the Client Access Express for Windows ODBC driver: To
receive optimal support, you will need to record the version for your Client Access
Express for Windows ODBC driver. Record this information by completing the
following steps:
1. From the Task bar select Start –> Settings –> Control Panel.
2. Double-click the Client Access Properties icon.
3. The General tab of the Client Access Properties dialog will display by default.
Record the Client Access version and service pack levels.

Recording the version of the 32–bit ODBC driver manager: To record the version for
your 32-bit ODBC driver manager, complete the following steps:
1. From the Task bar, select Start –> Find –> Files or Folders.
2. Enter ODBC32.DLL as the file name and select Find.
3. Note the size and date of the file.
4. Right-mouse on the file name and select Properties.
5. Select the Version tab and record the file version.

Chapter 3. Express C/C++ APIs 287


Collecting an SQL.LOG (ODBC Trace): Client Access Express (32-bit) - ODBC Data
Source Adminstrator dialog: Tracing tab

Follow these steps to collect an SQL.LOG:


1. Start ODBC Data Source Administrator.
2. Select the Tracing tab
3. Select the Start Tracing Now button.
4. Select Apply or OK.
5. Recreate the error
6. Return to ODBC Administrator.
7. Select the Tracing tab.
8. Select the Stop Tracing Now button.
9. The trace can be viewed in the location that you initially specified in the Log
file Path box.

Also see “Sample: ODBC trace” on page 165.

Recording additional information: To receive optimal support, record:


v “Name and version of the PC application”
v “Error messages” on page 289
Consult your hardware or software documentation for instructions on how to
obtain the required information.

Name and version of the PC application: Record the name and version of the PC
application that was used when the error was generated.

288 Client Access Express Programming


Error messages: To receive optimal support, record the PC application error
message, the Client Access ODBC error message, and the SQLState. It also may be
helpful to have a description of the action you were attempting when the failure
occurred. This information will enable the IBM Support staff to more accurately
recreate the problem.

The PC application provides an error message. Include the exact text and error
numbers in the error message. When a printer is unavailable, the image of the
error message can be captured by pressing the print screen key. Print screen copies
a bitmap of the current screen to the clipboard. Use your preferred application to
access and store the error bitmap in a folder for future reference.

ODBC defines a standard, layered error handling protocol. Include the return code,
the identity of the error source, the actual error text, and the ODBC SQLSTATE in
the ODBC error message. Client Access ODBC uses the following format to
identify the source of the error:
[IBM][Client Access Express ODBC Driver (32-bit)][DB2 UDB for AS/400 SQL]
Entry Definition
[IBM] The vendor identifier. If this value is anything except IBM, the failure did
not occur in IBM code. An error starting with [Microsoft] [ODBCxxx
DLL] implies the failure was at the ODBC driver manager.
[Client Access Express ODBC Driver 32-bit)]
The component that is reporting the error. When the Client Access Express
ODBC Driver reports the error and the [DB2 UDB for AS/400 SQL] field
does not follow, then the error occured on the PC. The request was never
sent to the AS/400.
[DB2 UDB for AS/400 SQL]
The AS/400. This field, when included, means that the failure originated
from the AS/400. The AS/400 joblog may contain additional information
for these types of errors.
For more information, see “Client Access ODBC error messages” on
page 165.

Note: Some programming languages encapsulate the ODBC APIs within their own
object structure. Examples include Microsoft DAO, RDO, and ADO. These
objects usually return their own error or return code. The programmer must
retrieve the actual ODBC error message. The ODBC error message may be
held in an error object.

ODBC diagnostic and performance tools:


v “Error message help”
v “ODBC trace utilities” on page 290
v “AS/400 communications trace” on page 290
v “AS/400 job traces” on page 290
v “AS/400 performance tools” on page 290
v “AS/400 job log” on page 290

Error message help: All of the Client Access error messages can be found either on
the AS/400 or in a Client Access help. For errors that begin with SQL, use the
following OS/400 command to view the message text:
DSPMSGD RANGE(SQLxxxx) MSGF(QSQLMSG)

Chapter 3. Express C/C++ APIs 289


For error messages that begin with IWS or PWS, use the following OS/400
command:
DSPMSGD RANGE(ZZZxxxx) MSGF(QIWS/QIWSMSG)
where ZZZ is IWS or PWS.

ODBC trace utilities: ODBC 3.0 includes its own trace utility. Available retail
utilities can be more robust, providing detailed entry and exit point tracing of
ODBC API calls. These tracing utilities include Trace Tools (Dr. DeeBee) and SST
Trace Plus (Systems Software Technology).

AS/400 communications trace: The OS/400 communications trace facility will trace
and format any communications type that has a line description (token ring and
Ethernet).

This is a great tool for isolating many problems. It also is a useful aid for
diagnosing where a performance delay is occurring. Use the timestamp and
eye-catcher fields to measure how long the AS/400 takes to process a request.

AS/400 job traces: The OS/400 job trace can help isolate most host problems and
many performance issues. A service job must first be started on the job to be
traced. Locate the fully qualified job name of the ODBC job. From any 5250
emulation session, start a service job on this QZDASOINIT job by using the
STRSRVJOB command. Then choose one of two traces, depending on the
information needed:
Trace job
Traces the internal calls made by the host server. Run the TRCJOB *ON
command.
Debug trace
Used to review the performance of your application and to determine the
cause of a particular problem.

The STRDBG command can be run against an active service job. This command
logs the decisions made by the query Optimizer to the joblob of the debug session.
It records estimated query times, access paths used, cursor errors, etc. Use the
following command:
STRDBG UPDPROD(*YES)

See “Collecting an SQL.LOG (ODBC Trace)” on page 288 for additional


information.

AS/400 performance tools: AS/400 performance toolkit provides reports and utilities
that can be used to create an in—depth analysis of your application performance.
The toolkit provides information about CPU utilization, disk arm utilization,
memory paging and much more. Although the base operating system includes the
ability to collect performance data, you will need the separately licensed program
Performance Tools/400 to analyze the results.

AS/400 job log: The ODBC joblog can record all errors that occur on the AS/400.
When the job is in debug mode (see “AS/400 job traces”), the joblog also will
contain performance-related information.

290 Client Access Express Programming


Express database APIs (Optimized SQL)
Note: This topic previously was titled Optimized Structured Query Language
(SQL). All previous references to Optimized SQL in this topic have been
renamed Expres database APIs.

Client Access Express database APIs provide a superset of the function that is
provided in the ODBC interface. All of the ODBC function is provided, along with
extensions that allow an application developer to take advantage of unique AS/400
functions. The Express database APIs provide access to AS/400 database files
through a call-level interface.
Express database APIs required files:

Header file Import library Dynamic Link Library


cwbdb.h cwbapi.lib cwbdb.dll

Express Toolkit:
The Client Access Express Toolkit provides Database documentation, access
to the cwbdb.h header file, and links to sample programs. To access this
information, open the Express Toolkit and select Database —> C/C++
APIs.
Express database APIs topics:
“Express database APIs overview”
“Typical use of Express database APIs” on page 293
“Objects that process data on the PC or AS/400” on page 295
“Code page support in Windows” on page 295
Database APIs listing
“Example: Using SQL to access database functions” on page 467
“Express Database (Optimized SQL) APIs return codes” on page 21
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Express database APIs overview


Use Express database SQL APIs to access database functions on the AS/400. These
functions can be grouped into three categories:
v Catalog information
v SQL functions
v Native database (NDB) functions

The Express Database APIs are built on an object-oriented base. Handles are used
to provide an application access to the following classes of objects:
v “Connection object”
v “Catalog request object” on page 292
v “Native database (NDB) request object” on page 292
v “SQL request” on page 292
v “Data format object” on page 293
v “Parameter marker format object” on page 293
v “Data object” on page 293

Connection object: This class of object represents an AS/400 database server


module. The connection class is used to control the processing of the AS/400
database server. This class gives the application control over such server attributes

Chapter 3. Express C/C++ APIs 291


as naming convention and sort sequence. Connection objects are independent of
each other. This means that it is possible to have connections to multiple AS/400s
or multiple connections to the same AS/400. Each connection could have a unique
set of server attributes.

All functional requests must be processed by a server. Therefore, an object of this


class must be created before an application can created objects of other classes.
When objects of other classes are created, the handle that represents a connection
object is used to identify which connection (database server) will be used to service
any functional requests for that object. This means that the server must be started
(using the cwbDB_StartServer call) before the function can be performed.

Catalog request object: This class of object is used to retrieve information about
database and other SQL objects (SQL packages) from the AS/400. Information that
pertains to the following is available through the catalog request:
Fields
Files
Foreign keys
Indices
Libraries
Members
Primary keys
Relational databases (RDBs)
Record formats
SQL packages
Statements that are stored in SQL packages
Special columns

By using the catalog request, an application can control both the type of
information that is to be returned and the objects for which the information is to
be returned. For example, you can use a catalog request to return the name and
description of all files whose names start with the letter Q in the QIWS library.

See “Catalog request APIs” on page 294 for more information.

Native database (NDB) request object: This class of object is used to manipulate
database file objects on the AS/400. This includes member manipulation (add,
clear, remove) as well as creating and duplicating database files. In addition, by
using NDB requests in association with SQL requests, an application can access
data in members other than the first member of a file using SQL as the access
method.

See “Native Database (NDB) request APIs” on page 294 for more information.

SQL request: This class of object is used to request SQL operations to be


performed on the AS/400.

The SQL request object allows an application to set various parameters that
control the processing of SQL statements on the AS/400 system. Among these
parameters are the library and SQL package name that allows the application to
use ″extended dynamic″ SQL. When extended dynamic SQL is used, SQL
statements only need to be prepared once. The prepared statement is stored in the
specified package and can be reused at a later time.

292 Client Access Express Programming


See “SQL request APIs” on page 294 for more information.

Data format object: This class of object describes data that is contained in a result
set (for example, the result of a select statement or the result of a catalog request).

The data format contains a description for each item in the result set. That
description includes: data type, data length, precision, scale, CCSID, and column
name.

Since NDB requests do not return data, this class is not used in conjunction with
NDB requests.

See “Objects that process data on the PC or AS/400” on page 295 for more
information.

Parameter marker format object: This class of objects describes data that
corresponds to parameter markers that are contained in SQL statements.

The parameter marker format contains a description for each parameter marker in
a prepared SQL statement. That description includes: data type, data length,
precision, scale, and CCSID.

See “Objects that process data on the PC or AS/400” on page 295 for more
information.

Data object: This class is used to return result data to the calling application.
Using a data object removes the responsibility from the calling application to
create buffers large enough to contain result data. The data object itself manages
how much storage is needed to contain the data.

See “Objects that process data on the PC or AS/400” on page 295 for more
information.

Typical use of Express database APIs


A connection object is required in order to perform any functional requests with
Express database APIs. You first must create a connection handle. Once this is
done, that handle can be used to override the default set of attributes of the server
job such as naming convention (LIB/FILE vs. USER.TABLE), or to override the
default sort sequence (by using the cwbDB_SetNLSS API). The server job then can
be started by using the cwbDB_StartServer API.

Once the connection is created and the server is started, requests and other related
objects can be created and processed. The AS/400 will not return any data until it
is requested (by using one of the cwbDB_Return* APIs—see “cwbDB_ReturnData”
on page 398). This, along with the ability to store parameters for a request on the
AS/400, allows an application to perform processing in an asynchronous manner.

When an application stores parameters for a request on the AS/400, AS/400


storage is allocated to contain result information for any operations that are
performed on that request. This result information is saved until another operation
is performed for that request. As a result, an application can create any number of
requests and store the parameters for those requests. Operations that take longer to
complete (like creating SQL collections) can be requested, and the application can
continue its work on the PC, while the AS/400 is processing the request. When the
application is ready to check the results of the operations, it then can request
whatever information is appropriate for the request (SQLCA, host error

Chapter 3. Express C/C++ APIs 293


information, data, and so on). Link to the following topics for descriptions of the
three types of requests and a list of their corresponding APIs:
v “Catalog request APIs”
v “Native Database (NDB) request APIs”
v “SQL request APIs”

Catalog request APIs: The catalog request APIs consist of a group of APIs that
allow an application to specify what object for which information is being
requested. For example, if the application needs information that pertains to
members of a database file, the following APIs likely would be called:
cwbDB_SetLibraryName
This qualifies the library for which the information will be retrieved. This may
contain wildcard values (QIWS*) or special values such as *LIBL, *USRLIBL,
and so on.
cwbDB_SetFileName
This qualifies the file for which the member information will be retrieved. This
may contain wildcard characters.
cwbDB_SetMemberName*
This is optional and may contain wild-card characters.
cwbDB_ReturnData
This is required for data to be sent to the PC from the AS/400. If this API is
not used, the data will be kept on the AS/400 until it is requested, or until the
next operation is performed.
cwbDB_RetrieveMemberInformation
One of the parameters on this API is a bitmap that indicates what information
is to be returned. The following information can be returned for members:
v Library name
v File name
v Member name
v Member description

Once the information has been retrieved, the application will use the data format
and the data object to process the data that has been retrieved. See “Objects that
process data on the PC or AS/400” on page 295 for more information.

Native Database (NDB) request APIs: Native database (NDB) requests are used
to manipulate database objects on the AS/400. For example, the override database
function can be used in conjuction with an SQL request to allow SQL to access
members other than the first member in a file. The following NDB APIs would be
used to accomplish this:
cwbDB_SetFileName
This is the file (table) that will be used in the SQL statement.
cwbDB_SetOverrideInformation*
This will indicate the file and member to be accessed.
cwbDB_ReturnHostErrorInfo
Since no data is available to be returned, this will provide status as to the
result of the override request.
cwbDB_OverrideFile
This actually does the override request.

SQL request APIs: SQL requests are used to perform SQL operations on the
AS/400. There are some operations for which a combined function API is

294 Client Access Express Programming


provided. For example, an application could call APIs to perform the following
functions: prepare a statement, describe the result set, open a cursor by using the
prepared statement, and fetch data from that cursor. Using the combined function
API, the application would make one API call to perform all four of those
functions (cwbDB_PrepareDescribeOpenFetch). The following APIs would be used
to open a cursor and retrieve some data:
cwbDB_SetCursorName
This is the name of the cursor that will be used when fetching the data.
cwbDB_SetStatementName
This is the name that is used when referring to prepared SQL statements.
cwbDB_SetStatementText
This is the actual SQL statement that is to be prepared.
cwbDB_ReturnData
No data is returned unless it is requested by the application. For this example,
we will request the data.
cwbDB_PrepareDescribeOpenFetch
This will process the statement and return data to the PC.

Objects that process data on the PC or AS/400


There are three classes that are used by the application for processing data that is
returned to the PC or for providing data to be processed by the AS/400. These
classes are:
Data format
The data format is used to describe data that is to be returned to the PC. It
contains a description of each of the columns of data in the result set. This
description includes the column name, length, and type. If the type of data
is character data, the Coded Character Set Identifier (CCSID) is included.
For numeric data, the description includes precision and scale. This
information is used by the application to parse the data that is returned to
the PC.
Parameter marker format
Parameter marker formats are similar to the data formats in that they
describe data that is contained in a buffer. The difference is that the
parameter marker format is used to describe data that the application is
using as input to an SQL request. The information in the parameter marker
format is used by Database APIs to parse through a buffer that contains
data that is to be used to provide data values to an SQL statement.
Data object
The data object is a very simple object. It provides a pointer and length to
data that is returned to the PC. As mentioned previously, using the data
object provides a mechanism for the application to receive data without
having to allocate storage of sufficient size to contain the data. That storage
management is contained within the data object.

Code page support in Windows


In Windows, data can be manipulated in ASCII (OEM) or ANSI code pages. The
default behavior of these Express database APIs is to use the ASCII code page. If
you want your program to use the ANSI code page instead, use the
cwbNL_GetANSICodePage API to retrieve the ANSI code page, convert the code
page to a CCSID with “cwbNL_CodePageToCCSID” on page 567, and then
usecwbDB_SetClientDataCCSID and cwbDB_SetClientHostErrorCCSID to change
the behavior of these APIs.

Chapter 3. Express C/C++ APIs 295


Note: Unicode is not supported by these APIs.

Express database APIs listing


The following Express database APIs are listed alphabetically, by function:

Function Express database APIs


Database server attributes cwbDB_ApplyAttributes
cwbDB_CreateConnectionHandle
cwbDB_CreateConnectionHandleEx
cwbDB_DeleteConnectionHandle
cwbDB_GetCommitmentControl
cwbDB_GetDateFormat
cwbDB_GetDateSeparator
cwbDB_GetDecimalSeparator
cwbDB_GetIgnoreDecimalDataError
cwbDB_GetNamingConvention
cwbDB_GetServerFunctionalLevel
cwbDB_GetTimeFormat
cwbDB_GetTimeSeparator
cwbDB_SetCommitmentControl
cwbDB_SetDateFormat
cwbDB_SetDateSeparator
cwbDB_SetDecimalSeparator
cwbDB_SetIgnoreDecimalDataError
cwbDB_SetNLSS
cwbDB_SetNamingConvention
cwbDB_SetTimeFormat
cwbDB_SetTimeSeparator
cwbDB_StartServer
cwbDB_StartServerDetailed
cwbDB_StopServer

296 Client Access Express Programming


Function Express database APIs
Catalog request cwbDB_CreateCatalogRequestHandle
cwbDB_DeleteCatalogRequestHandle
cwbDB_RetrieveFieldInformation
cwbDB_RetrieveFileInformation
cwbDB_RetrieveForeignKeyInformation
cwbDB_RetrieveIndexInformation
cwbDB_RetrieveLibraryInformation
cwbDB_RetrieveMemberInformation
cwbDB_RetrievePackageStatementInformation
cwbDB_RetrievePrimaryKeyInformation
cwbDB_RetrieveRDBInformation
cwbDB_RetrieveRecordFormatInformation
cwbDB_RetrieveSpecialColumnInformation
cwbDB_RetrieveSQLPackageInformation
cwbDB_SetFieldName
cwbDB_SetFileAttributes
cwbDB_SetFileInfoOrdering
cwbDB_SetFileType
cwbDB_SetForeignKeyFileName
cwbDB_SetForeignKeyLibName
cwbDB_SetFormatName
cwbDB_SetIndexType
cwbDB_SetLongFileName
cwbDB_SetMemberName
cwbDB_SetNullable
cwbDB_SetPackageName
cwbDB_SetPrimaryKeyFileName
cwbDB_SetPrimaryKeyLibName
cwbDB_SetRDBName
cwbDB_SetStatementType
Native database (NDB) request cwbDB_AddLibraryToList
cwbDB_AddMember
cwbDB_ClearMember
cwbDB_CreateDuplicateFile
cwbDB_CreateNDBRequestHandle
cwbDB_CreateSourcePhysicalFile
cwbDB_DeleteFile
cwbDB_DeleteNDBRequestHandle
cwbDB_OverrideFile
cwbDB_RemoveMember
cwbDB_RemoveOverride
cwbDB_SetAddLibraryName
cwbDB_SetAddLibraryPosition
cwbDB_SetAuthority
cwbDB_SetBaseFile
cwbDB_SetFileText
cwbDB_SetMaximumMembers
cwbDB_SetMemberText
cwbDB_SetOverrideInformation
cwbDB_SetRecordLength

Chapter 3. Express C/C++ APIs 297


Function Express database APIs
SQL request cwbDB_ClearPackage
cwbDB_Close
cwbDB_Commit
cwbDB_Connect
cwbDB_CreatePackage
cwbDB_CreateSQLRequestHandle
cwbDB_DeletePackage
cwbDB_DeleteSQLRequestHandle
cwbDB_Describe
cwbDB_DescribeParameterMarkers
cwbDB_DynamicStreamFetch
cwbDB_EndStreamFetch
cwbDB_Execute
cwbDB_ExecuteImmediate
cwbDB_ExtendedDynamicStreamFetch
cwbDB_Fetch
cwbDB_MoreStreamData
cwbDB_Open
cwbDB_OpenDescribeFetch
cwbDB_Prepare
cwbDB_PrepareDescribe
cwbDB_PrepareDescribeOpenFetch
cwbDB_ReturnParameterMarkerFormat
cwbDB_ReturnSQLCA
cwbDB_Rollback
cwbDB_SetBlockCount
cwbDB_SetCursorName
cwbDB_SetDescribeOption
cwbDB_SetFetchScrollOptions
cwbDB_SetHoldIndicator
cwbDB_SetParameterMarkerBlock
cwbDB_SetParameterMarkers
cwbDB_SetPrepareOption
cwbDB_SetScrollableCursor
cwbDB_SetStatementName
cwbDB_SetStatementText
cwbDB_SetStreamFetchSyncCount
Multiple requests types cwbDB_GetData - Catalog, NDB, SQL
cwbDB_ReturnData - Catalog, NDB, SQL
cwbDB_ReturnDataFormat - Catalog, SQL
cwbDB_ReturnHostErrorInfo - Catalog, NDB, SQL
cwbDB_SetClientDataCCSID - Catalog, NDB, SQL
cwbDB_SetClientHostErrorCCSID - Catalog, NDB, SQL
cwbDB_SetClientInputCCSID - Catalog, NDB, SQL
cwbDB_SetFileName - Catalog, NDB
cwbDB_SetLibraryName - Catalog, NDB, SQL
cwbDB_StoreRequestParameters - Catalog, NDB, SQL

298 Client Access Express Programming


Function Express database APIs
Data-description manipulation cwbDB_CreateDataFormatHandle
cwbDB_CreateDataHandle
cwbDB_CreateParameterMarkerFormatHandle
cwbDB_DeleteDataFormatHandle
cwbDB_DeleteDataHandle
cwbDB_DeleteParameterMarkerFormatHandle
cwbDB_GetColumnCCSID
cwbDB_GetColumnCount
cwbDB_GetColumnLength
cwbDB_GetColumnName
cwbDB_GetColumnPrecision
cwbDB_GetColumnScale
cwbDB_GetColumnType
cwbDB_GetConversionIndicator
cwbDB_GetDataLength
cwbDB_GetDataPointer
cwbDB_GetParameterCCSID
cwbDB_GetParameterCount
cwbDB_GetParameterLength
cwbDB_GetParameterPrecision
cwbDB_GetParameterScale
cwbDB_GetParameterType
cwbDB_GetRowSize
cwbDB_GetSizeOfInputParameters
cwbDB_GetSizeOfOutputParameters
cwbDB_IsParameterInput
cwbDB_IsParameterInputOutput
cwbDB_SetClientColumnToNumeric
cwbDB_SetClientColumnToString
cwbDB_SetClientParameterToNumeric
cwbDB_SetClientParameterToString
cwbDB_SetConversionIndicator
cwbDB_SetConvert65535

Chapter 3. Express C/C++ APIs 299


cwbDB_AddLibraryToList:

Purpose: Add a library to the AS/400 library list.

Syntax:

unsigned int CWB_ENTRY cwbDB_AddLibraryToList(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The
cwbDB_AddLibraryToList API may be called after setting the position in the
library list at which the library is to be added using the
cwbDB_SetAddLibraryPosition API. The cwbDB_AddLibraryToList API should
be called after setting the library name in the request via the
cwbDB_SetAddLibraryName API. This API will result in a request datastream
flowing to the AS/400 server and, if requested, a response to the request flowing
back to the client. A call to cwbDB_ReturnHostErrorInfo is needed in order
determine the success of the operation for this API. Calling
cwbDB_ReturnHostErrorInfo prior to calling this API will result in a synchronous
operation (the application will not get control back until the result is returned to
the PC from the AS/400).

300 Client Access Express Programming


cwbDB_AddMember:

Purpose: Add a member to a file on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_AddMember(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_AddMember
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 301


cwbDB_ApplyAttributes:

Purpose: Activates the changes that were made to server attributes by previous
calls - (naming convention, commitment control, etc.) Use this to change server
attributes after the server has been started.

Syntax:

unsigned int CWB_ENTRY cwbDB_ApplyAttributes(


cwbDB_ConnectionHandle connection,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: This API is only needed if the server attributes are changed after the server
has been started (cwbDB_StartServer).

302 Client Access Express Programming


cwbDB_ClearMember:

Purpose: Clear data from a member in an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_ClearMember(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_ClearMember
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 303


cwbDB_ClearPackage:

Purpose: Clear all statements from an SQL package.

Syntax:

unsigned int CWB_ENTRY cwbDB_ClearPackage(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The
cwbDB_ClearPackage API should be called after setting the desired values in the
request. This API will result in a request datastream flowing to the AS/400 server
and if requested, a response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

304 Client Access Express Programming


cwbDB_Close:

Purpose: Close an open cursor.

Syntax:

unsigned int CWB_ENTRY cwbDB_Close(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Close API
should be called after setting the desired values in the request. This API will result
in a request datastream flowing to the AS/400 server and if requested, a response
to the request flowing back to the client.

Chapter 3. Express C/C++ APIs 305


cwbDB_Commit:

Purpose: Perform a commit operation to commit a unit of work.

Syntax:

unsigned int CWB_ENTRY cwbDB_Commit(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Commit
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

306 Client Access Express Programming


cwbDB_Connect:

Purpose: Perform a Distributed Relational Database Architecture™ (DRDA)


connection management function. This API is used to establish and switch between
connections to other Relational Databases.

Syntax:

unsigned int CWB_ENTRY cwbDB_Connect(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Connect
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to either cwbDB_ReturnHostErrorInfo or cwbDB_ReturnSQLCA prior to


this call will allow an application to determine the success of the API operation.

Chapter 3. Express C/C++ APIs 307


cwbDB_CreateCatalogRequestHandle:

Purpose: Allocate a handle to a database request. This handle will be used on


subsequent API calls that request object information.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateCatalogRequestHandle(


cwbDB_ConnectionHandle connection,
cwbDB_RequestHandle *request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to the connection which will be used when servicing the request.
cwbDB_RequestHandle *request - output
Pointer to a cwbDB_RequestHandle where the handle of the Request will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

308 Client Access Express Programming


cwbDB_CreateConnectionHandle:

Purpose: Allocate a handle to an AS/400 database access server.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateConnectionHandle(


char *systemName,
cwbDB_ConnectionHandle *connection,
cwbSV_ErrHandle errorHandle);

Parameters:
char *systemName - input
Pointer to an ASCIIZ string that contains the name of the system from which
database requests will be serviced.
cwbDB_ConnectionHandle *connection - output
Pointer to a cwbDB_ConnectionHandle where the handle of the connection
will be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: None

Chapter 3. Express C/C++ APIs 309


cwbDB_CreateConnectionHandleEx:

Purpose: Allocate a handle to an AS/400 database access server.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateConnectionHandleEx(


cwbCO_SysHandle sysHandle,
cwbDB_ConnectionHandle* connection,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbCO_SysHandle sysHandle - input
Handle to a system object.
cwbDB_ConnectionHandle *connection - output
Pointer to a cwbDB_ConnectionHandle where the handle of the connection
will be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: This function requires that you previously have issued


cwbCO_CreateSystem.

310 Client Access Express Programming


cwbDB_CreateDataFormatHandle:

Purpose: Allocate a handle to a description of SQL data.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateDataFormatHandle(


cwbDB_ConnectionHandle connection,
cwbDB_FormatHandle *format,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
cwbDB_FormatHandle *format - output
Pointer to a cwbDB_FormatHandle where the handle of the data format will
be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 311


cwbDB_CreateDataHandle:

Purpose: Allocate a handle to a data object.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateDataHandle(


cwbDB_DataHandle *dataHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_DataHandle *dataHandle - output
Pointer to a cwbDB_DataHandle where the handle of a data object will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: The cwbDB_CreateDataHandle is used prior to requesting various pieces


of information to be returned to an application. In general, if the information being
requested has a varying length, the information will be returned using a data
handle. This mechanism moves the responsibility of allocating the memory that is
to contain the data from the calling application to the API. When finished with the
data handle, the cwbDB_DeleteDataHandle API should be called to free any
resources that are associated with the data handle.

312 Client Access Express Programming


cwbDB_CreateDuplicateFile:

Purpose: Create a file based on existing file.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateDuplicateFile(


cwbDB_RequestHandle request,
cwb_Boolean copyDataIndicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwb_Boolean copyDataIndicator - input
Boolean value that indicates whether the data from the base file is to be copied
into the duplicate file.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use one of the defined values for the copyDataIndicator:


CWBDB_DO_NOT_COPY_DATA
CWBDB_COPY_DATA

This API is not valid for List or SQL requests. The cwbDB_CreateDuplicateFile
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 313


cwbDB_CreateNDBRequestHandle:

Purpose: Allocate a handle to a database request. This handle will be used on


subsequent API calls that request operations to be performed with AS/400 file
objects.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateNDBRequestHandle(


cwbDB_ConnectionHandle connection,
cwbDB_RequestHandle *request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to the connection which will be used when servicing the request.
cwbDB_RequestHandle *request - output
Pointer to a cwbDB_RequestHandle where the handle of the Request will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

314 Client Access Express Programming


cwbDB_CreatePackage:

Purpose: Create an SQL package for preparing statements.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreatePackage(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandleAPI. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The
cwbDB_CreatePackage API should be called after setting the desired values in the
request. This API will result in a request datastream flowing to the AS/400 server
and if requested, a response to the request flowing back to the client.

Chapter 3. Express C/C++ APIs 315


cwbDB_CreateParameterMarkerFormatHandle:

Purpose: Allocate a handle to a description of SQL parameter marker data.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateParameterMarkerFormatHandle(


cwbDB_ConnectionHandle connection,
cwbDB_FormatHandle *format,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
cwbDB_FormatHandle *format - output
Pointer to a cwbDB_FormatHandle where the handle of the parameter marker
format will be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

316 Client Access Express Programming


cwbDB_CreateSourcePhysicalFile:

Purpose: Create a source file on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateSourcePhysicalFile(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandleAPI. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The
cwbDB_CreateSourcePhysicalFile API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 317


cwbDB_CreateSQLRequestHandle:

Purpose: Allocate a handle to a database request. This handle will be used on


subsequent API calls that request SQL services.

Syntax:

unsigned int CWB_ENTRY cwbDB_CreateSQLRequestHandle(


cwbDB_ConnectionHandle connection,
cwbDB_RequestHandle *request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to the connection which will be used when servicing the request.
cwbDB_RequestHandle *request - output
Pointer to a cwbDB_RequestHandle where the handle of the Request will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

318 Client Access Express Programming


cwbDB_DeleteCatalogRequestHandle:

Purpose: Deallocates a request handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteCatalogRequestHandle(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 319


cwbDB_DeleteConnectionHandle:

Purpose: Deallocates the handle to the AS/400 server.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteConnectionHandle(


cwbDB_ConnectionHandle connection,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

320 Client Access Express Programming


cwbDB_DeleteDataFormatHandle:

Purpose: Deallocates a format handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteDataFormatHandle(


cwbDB_FormatHandle format,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 321


cwbDB_DeleteDataHandle:

Purpose: Deallocates a data handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteDataHandle(


cwbDB_DataHandle dataHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_DataHandle dataHandle - input
Handle to a data object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

322 Client Access Express Programming


cwbDB_DeleteFile:

Purpose: Delete a file from an AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteFile(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_DeleteFile API
should be called after setting the desired values in the request. This API will result
in a request datastream flowing to the AS/400 server and if requested, a response
to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 323


cwbDB_DeleteNDBRequestHandle:

Purpose: Deallocates a request handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteNDBRequestHandle(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

324 Client Access Express Programming


cwbDB_DeletePackage:

Purpose: Delete an SQL package.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeletePackage(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The
cwbDB_DeletePackage API should be called after setting the desired values in the
request. This API will result in a request datastream flowing to the AS/400 server
and if requested, a response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 325


cwbDB_DeleteParameterMarkerFormatHandle:

Purpose: Deallocates a format handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteParameterMarkerFormatHandle(


cwbDB_FormatHandle format,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a parameter marker format object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

326 Client Access Express Programming


cwbDB_DeleteSQLRequestHandle:

Purpose: Deallocates a request handle.

Syntax:

unsigned int CWB_ENTRY cwbDB_DeleteSQLRequestHandle(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 327


cwbDB_Describe:

Purpose: Describes a prepared statement. If there is no result set, no column


descriptions will be returned.

Syntax:

unsigned int CWB_ENTRY cwbDB_Describe(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Describe
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnDataFormat is needed in order get the description of the


data. Calling cwbDB_ReturnDataFormat prior to calling this API will result in a
synchronous operation (the application will not get control back until the result is
returned to the PC from the AS/400).

328 Client Access Express Programming


cwbDB_DescribeParameterMarkers:

Purpose: Describes the parameter markers for a prepared statement. If the


statement is an ″UPDATE WHERE CURRENT OF CURSOR″, the cursor must be
open before the describe parameter markers can be performed.

Syntax:

unsigned int CWB_ENTRY cwbDB_DescribeParameterMarkers(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Describe
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnParameterMarkerFormat is needed in order get the


description of the parameter markers. Calling
cwbDB_ReturnParameterMarkerFormat prior to calling this API will result in a
synchronous operation (the application will not get control back until the result is
returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 329


cwbDB_DynamicStreamFetch:

Purpose: This API will prepare a select statement, open a cursor and fetch all
resulting data. The row data will be returned to the application in blocks, the size
of which will be optimized for the communication mechanism. To get additional
blocks, use the cwbDB_MoreStreamData API.

Syntax:

unsigned int CWB_ENTRY cwbDB_DynamicStreamFetch(


cwbDB_RequestHandle request,
char *statementText,
cwbDB_DataHandle data,
cwbDB_DataHandle indicators,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *statementText - input
Pointer to an ASCIIZ string containing select text.
cwbDB_DataHandle data - input
Handle to a data object into which the returned data will be placed.
cwbDB_DataHandle indicators - input
Handle to a data object into which the returned data indicators will be placed.
There is one indicator value for each column value of each row of data that is
returned from the AS/400. The indicator will be a negative number if the value
for the column is NULL. If an error occurs while converting the data, a
character ’E’ will be placed in that column’s indicator field.
cwbDB_FormatHandle formatHandle - input
Handle to a data format that contains a description of the returned data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

330 Client Access Express Programming


cwbDB_EndStreamFetch:

Purpose: Cancel the stream fetch operation before all the data has been returned.

Syntax:

unsigned int CWB_ENTRY cwbDB_EndStreamFetch(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 331


cwbDB_Execute:

Purpose: Execute a prepared SQL statement.

Syntax:

unsigned int CWB_ENTRY cwbDB_Execute(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Execute
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

332 Client Access Express Programming


cwbDB_ExecuteImmediate:

Purpose: Prepare and execute an SQL statement.

Syntax:

unsigned int CWB_ENTRY cwbDB_ExecuteImmediate(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The
cwbDB_ExecuteImmediate API should be called after setting the desired values in
the request. This API will result in a request datastream flowing to the AS/400
server and if requested, a response to the request flowing back to the client.

Chapter 3. Express C/C++ APIs 333


cwbDB_ExtendedDynamicStreamFetch:

Purpose: This API will perform a stream fetch (see previous API) for a statement
that is already prepared in an SQL package.

Syntax:

unsigned int CWB_ENTRY cwbDB_ExtendedDynamicStreamFetch(


cwbDB_RequestHandle request,
char *libraryName,
char *packageName,
char *statementName,
cwbDB_DataHandle data,
cwbDB_DataHandle indicators,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *libraryName - input
Pointer to an ASCIIZ string containing library name.
char *packageName - input
Pointer to an ASCIIZ string containing package name.
char *statementName - input
Pointer to an ASCIIZ string containing statement name.
cwbDB_DataHandle data - input
Handle to a data object into which the returned data will be placed.
cwbDB_DataHandle indicators - input
Handle to a data object into which the returned data indicators will be placed.
There is one indicator value for each column value of each row of data that is
returned from the AS/400. The indicator will be a negative number if the value
for the column is NULL. If an error occurs while converting the data, a
character ’E’ will be placed in that column’s indicator field.
cwbDB_FormatHandle formatHandle - input
Handle to a data format that contains a description of the returned data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

334 Client Access Express Programming


cwbDB_Fetch:

Purpose: Fetch a row or block of rows (this is controlled by the


cwbDB_SetBlockCount API) from an open cursor.

Syntax:

unsigned int CWB_ENTRY cwbDB_Fetch(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Fetch API
should be called after setting the desired values in the request. This API will result
in a request datastream flowing to the AS/400 server and if requested, a response
to the request flowing back to the client. Please note that fetched data will not be
returned unless the data is requested (using the cwbDB_ReturnData API).

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 335


cwbDB_GetColumnCCSID:

Purpose: Returns the Coded Character Set Identifier (CCSID) for a specified
column of data.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnCCSID(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long columnPosition,
unsigned short *dataCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long columnPosition - input
Specifies the relative position of the column.
unsigned short *dataCCSID - output
Pointer to a short integer to contain the CCSID for the specified column.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

336 Client Access Express Programming


cwbDB_GetColumnCount:

Purpose: Returns the number of columns of data that are described by the data
format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnCount(


cwbDB_FormatHandle format,
unsigned long *columnCount,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long *columnCount - output
Pointer to an unsined long integer which will contain the column count.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 337


cwbDB_GetColumnLength:

Purpose: Returns the length (in bytes) of the data for a specified column.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnLength(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long columnPosition,
unsigned long *dataLength,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long columnPosition - input
Specifies the relative position of the column.
unsigned long *dataLength - output
Pointer to short integer to contain the data length.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

338 Client Access Express Programming


cwbDB_GetColumnName:

Purpose: Returns the column name (if it exists) for a column of data.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnName(


cwbDB_FormatHandle format,
unsigned long columnPosition,
cwbDB_DataHandle columnHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long columnPosition - input
Specifies the relative position of the column.
cwbDB_DataHandle columnHandle - input
handle to a data object which will contain the column name
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 339


cwbDB_GetColumnPrecision:

Purpose: Returns the precision for a specified column of data.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnPrecision(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long columnPosition,
unsigned short *dataPrecision,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long columnPosition - input
Specifies the relative position of the column.
unsigned short *dataPrecision - output
Pointer to short integer to contain the data precision.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

340 Client Access Express Programming


cwbDB_GetColumnScale:

Purpose: Returns the scale for a specified column of data.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnScale(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long columnPosition,
unsigned short *dataScale,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long columnPosition - input
Specifies the relative position of the column.
unsigned short *dataScale - output
Pointer to short integer to contain the data scale.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

Chapter 3. Express C/C++ APIs 341


cwbDB_GetColumnType:

Purpose: Returns the data type for a specified column of data.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetColumnType(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long columnPosition,
signed short *dataType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long columnPosition - input
Specifies the relative position of the column.
signed short *dataType - output
Short integer which will contain the data type.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

If the system information is requested, the type returned is the SQL type. If the
local information is requested, see the defined values:
CWBDB_PCNOCONVERSION
CWBDB_PCSTRING
CWBDB_PCLONG
CWBDB_PCSHORT
CWBDB_PCFLOAT
CWBDB_PCDOUBLE
CWBDB_PCPACKED
CWBDB_PCZONED
CWBDB_PCINVALIDTYPE
CWBDB_PCVARSTRING
CWBDB_PCGRAPHIC

342 Client Access Express Programming


CWBDB_PCVARGRAPHIC

Chapter 3. Express C/C++ APIs 343


cwbDB_GetCommitmentControl:

Purpose: Get the current commitment control level.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetCommitmentControl(


cwbDB_ConnectionHandle connection,
unsigned short *commitmentLevel,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *commitmentLevel - output
Pointer to an unsigned short where the current value will be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
CWBDB_NONE
CWBDB_CURSOR_STABILITY
CWBDB_CHANGE
CWBDB_ALL

344 Client Access Express Programming


cwbDB_GetConversionIndicator:

Purpose: Gets the indicator that says whether data is to be converted between the
client and host format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetConversionIndicator(


cwbDB_FormatHandle format,
cwb_Boolean *conversionIndicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
cwb_Boolean *conversionIndicator - output
CWB_FALSE indicates that no conversion CWB_TRUE indicates conversion
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 345


cwbDB_GetData:

Purpose: Get the requested data from the host. This data can include the selected
data, data format, host return code, and SQLCA.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetData(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_GetData API should be called after requesting the desired
data (using the cwbDB_Return* APIs). This API will result in a request datastream
flowing to the AS/400 server and if requested, a response to the request flowing
back to the client.

346 Client Access Express Programming


cwbDB_GetDataLength:

Purpose: Returns the length of the data contained in a data object.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetDataLength(


cwbDB_DataHandle dataHandle,
unsigned long *dataLength,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_DataHandle dataHandle - input
Handle to a data object.
unsigned long *dataLength - output
Unsigned long integer to contain the length of the data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 347


cwbDB_GetDataPointer:

Purpose: Returns the address of the data in a data object.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetDataPointer(


cwbDB_DataHandle dataHandle,
char **data,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_DataHandle dataHandle - input
Handle to a data object.
char **data - output
Pointer to pointer to the data buffer.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

348 Client Access Express Programming


cwbDB_GetDateFormat:

Purpose: Get the current date format. See cwbDB_SetDateFormat for additional
information about date formats.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetDateFormat(


cwbDB_ConnectionHandle connection,
unsigned short *dateFormat,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short *dateFormat - output
Pointer to an unsigned short where the current date format value will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
Format name Date format constant Value
--------------- --------------------- ------
Julian CWBDB_DATE_FMT_JUL 0
month day year CWBDB_DATE_FMT_MDY 1
day month year CWBDB_DATE_FMT_DMY 2
year month day CWBDB_DATE_FMT_YMD 3
USA CWBDB_DATE_FMT_USA 4
ISO CWBDB_DATE_FMT_ISO 5
IBM Japan CWBDB_DATE_FMT_JIS 6
IBM Europe CWBDB_DATE_FMT_EUR 7

Chapter 3. Express C/C++ APIs 349


cwbDB_GetDateSeparator:

Purpose: Get the current date separator. See cwbDB_SetDateSeparator for


additional information about date separators.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetDateSeparator(


cwbDB_ConnectionHandle connection,
unsigned short *dateSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *dateSeparator - output
Pointer to an unsigned short where the current date data separator value will
be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
Date separator Date separator constant
--------------- ------------------------
Slash CWBDB_DATE_SEP_SLASH
Dash CWBDB_DATE_SEP_DASH
Period CWBDB_DATE_SEP_PERIOD
Comma CWBDB_DATE_SEP_COMMA
Blank CWBDB_DATE_SEP_BLANK

350 Client Access Express Programming


cwbDB_GetDecimalSeparator:

Purpose: Get the current decimal separator. See cwbDB_SetDecimalSeparator for


additional information about decimal separators.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetDecimalSeparator(


cwbDB_ConnectionHandle connection,
unsigned short *decimalSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *decimalSeparator - output
Pointer to an unsigned short where the current decimal separator value will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
Time separator Time separator constant
--------------- ------------------------
Period CWBDB_DECIMAL_SEP_PERIOD
Comma CWBDB_DECIMAL_SEP_COMMA

Chapter 3. Express C/C++ APIs 351


cwbDB_GetIgnoreDecimalDataError:

Purpose: Get the current setting for the decimal data error indicator.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetIgnoreDecimalDataError(


cwbDB_ConnectionHandle connection,
unsigned short *ignoreDecimalError,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *ignoreDecimalError - output
Pointer to an unsigned short where the current value will be returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value returned will be one of the following:
CWBDB_IGNORE_ERROR
CWBDB_CORRECT_ERROR

352 Client Access Express Programming


cwbDB_GetNamingConvention:

Purpose: Get the naming convention (SQL or native AS/400) that is in effect for
the specified connection.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetNamingConvention(


cwbDB_ConnectionHandle connection,
unsigned short *namingConvention,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short *namingConvention - output
Pointer to an unsigned short where the current naming convention will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
CWBDB_PERIOD_NAME_CONV
CWBDB_SLASH_NAME_CONV

Chapter 3. Express C/C++ APIs 353


cwbDB_GetParameterCCSID:

Purpose: Returns the Coded Character Set Identifier (CCSID) for a specified
parameter.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterCCSID(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long parameterPosition,
unsigned short *dataCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
unsigned short *dataCCSID - output
Pointer to a short integer to contain the CCSID for the specified parameter.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

354 Client Access Express Programming


cwbDB_GetParameterCount:

Purpose: Returns the number of parameters that are described by the data format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterCount(


cwbDB_FormatHandle format,
unsigned long *parameterCount,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long *parameterCount - output
Pointer to an unsined long integer which will contain the parameter count.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 355


cwbDB_GetParameterLength:

Purpose: Returns the length (in bytes) of the data for a specified parameter.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterLength(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long parameterPosition,
unsigned long *dataLength,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
unsigned long *dataLength - output
Pointer to short integer to contain the data length.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

356 Client Access Express Programming


cwbDB_GetParameterPrecision:

Purpose: Returns the precision for a specified parameter.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterPrecision(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long parameterPosition,
unsigned short *dataPrecision,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
unsigned short *dataPrecision - output
Pointer to short integer to contain the data precision.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

Chapter 3. Express C/C++ APIs 357


cwbDB_GetParameterScale:

Purpose: Returns the scale for a specified parameter.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterScale(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long parameterPosition,
unsigned short *dataScale,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
unsigned short *dataScale - output
Pointer to short integer to contain the data scale.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

358 Client Access Express Programming


cwbDB_GetParameterType:

Purpose: Returns the data type for a specified parameter.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetParameterType(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long parameterPosition,
signed short *dataType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
signed short *dataType - output
Short integer which will contain the data type.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

If the system information is requested, the type returned is the SQL type. If the
local information is requested, see the defined values:
CWBDB_PCNOCONVERSION
CWBDB_PCSTRING
CWBDB_PCLONG
CWBDB_PCSHORT
CWBDB_PCFLOAT
CWBDB_PCDOUBLE
CWBDB_PCPACKED
CWBDB_PCZONED
CWBDB_PCINVALIDTYPE
CWBDB_PCVARSTRING
CWBDB_PCGRAPHIC

Chapter 3. Express C/C++ APIs 359


CWBDB_PCVARGRAPHIC

360 Client Access Express Programming


cwbDB_GetRowSize:

Purpose: Returns the size (in bytes) of the data described by the data format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetRowSize(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long *rowSize,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long *rowSize - output
Pointer to an unsigned long integer which will contain the row size.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

Chapter 3. Express C/C++ APIs 361


cwbDB_GetServerFunctionalLevel:

Purpose: Get the current server functional level.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetServerFunctionalLevel(


cwbDB_ConnectionHandle connection,
char *serverFunctionalLevel,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
char * serverFunctionalLevel - output
Pointer to buffer 11 characters long to receive the server’s functional level.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data.

362 Client Access Express Programming


cwbDB_GetSizeOfInputParameters:

Purpose: Returns the size (in bytes) of the input data described by parameter
marker format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetSizeOfInputParameters(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long *inputSize,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a parameter marker format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long *inputSize - output
Pointer to an unsigned long integer which will contain the row size.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

Chapter 3. Express C/C++ APIs 363


cwbDB_GetSizeOfOutputParameters:

Purpose: Returns the size (in bytes) of the output data described by parameter
marker format.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetSizeOfOutputParameters(


cwbDB_FormatHandle format,
unsigned long location,
unsigned long *inputSize,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a parameter marker format object.
unsigned long location - input
Indicates whether the system or local information is to be returned.
unsigned long *outputSize - output
Pointer to an unsigned long integer which will contain the row size.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandleAPI. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the location parameter, use one of the defined values:
CWBDB_SYSTEM
CWBDB_LOCAL

364 Client Access Express Programming


cwbDB_GetTimeFormat:

Purpose: Get the current time format. See cwbDB_SetTimeFormat for additional
information about time formats.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetTimeFormat(


cwbDB_ConnectionHandle connection,
unsigned short *timeFormat,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *timeFormat - output
Pointer to an unsigned short where the current time format value will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
Format name Time format constant
--------------- -----------------------
Hours minutes seconds CWBDB_TIME_FMT_HMS
USA CWBDB_TIME_FMT_USA
ISO CWBDB_TIME_FMT_ISO
IBM Europe CWBDB_TIME_FMT_EUR
IBM Japan CWBDB_TIME_FMT_JIS

Chapter 3. Express C/C++ APIs 365


cwbDB_GetTimeSeparator:

Purpose: Get the current time separator. See cwbDB_SetTimeSeparator for


additional information about time separators.

Syntax:

unsigned int CWB_ENTRY cwbDB_GetTimeSeparator(


cwbDB_ConnectionHandle connection,
unsigned short *timeSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short *timeSeparator - output
Pointer to an unsigned short where the current time separator value will be
returned.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: The cwbDB_StartServer API must be called before this API can return
valid data. The value that is returned will be one of the following:
Time separator Time separator constant
--------------- ------------------------
Colon CWBDB_TIME_SEP_COLON
Period CWBDB_TIME_SEP_PERIOD
Comma CWBDB_TIME_SEP_COMMA
Blank CWBDB_TIME_SEP_BLANK

366 Client Access Express Programming


cwbDB_IsParameterInput:

Purpose: Returns a Boolean value indicating whether the parameter is input only.

Syntax:

unsigned int CWB_ENTRY cwbDB_IsParameterInput(


cwbDB_FormatHandle format,
unsigned long parameterPosition,
cwb_Boolean *parameterIsInput,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a parameter marker format object.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
cwb_Boolean *parameterIsInput - output
Pointer to a Boolean indicating if the parameter is input only.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 367


cwbDB_IsParameterInputOutput:

Purpose: Returns a Boolean value indicating whether the parameter is input and
output.

Syntax:

unsigned int CWB_ENTRY cwbDB_IsParameterInputOutput(


cwbDB_FormatHandle format,
unsigned long parameterPosition,
cwb_Boolean *parameterIsInputOutput,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a parameter marker format object.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
cwb_Boolean *parameterIsInputOutput - output
Pointer to a Boolean indicating if the parameter is input and output.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

368 Client Access Express Programming


cwbDB_MoreStreamData:

Purpose: This API will get the next block of stream fetch data.

Syntax:

unsigned int CWB_ENTRY cwbDB_MoreStreamData(


cwbDB_RequestHandle request,
cwbDB_DataHandle data,
cwbDB_DataHandle indicators,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbDB_DataHandle data - input
Handle to a data object into which the returned data will be placed.
cwbDB_DataHandle indicators - input
Handle to a data object into which the returned data indicators will be placed.
There is one indicator value for each column value of each row of data that is
returned from the AS/400. The indicator will be a negative number if the value
for the column is NULL. If an error occurs while converting the data, a
character ’E’ will be placed in that column’s indicator field.
cwbDB_FormatHandle formatHandle - input
Handle to a data format that contains a description of the returned data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 369


cwbDB_Open:

Purpose: Open a cursor.

Syntax:

unsigned int CWB_ENTRY cwbDB_Open(


cwbDB_RequestHandle request,
unsigned char openOptions,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned char openOptions - input
Input value for open options indicator.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the openOptions, use the defined values


CWBDB_READ
CWBDB_WRITE
CWBDB_UPDATE
CWBDB_DELETE
CWBDB_OPEN_ALL - Provided for convenience

This API is not valid for NDB or catalog requests. The cwbDB_Open API should
be called after setting the desired values in the request. This API will result in a
request datastream flowing to the AS/400 server and if requested, a response to
the request flowing back to the client.

370 Client Access Express Programming


cwbDB_OpenDescribeFetch:

Purpose: This API combines the open, describe and fetch operations. This
combined function is valuable when the statement is already prepared (extended
dynamic SQL).

Syntax:

unsigned int CWB_ENTRY cwbDB_OpenDescribeFetch(


cwbDB_RequestHandle request,
unsigned char openOptions,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned char openOptions - input
Input value for open options indicator.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the openOptions, use the defined values:


CWBDB_READ
CWBDB_WRITE
CWBDB_UPDATE
CWBDB_DELETE
CWBDB_OPEN_ALL - Provided for convenience

This API is not valid for NDB or catalog requests. The


cwbDB_OpenDescribeFetch API should be called after setting the desired values
in the request. This API will result in a request datastream flowing to the AS/400
server and if requested, a response to the request flowing back to the client. Please
note that fetched data will not be returned unless the data is requested (using the
cwbDB_ReturnData API).

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 371


cwbDB_OverrideFile:

Purpose: Override database file reference to another file/member.

Syntax:

unsigned int CWB_ENTRY cwbDB_OverrideFile(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_OverRideFile
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

372 Client Access Express Programming


cwbDB_Prepare:

Purpose: Prepares an SQL statement. If an SQL package has been set, this API will
prepare a statement into the package.

Syntax:

unsigned int CWB_ENTRY cwbDB_Prepare(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Prepare
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

Chapter 3. Express C/C++ APIs 373


cwbDB_PrepareDescribe:

Purpose: This API combines the prepare and describe operations. The advantage of
using this API is that the SQL component is called only once.

Syntax:

unsigned int CWB_ENTRY cwbDB_PrepareDescribe(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The
cwbDB_PrepareDescribe API should be called after setting the desired values in
the request. This API will result in a request datastream flowing to the AS/400
server and if requested, a response to the request flowing back to the client.

A call to cwbDB_ReturnDataFormat is needed in order get the description of the


data. Calling cwbDB_ReturnDataFormat prior to calling this API will result in a
synchronous operation (the application will not get control back until the result is
returned to the PC from the AS/400).

374 Client Access Express Programming


cwbDB_PrepareDescribeOpenFetch:

Purpose: This API combines the prepare, describe, open, and fetch operations. By
combining these operations, performance will improve because only one call is
made to the SQL component on the host.

Syntax:

unsigned int CWB_ENTRY cwbDB_PrepareDescribeOpenFetch(


cwbDB_RequestHandle request,
unsigned char openOptions,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned char openOptions - input
Input value for open options indicator.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the openOptions, use the defined values


CWBDB_READ
CWBDB_WRITE
CWBDB_UPDATE
CWBDB_DELETE
CWBDB_OPEN_ALL - Provided for convenience

This API is not valid for NDB or catalog requests. The


cwbDB_PrepareDescribeOpenFetch API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client. Please note that fetched data will not be returned unless the data is
requested (using the cwbDB_ReturnData API).

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 375


cwbDB_RemoveMember:

Purpose: Remove a member from an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RemoveMember(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_RemoveMember
API should be called after setting the desired values in the request. This API will
result in a request datastream flowing to the AS/400 server and if requested, a
response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

376 Client Access Express Programming


cwbDB_RemoveOverride:

Purpose: Remove an override from a file reference.

Syntax:

unsigned int CWB_ENTRY cwbDB_RemoveOverride(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The
cwbDB_RemoveOverRide API should be called after setting the desired values in
the request. This API will result in a request datastream flowing to the AS/400
server and if requested, a response to the request flowing back to the client.

A call to cwbDB_ReturnHostErrorInfo is needed in order determine the success of


the operation for this API. Calling cwbDB_ReturnHostErrorInfo prior to calling
this API will result in a synchronous operation (the application will not get control
back until the result is returned to the PC from the AS/400).

Chapter 3. Express C/C++ APIs 377


cwbDB_RetrieveFieldInformation:

Purpose: Get information about the fields in an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveFieldInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the fields.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values


CWBDB_GET_FLD_LIB
CWBDB_GET_FLD_REMARKS
CWBDB_GET_FLD_FILE
CWBDB_GET_FLD_NAME
CWBDB_GET_FLD_DESC
CWBDB_GET_FLD_DATA_TYPE
CWBDB_GET_FLD_LEN
CWBDB_GET_FLD_NULL
CWBDB_GET_FLD_RADIX
CWBDB_GET_FLD_PREC
CWBDB_GET_FLD_SCALE

rc = cwbDB_RetrieveFieldInformation( requestHandle,

CWBDB_GET_FLD_FILE |

CWBDB_GET_FLD_NAME |

CWBDB_GET_FLD_DATA_TYPE |

CWBDB_GET_FLD_PREC |

CWBDB_GET_FLD_SCALE,

378 Client Access Express Programming


errorHandle);

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveFieldInformation API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 379


cwbDB_RetrieveFileInformation:

Purpose: Get information about files on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveFileInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the files.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_FILE_LIB
CWBDB_GET_FILE_REMARKS
CWBDB_GET_FILE_NAME
CWBDB_GET_FILE_ATTRIB
CWBDB_GET_FILE_DESC
CWBDB_GET_FILE_COL_CNT
CWBDB_GET_FILE_AUTH

rc = cwbDB_RetrieveFileInformation( requestHandle,
CWBDB_GET_FILE_NAME |
CWBDB_GET_FILE_ATTRIB |
CWBDB_GET_FILE_DESC |
CWBDB_GET_FILE_COL_CNT |
CWBDB_GET_FILE_AUTH,
errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveFileInformation API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

380 Client Access Express Programming


A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 381


cwbDB_RetrieveForeignKeyInformation:

Purpose: Get information about foreign keys for an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveForeignKeyInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for foreign keys.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:

Foreign Key Primary Key Information constants


CWBDB_GET_FG_PRKEY_LIB
CWBDB_GET_FG_PRKEY_FILE
CWBDB_GET_FG_PRKEY_COL_ID

Foreign Key Information constants


CWBDB_GET_FG_KEY_LIB
CWBDB_GET_FG_KEY_FILE
CWBDB_GET_FG_KEY_COL_ID
CWBDB_GET_FG_KEY_SEQ
CWBDB_GET_FG_KEY_UPDATE
CWBDB_GET_FG_KEY_DELETE

rc = cwbDB_RetrievePrimaryKeyInformation( requestHandle,
CWBDB_GET_FG_PRKEY_LIB |
CWBDB_GET_FG_PRKEY_FILE |
CWBDB_GET_FG_PRKEY_COL_ID |
CWBDB_GET_FG_KEY_LIB |
CWBDB_GET_FG_KEY_FILE |
CWBDB_GET_FG_KEY_COL_ID |
CWBDB_GET_FG_KEY_SEQ |

382 Client Access Express Programming


CWBDB_GET_FG_KEY_UPDATE |
CWBDB_GET_FG_KEY_DELETE, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveForeignKeyInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 383


cwbDB_RetrieveIndexInformation:

Purpose: Get information about the indices for an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveIndexInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the indices.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_IDX_LIB
CWBDB_GET_IDX_TBL_NAME
CWBDB_GET_IDX_UNIQUE
CWBDB_GET_IDX_IDX_LIB
CWBDB_GET_IDX_IDX_NAME
CWBDB_GET_IDX_COL_CNT
CWBDB_GET_IDX_COL_NAME
CWBDB_GET_IDX_COL_SEQ
CWBDB_GET_IDX_COLLAT

rc = cwbDB_RetrieveIndexInformation( requestHandle,
CWBDB_GET_IDX_TBL_NAME |
CWBDB_GET_IDX_UNIQUE |
CWBDB_GET_IDX_IDX_LIB |
CWBDB_GET_IDX_IDX_NAME |
CWBDB_GET_IDX_COL_CNT, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveIndexInformation API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

384 Client Access Express Programming


A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 385


cwbDB_RetrieveLibraryInformation:

Purpose: Get information about a library or list of libraries.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveLibraryInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the libraries.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_LIBRARY_NAME
CWBDB_GET_LIBRARY_DESC

rc = cwbDB_RetrieveLibraryInformation( requestHandle,
CWBDB_GET_LIBRARY_NAME |
CWBDB_GET_LIBRARY_DESC, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveLibraryInformation API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

386 Client Access Express Programming


cwbDB_RetrieveMemberInformation:

Purpose: Get information about members of an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveMemberInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the members.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_MBR_LIB
CWBDB_GET_MBR_FILE
CWBDB_GET_MBR_NAME
CWBDB_GET_MBR_DESC

rc = cwbDB_RetrieveMemberInformation( requestHandle,
CWBDB_GET_MBR_LIB |
CWBDB_GET_MBR_FILE |
CWBDB_GET_MBR_NAME |
CWBDB_GET_MBR_DESC, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveMemberInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 387


cwbDB_RetrievePackageStatementInformation:

Purpose: Get information about statements stored in an SQL package on the


AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrievePackageStatementInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the SQL
statements.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_SQLSTMT_LIB
CWBDB_GET_SQLSTMT_PKG
CWBDB_GET_SQLSTMT_NAME
CWBDB_GET_SQLSTMT_TYPE
CWBDB_GET_SQLSTMT_TEXT
CWBDB_GET_SQLSTMT_PM_CNT

rc = cwbDB_RetrievePackageStatementInformation( requestHandle,
CWBDB_GET_SQLSTMT_NAME |
CWBDB_GET_SQLSTMT_TYPE |
CWBDB_GET_SQLSTMT_TEXT, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrievePackageStatementInformation API should be called after setting
the desired values in the request. This API will result in a request datastream
flowing to the AS/400 server and if requested, a response to the request flowing
back to the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently

388 Client Access Express Programming


cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 389


cwbDB_RetrievePrimaryKeyInformation:

Purpose: Get information about primary keys for an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrievePrimaryKeyInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for primary keys.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_PR_KEY_LIB
CWBDB_GET_PR_KEY_FILE
CWBDB_GET_PR_KEY_COL_ID
CWBDB_GET_PR_KEY_COL_SEQ

rc = cwbDB_RetrievePrimaryKeyInformation( requestHandle,
CWBDB_GET_PR_KEY_LIB |
CWBDB_GET_PR_KEY_FILE |
CWBDB_GET_PR_KEY_COL_ID |
CWBDB_GET_PR_KEY_COL_SEQ, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrievePrimaryKeyInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

390 Client Access Express Programming


cwbDB_RetrieveRDBInformation:

Purpose: Get information about a relational database on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveRDBInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the relational
database.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_RDB_NAME
CWBDB_GET_RDB_DEVICE
CWBDB_GET_RDB_MODE
CWBDB_GET_RDB_RMTLOC
CWBDB_GET_RDB_LOCLOC
CWBDB_GET_RDB_RMTNET
CWBDB_GET_RDB_TPNAME
CWBDB_GET_RDB_DESC
CWBDB_GET_RDB_TPNDISP
CWBDB_GET_RDB_PGM
CWBDB_GET_RDB_PGMLIB
CWBDB_GET_RDB_PGMLEVEL

rc = cwbDB_RetrieveRDBInformation( requestHandle,
CWBDB_GET_RDB_NAME |
CWBDB_GET_RDB_RMTLOC |
CWBDB_GET_RDB_RMTNET |
CWBDB_GET_RDB_TPNAME |
CWBDB_GET_RDB_DESC, errorHandle );

Chapter 3. Express C/C++ APIs 391


This API is not valid for NDB or SQL requests. The
cwbDB_RetrieveRDBInformation API should be called after setting the desired
values in the request. This API will result in a request datastream flowing to the
AS/400 server and if requested, a response to the request flowing back to the
client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

392 Client Access Express Programming


cwbDB_RetrieveRecordFormatInformation:

Purpose: Get information about the record formats for an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveRecordFormatInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the record
formats.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_FMT_LIB
CWBDB_GET_FMT_FILE
CWBDB_GET_FMT_NAME
CWBDB_GET_FMT_REC_LEN
CWBDB_GET_FMT_DESC

rc = cwbDB_RetrieveRecordFormatInformation( requestHandle,
CWBDB_GET_FMT_LIB |
CWBDB_GET_FMT_FILE |
CWBDB_GET_FMT_NAME |
CWBDB_GET_FMT_REC_LEN |
CWBDB_GET_FMT_DESC, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveRecordFormatInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently

Chapter 3. Express C/C++ APIs 393


cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

394 Client Access Express Programming


cwbDB_RetrieveSpecialColumnInformation:

Purpose: Get information about special columns for an AS/400 file.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveSpecialColumnInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the columns.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_SP_COL_LIB
CWBDB_GET_SP_COL_TABLE
CWBDB_GET_SP_COL_COL_NAME
CWBDB_GET_SP_COL_DATA_TYPE
CWBDB_GET_SP_COL_PRECISION
CWBDB_GET_SP_COL_LENGTH
CWBDB_GET_SP_COL_SCALE

rc = cwbDB_RetrieveSpecialColumnInformation( requestHandle,
CWBDB_GET_SP_COL_LIB |
CWBDB_GET_SP_COL_TABLE |
CWBDB_GET_SP_COL_COL_NAME |
CWBDB_GET_SP_COL_DATA_TYPE |
CWBDB_GET_SP_COL_PRECISION |
CWBDB_GET_SP_COL_LENGTH |
CWBDB_GET_SP_COL_SCALE, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveSpecialColumnInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

Chapter 3. Express C/C++ APIs 395


A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

396 Client Access Express Programming


cwbDB_RetrieveSQLPackageInformation:

Purpose: Get information about an SQL package on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDB_RetrieveSQLPackageInformation(


cwbDB_RequestHandle request,
unsigned long retrieveInformation,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long retrieveInformation - input
Bitmap that indicates what information is to be retrieved for the SQL packages.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: Use the defined values:


CWBDB_GET_SQLPKG_LIB
CWBDB_GET_SQLPKG_NAME
CWBDB_GET_SQLPKG_DESC

rc = cwbDB_RetrieveSQLPackageInformation( requestHandle,
CWBDB_GET_SQLPKG_LIB |
CWBDB_GET_SQLPKG_NAME |
CWBDB_GET_SQLPKG_DESC, errorHandle );

This API is not valid for NDB or SQL requests. The


cwbDB_RetrieveSQLPackageInformation API should be called after setting the
desired values in the request. This API will result in a request datastream flowing
to the AS/400 server and if requested, a response to the request flowing back to
the client.

A call to the cwbDB_ReturnData API is needed prior to calling this API if the
application is to process the data immediately. If the application is to operate
asynchronously, then the call to cwbDB_ReturnData and subsequently
cwbDB_GetData are needed after this API in order to get the data that result from
this API call. Once the data is returned, information in the data format handle is
used to determine how to parse the data.

Chapter 3. Express C/C++ APIs 397


cwbDB_ReturnData:

Purpose: Instructs the API to return the data that is in the result set for the
operation.

Syntax:

unsigned int CWB_ENTRY cwbDB_ReturnData(


cwbDB_RequestHandle request,
cwbDB_DataHandle data,
cwbDB_DataHandle indicators,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbDB_DataHandle data - input
Handle for the data being returned. This address is returned when the data is
received from the AS/400 on completion of a function request.
cwbDB_DataHandle indicators - input
Handle which will be used to return the address of the null value/error
indicators being returned. There is one indicator value for each column value
that is to be returned (for each column of each row) The indicator will be a
negative number if the value for the column is NULL. If an error occurs while
converting the data, a character ’E’ will be placed in that columns indicator
field. This address is returned when the data is received from the AS/400 on
completion of a function request.
cwbDB_FormatHandle formatHandle - input
Handle to a data format that contains a description of the returned data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ReturnData API is used to instruct the AS/400 server to


return the data which results from an operation (either an SQL fetch operation or a
catalog retrieval operation). After calling this API, the next API call for the request
that results in a datastream to flow to the server will result in the requested data
being returned to the application.

398 Client Access Express Programming


cwbDB_ReturnDataFormat:

Purpose: Instructs the API to return the format of the data to be returned.

Syntax:

unsigned int CWB_ENTRY cwbDB_ReturnDataFormat(


cwbDB_RequestHandle request,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbDB_FormatHandle formatHandle - input
Handle to a data format that contains a description of the returned data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ReturnDataFormat API is used to instruct the AS/400 server


to return the data format which describes a set of selected data. After calling this
API, the next API call for the request that results in a datastream to flow to the
server will result in the requested data being returned to the application.

Chapter 3. Express C/C++ APIs 399


cwbDB_ReturnHostErrorInfo:

Purpose: Instructs the API to return host error information when a function is
performed on the host server.

Syntax:

unsigned int CWB_ENTRY cwbDB_ReturnHostErrorInfo(


cwbDB_RequestHandle request,
unsigned short *hostErrorClass,
signed long *hostErrorCode,
cwbDB_DataHandle hostMsgID,
cwbDB_DataHandle firstLevelMessageText,
cwbDB_DataHandle secondLevelMessageText,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short *hostErrorClass - input
Pointer to location where the error class will be returned. This class indicates
which database server module encountered an error.
v 0 - no error
v 1 - SQL functional error
v 2 - SQL parameter error
v 3 - List functional error
v 4 - List parameter error
v 5 - NDB functional error
v 6 - NDB parameter error
v 7 - General server error
v 8 - User exit error
signed long *hostErrorCode - input
Pointer to location where the return code from the server module will be
placed.
cwbDB_DataHandle hostMsgID - input
Handle to a data object that will contain the host message identifier. If this
parameter is set to 0, the host message identifier will not be retrieved.
cwbDB_DataHandle firstLevelMessageText - input
Handle to a data object that will contain the host first level message text. If this
parameter is set to 0, the first level message text will not be retrieved.
cwbDB_DataHandle secondLevelMessageText - input
Handle to a data object that will contain the host second level message text. If
this parameter is set to 0, the second level message text will not be retrieved.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.

400 Client Access Express Programming


CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ReturnHostErrorInfo API is used to instruct the AS/400


server to return the error or diagnostic information pertaining to a functional
request. After calling this API, the next API call for the request that results in a
datastream to flow to the server will result in the requested data being returned to
the application.

Chapter 3. Express C/C++ APIs 401


cwbDB_ReturnParameterMarkerFormat:

Purpose: Instructs the API to return the format of the parameter marker data for
an SQL statement.

Syntax:

unsigned int CWB_ENTRY cwbDB_ReturnParameterMarkerFormat(


cwbDB_RequestHandle request,
cwbDB_FormatHandle formatHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbDB_FormatHandle formatHandle - input
Handle to a parameter marker format that will contain the description of
parameter data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ReturnParameterMarkerFormat API is used to instruct the


AS/400 server to return the format which describes a set parameter markers for a
prepared statement. After calling this API, the next API call for the request that
results in a datastream to flow to the server will result in the requested data being
returned to the application.

402 Client Access Express Programming


cwbDB_ReturnSQLCA:

Purpose: Instructs the API to return the SQL Communication Area (SQLCA).

Syntax:

unsigned int CWB_ENTRY cwbDB_ReturnSQLCA(


cwbDB_RequestHandle request,
cwbDB_SQLCA *sqlca,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
struct cwbDB_SQLCA *sqlca - input
Pointer to a structure that will contain SQLCA returned from the host.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ReturnSQLCA API is used to instruct the AS/400 server to


return the SQL Communication Area (SQLCA). After calling this API, the next API
call for the request that results in a datastream to flow to the server will result in
the requested data being returned to the application.

Chapter 3. Express C/C++ APIs 403


cwbDB_Rollback:

Purpose: Perform a rollback operation.

Syntax:

unsigned int CWB_ENTRY cwbDB_Rollback(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests. The cwbDB_Rollback
API should be called after setting the desired values in the request. This API
results in a request datastream flowing to the AS/400 server, and if requested, a
response to the request flowing back to the client.

404 Client Access Express Programming


cwbDB_SetAddLibraryName:

Purpose: Add a library to the AS/400 library list.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetAddLibraryName(


cwbDB_RequestHandle request,
const char *addLibraryName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
const char *addLibraryName - input
The name of the library to be added to the library list.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_AddLibrary API should be called after calling this API. The
cwbDB_SetAddLibraryPosition API may be called before or after this API is
called, but before cwbDB_AddLibrary is called. This API is not valid for List or
SQL requests.

Chapter 3. Express C/C++ APIs 405


cwbDB_SetAddLibraryPosition:

Purpose: Sets the position at which to add a library to the library list via the
cwbDB_AddLibraryToList API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetAddLibraryPosition(


cwbDB_RequestHandle request,
const unsigned short position,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
const unsigned short position - input
The position in the library list to add the library name set via
cwbDB_SetAddLibraryName. Use one of the following defined constants:
DB_ADD_LIBRARY_TO_FRONT - Add library to front of list
DB_ADD_LIBRARY_TO_END - Add library to end of list
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests. The cwbDB_AddLibrary
API should be called after calling this API.

406 Client Access Express Programming


cwbDB_SetAuthority:

Purpose: Set the public authority for a file that will be created through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetAuthority(


cwbDB_RequestHandle request,
unsigned short authority,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short authority - input
Long integer that indicates the public authority for a newly created file.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid authority value

Usage: Use one of the defined values:


CWBDB_SET_LIBRARY_CREATE_AUTHORITY
CWBDB_SET_ALL_AUTHORITY
CWBDB_SET_CHANGE_AUTHORITY
CWBDB_SET_EXCLUDE_AUTHORITY
CWBDB_SET_USE_AUTHORITY
CWBDB_SET_SAME_AUTHOR

This API is not valid for List or SQL requests.

Chapter 3. Express C/C++ APIs 407


cwbDB_SetBaseFile:

Purpose: Set the name of a base file for creating a new file with the same format
through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetBaseFile(


cwbDB_RequestHandle request,
char *baseLibraryName,
char *baseFileName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *baseLibraryName - input
Pointer to an ASCIIZ string that contains the base library name to be used
when creating a new file.
char *baseFileName - input
Pointer to an ASCIIZ string that contains the base file name to be used when
creating a new file.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is used in preparation for cwbDB_CreateDuplicateFile. This API


is not valid for List or SQL requests.

408 Client Access Express Programming


cwbDB_SetBlockCount:

Purpose: Set the number of rows to be blocked together when fetching data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetBlockCount(


cwbDB_RequestHandle request,
unsigned long blockCount,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long blockCount - input
Input value for block count.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 409


cwbDB_SetClientColumnToNumeric:

Purpose: Sets the information for a column description for string data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientColumnToNumeric(


cwbDB_FormatHandle format,
unsigned long columnPosition,
signed short columnType,
unsigned long columnLength,
unsigned short columnPrecision,
unsigned short columnScale,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long columnPosition - input
Specifies the relative position of the column.
signed short columnType - input
Specifies the numeric type to be used.
unsigned long columnLength - input
Only used if the type is zoned or packed decimal
unsigned short columnPrecision - input
Only used if the type is zoned or packed decimal
unsigned short columnScale - input
Only used if the type is zoned or packed decimal
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the columnType parameter, use one of the defined values:
CWBDB_PCLONG
CWBDB_PCSHORT
CWBDB_PCFLOAT
CWBDB_PCDOUBLE
CWBDB_PCPACKED
CWBDB_PCZONED

410 Client Access Express Programming


cwbDB_SetClientColumnToString:

Purpose: Sets the information for a column description for string data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientColumnToString(


cwbDB_FormatHandle format,
unsigned long columnPosition,
signed short columnType,
unsigned long columnLength,
unsigned short columnCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long columnPosition - input
Specifies the relative position of the column.
signed short columnType - input
Specifies the string type to be used.
unsigned long columnLength - input
Specifies the column length to be used.
unsigned short columnCCSID - input
Specifies the column CCSID (Coded Character Set Identifier) to be used.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the columnType parameter, use one of the defined values:
CWBDB_PCSTRING
CWBDB_PCVARSTRING
CWBDB_PCGRAPHIC
CWBDB_PCVARGRAPHIC

Chapter 3. Express C/C++ APIs 411


cwbDB_SetClientDataCCSID:

Purpose: Sets the CCSID (Coded Character Set ID) for the client. The new CCSID
value will be used when converting EBCDIC data from the AS/400. Use
cwbDB_SetClientHostErrorCCSID to set the CCSID used when converting host
error information.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientDataCCSID(


cwbDB_ConnectionHandle connection,
unsigned short clientDataCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short clientCCSID - input
Specifies the CCSID (Coded Character Set Identifier to be used.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be called any time after a connection handle has been
created.

412 Client Access Express Programming


cwbDB_SetClientInputCCSID:

Purpose: Sets the CCSID (Coded Character Set Identifier) for data being input such
as file names, SQL statement text, and so on. The new CCSID value will be used
when converting EBCDIC data from the AS/400. Use
cwbDB_SetClientHostErrorCCSID to set the CCSID used when converting host
error information.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientInputCCSID(


cwbDB_ConnectionHandle connection,
unsigned short inputCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short inputCCSID - input
Specifies the CCSID to be used.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be called any time after a connection handle has been
created.

Chapter 3. Express C/C++ APIs 413


cwbDB_SetClientHostErrorCCSID:

Purpose: Sets the CCSID (Coded Character Set ID) for the client. The new CCSID
value will be used when converting EBCDIC server messages. Use
cwbDB_SetClientDataCCSID to change the CCSID used for converting data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientHostErrorCCSID(


cwbDB_ConnectionHandle connection,
unsigned short clientHostErrorCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short clientHostErrorCCSID - input
Specifies the CCSID (Coded Character Set Identifier to be used.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be called any time after a connection handle has been
created.

414 Client Access Express Programming


cwbDB_SetClientParameterToNumeric:

Purpose: Sets the information for a parameter description for string data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientParameterToNumeric(


cwbDB_FormatHandle format,
unsigned long parameterPosition,
signed short parameterType,
unsigned long parameterLength,
unsigned short parameterPrecision,
unsigned short parameterScale,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
signed short parameterType - input
Specifies the numeric type to be used.
unsigned long parameterLength - input
Only used if the type is zoned or packed decimal
unsigned short parameterPrecision - input
Only used if the type is zoned or packed decimal
unsigned short parameterScale - input
Only used if the type is zoned or packed decimal
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the parameterType parameter, use one of the defined values:
CWBDB_PCLONG
CWBDB_PCSHORT
CWBDB_PCFLOAT
CWBDB_PCDOUBLE
CWBDB_PCPACKED
CWBDB_PCZONED

Chapter 3. Express C/C++ APIs 415


cwbDB_SetClientParameterToString:

Purpose: Sets the information for a parameter description for string data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetClientParameterToString(


cwbDB_FormatHandle format,
unsigned long parameterPosition,
signed short parameterType,
unsigned long parameterLength,
unsigned short parameterCCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
unsigned long parameterPosition - input
Specifies the relative position of the parameter.
signed short parameterType - input
Specifies the string type to be used.
unsigned long parameterLength - input
Specifies the parameter length to be used.
unsigned short parameterCCSID - input
Specifies the parameter CCSID (Coded Character Set Identifier) to be used.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For the parameterType parameter, use one of the defined values:
CWBDB_PCSTRING
CWBDB_PCVARSTRING
CWBDB_PCGRAPHIC
CWBDB_PCVARGRAPHIC

416 Client Access Express Programming


cwbDB_SetCommitmentControl:

Purpose: Set the commitment level for the database server to use when accessing
data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetCommitmentControl(


cwbDB_ConnectionHandle connection,
unsigned short commitmentLevel,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short commitmentLevel - input
Indicates the commitment level for server operations.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: Use one of the defined values:


CWBDB_NONE
CWBDB_CURSOR_STABILITY
CWBDB_CHANGE
CWBDB_ALL

The cwbDB_ApplyAttributes API must be called after


cwbDB_SetCommitmentControl in order for the new commitment level to take
affect.

Chapter 3. Express C/C++ APIs 417


cwbDB_SetConversionIndicator:

Purpose: Sets the indicator that says whether data is to be converted between the
client and host format.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetConversionIndicator(


cwbDB_FormatHandle format,
cwb_Boolean conversionIndicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_FormatHandle format - input
Handle to a data format object.
cwb_Boolean conversionIndicator - input
CWB_FALSE indicates no conversion. CWB_TRUE indicates conversion.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: The cwbDB_ApplyAttributes API must be called after


cwbDB_SetConversionIndicator in order for the new value to take affect.

418 Client Access Express Programming


cwbDB_SetConvert65535:

Purpose: Sets the indicator that says whether data marked with CCSID 65535 is to
be converted between ASCII and EBCDIC. Data tagged with CCSID 65535 are
binary data. Selecting to convert this this data may cause conversion errors and
possible data integrity problems. USE THIS API AT YOUR OWN RISK. Having
stated that, it is important to note that some older data may have text data tagged
with CCSID 65535. Also, some AS/400 tools still write data to files using CCSID
65535. Therefore, there may be appropriate times to use this API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetConvert65535(


cwbDB_ConnectionHandle connection,
cwb_Boolean convert65535indicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to a connection object.
ccwb_Boolean convert65535indicator - input
CWB_FALSE indicates no conversion of binary data. CWB_TRUE indicates
conversion of data will take place.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: None

Chapter 3. Express C/C++ APIs 419


cwbDB_SetCursorName:

Purpose: Set the statement name to be used for this request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetCursorName(


cwbDB_RequestHandle request,
char *cursorName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *cursorName - input
Pointer to an ASCIIZ string containing the cursor name being used for an SQL
request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

420 Client Access Express Programming


cwbDB_SetDateFormat:

Purpose: Set the format for date data returned from the AS/400. Date data on the
AS/400 are stored encoded and are returned to the client as character strings.
These character strings can be formatted in eight different ways:
Format name Format Example
--------------- ---------- ---------------
Julian yy/ddd 87/253
month day year mm/dd/yy 10/12/87
day month year dd/mm/yy 12/10/87
year month day yy/mm/dd 87/10/12
USA mm/dd/yyyy 10/12/1987
ISO yyyy-mm-dd 1987-10-12
IBM Japan yyyy-mm-dd 1987-10-12
IBM Europe dd.mm.yyyy 12.10.1987

Syntax:

unsigned int CWB_ENTRY cwbDB_SetDateFormat(


cwbDB_ConnectionHandle connection,
unsigned short dateFormat,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short dateFormat - input
Indicates the format of date data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: It is not valid to call this API after calling the cwbDB_StartServer API. Use
one of the defined values:
Format name Date format constant Value
--------------- -------------------- ------
Julian CWBDB_DATE_FMT_JUL 0
month day year CWBDB_DATE_FMT_MDY 1
day month year CWBDB_DATE_FMT_DMY 2
year month day CWBDB_DATE_FMT_YMD 3
USA CWBDB_DATE_FMT_USA 4
ISO CWBDB_DATE_FMT_ISO 5
IBM Japan CWBDB_DATE_FMT_JIS 6
IBM Europe CWBDB_DATE_FMT_EUR 7

Chapter 3. Express C/C++ APIs 421


cwbDB_SetDateSeparator:

Purpose: Set the character which separates the elements of date data returned from
the AS/400. Date data on the AS/400 are stored encoded and are returned to the
client as character strings. These character strings can have one of five different
date separator characters:
Date separator Character Example
--------------- ---------- ---------------
Slash / 03/17/94
Dash - 03-17-94
Period . 03.17.94
Comma , 03,17,94
Blank 03 17 94

Syntax:

unsigned int CWB_ENTRY cwbDB_SetDateSeparator(


cwbDB_ConnectionHandle connection,
unsigned short dateSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short dateSeparator - input
Indicates the separator character for date fields.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: It is not valid to call this API after calling the cwbDB_StartServer API. Use
one of the defined values:
Date separator Date separator constant
--------------- -----------------------
Slash CWBDB_DATE_SEP_SLASH
Dash CWBDB_DATE_SEP_DASH
Period CWBDB_DATE_SEP_PERIOD
Comma CWBDB_DATE_SEP_COMMA
Blank CWBDB_DATE_SEP_BLANK

422 Client Access Express Programming


cwbDB_SetDecimalSeparator:

Purpose: Set the character which separates the elements of decimal data returned
from the AS/400.
Decimal separator Character Example
----------------- ---------- ---------------
Period . 123.45
Comma , 123,45

Syntax:

unsigned int CWB_ENTRY cwbDB_SetDecimalSeparator(


cwbDB_ConnectionHandle connection,
unsigned short decimalSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short decimalSeparator - input
Indicates the desired decimal separator character.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: It is not valid to call this API after calling the cwbDB_StartServer API. Use
one of the defined values:
Time separator Time separator constant
--------------- --------------------------
Period CWBDB_DECIMAL_SEP_PERIOD
Comma CWBDB_DECIMAL_SEP_COMMA

Chapter 3. Express C/C++ APIs 423


cwbDB_SetDescribeOption:

Purpose: Set the describe option to determine what data is to be returned as a


result of a describe.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetDescribeOption(


cwbDB_RequestHandle request,
unsigned short describeOption,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short describeOption - input
Long integer specifying the type of data to be returned on a describe
operation.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid describeOption value.

Usage: Use one of the defined values:


CWBDB_DESC_ALIAS_NAMES
CWBDB_DESC_NAMES_ONLY
CWBDB_DESC_LABELS

This API is not valid for NDB or catalog requests.

424 Client Access Express Programming


cwbDB_SetFetchScrollOptions:

Purpose: After using the cwbDB_SetScrollableCursor, this API is used to indicate


how to scroll through the data.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFetchScrollOptions(


cwbDB_RequestHandle request,
unsigned short scrollType,
unsigned long relativeDistance,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short scrollType - input
Indicates type of scrolling to be performed.
unsigned long relativeDistance - input
If the scrollType indicates scrolling relative to the current cursor position, this
parameter indicates the relative distance. For other scrollType values, this
parameter is ignored.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid scrollType value.

Usage: Use one of the defined values:


CWBDB_SCROLL_NEXT
CWBDB_SCROLL_PREVIOUS
CWBDB_SCROLL_FIRST
CWBDB_SCROLL_LAST
CWBDB_SCROLL_BEFORE_FIRST
CWBDB_SCROLL_AFTER_LAST
CWBDB_SCROLL_CURRENT
CWBDB_SCROLL_RELATIVE

This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 425


cwbDB_SetFieldName:

Purpose: Set the field name to be used in a catalog request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFieldName(


cwbDB_RequestHandle request,
char *fieldName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *fieldName - input
Pointer to an ASCIIZ string containing the field name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

426 Client Access Express Programming


cwbDB_SetFileAttributes:

Purpose: Set the file attributes to be used as a qualifier for a list request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFileAttributes(


cwbDB_RequestHandle request,
unsigned short fileAttributes,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short fileAttributes - input
Long integer that indicates attributes of files to be retrieved for a catalog
request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. Use one of the
defined values:
CWBDB_ALL_FILES_ATTRIBUTES
CWBDB_PHYSICAL_FILES_ATTRIBUTES
CWBDB_LOGICAL_FILES_ATTRIBUTES
CWBDB_ODBC_TABLES_ATTRIBUTES
CWBDB_ODBC_VIEWS_ATTRIBUTES

This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 427


cwbDB_SetFileInfoOrdering:

Purpose: Changes the ordering of the data returned by catalog requests.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFileInfoOrdering(


cwbDB_RequestHandle request,
unsigned short fileInfoOrder,
cwbSV_ErrHandle errorHandle

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long infoOrdering - input
Long integer that indicates how the returned information is to be ordered.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. Use one of the
defined values:
CWBDB_DEFAULT_CATALOG_ORDERING
CWBDB_ODBC_TABLE_ORDERING
CWBDB_ODBC_TABLE_PRIVILEGE_ORDER

This API is not valid for NDB or SQL requests.

428 Client Access Express Programming


cwbDB_SetFileName:

Purpose: Set the file name to be used as a qualifier for a list request. This is the
short file name (system name).

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFileName(


cwbDB_RequestHandle request,
char *fileName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *fileName - input
Pointer to an ASCIIZ string containing the file name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. This API is
not valid for SQL requests.

Chapter 3. Express C/C++ APIs 429


cwbDB_SetFileText:

Purpose: Set the text description for a file that will be created through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFileText(


cwbDB_RequestHandle request,
char *fileText,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *fileText - input
Pointer to an ASCIIZ string that contains the text description to be used when
creating a file.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests.

430 Client Access Express Programming


cwbDB_SetFileType:

Purpose: Set the file type to be used as a qualifier for a list request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFileType(


cwbDB_RequestHandle request,
unsigned short fileType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short fileAttribute - input
Long integer that indicates type of files to be retrieved for a catalog request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. Use one of the
defined values:
CWBDB_ALL_FILES
CWBDB_SOURCE_FILES
CWBDB_DATA_FILES

This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 431


cwbDB_SetForeignKeyFileName:

Purpose: Set the foreign key file name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetForeignKeyFileName(


cwbDB_RequestHandle request,
char *fileName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *fileName - input
Pointer to an ASCIIZ string containing the foreign key file name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

432 Client Access Express Programming


cwbDB_SetForeignKeyLibName:

Purpose: Set the foreign key library name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetForeignKeyLibName(


cwbDB_RequestHandle request,
char *libName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *libName - input
Pointer to an ASCIIZ string containing the foreign key library name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 433


cwbDB_SetFormatName:

Purpose: Set the record format name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetFormatName(


cwbDB_RequestHandle request,
char *formatName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *formatName - input
Pointer to an ASCIIZ string containing the record format name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

434 Client Access Express Programming


cwbDB_SetHoldIndicator:

Purpose: This API instructs SQL how to treat active statements (open cursors and
prepared dynamic SQL statements) when a commit or rollback operation is
performed. CWBDB_HOLD indicates that open cursors and prepared dynamic SQL
statements will be preserved. CWBDB_WORK will cause open cursors to be closed
and prepared dynamic SQL statement to be destroyed.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetHoldIndicator(


cwbDB_RequestHandle request,
unsigned short holdIndicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short holdIndicator - input
Input value for hold indicator.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid holdIndicator value.

Usage: Use one of the defined values:


CWBDB_WORK
CWBDB_HOLD

This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 435


cwbDB_SetIgnoreDecimalDataError:

Purpose: Set an indicator that says whether to ignore or correct zoned decimal
data errors.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetIgnoreDecimalDataError(


cwbDB_ConnectionHandle connection,
unsigned short ignoreDecimalError,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short ignoreDecimalError - input
Indicates how decimal data errors will be treated.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: Use one of the defined values:


CWBDB_IGNORE_ERROR
CWBDB_CORRECT_ERROR

The cwbDB_ApplyAttributes API must be called after


cwbDB_SetIgnoreDecimalDataError in order for the new value to take affect.

436 Client Access Express Programming


cwbDB_SetIndexType:

Purpose: Set the type of index criteria to be used in a catalog request

Syntax:

unsigned int CWB_ENTRY cwbDB_SetIndexType(


cwbDB_RequestHandle request,
unsigned short indexType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short indexType - input
Long integer that indicates index rule to be retrieved for a catalog request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. Use one of the defined values:
CWBDB_UNIQUE_INDEX
CWBDB_DUPLICATE_INDEX
CWBDB_DUP_NULL_INDEX

This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 437


cwbDB_SetLibraryName:

Purpose: Set the library name to be used for the current database request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetLibraryName(


cwbDB_RequestHandle request,
char *libraryName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *libraryName - input
Pointer to an ASCIIZ string containing the library name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For SQL requests, this is the library that is used when locating an SQL
package to be used for stored statements. For List and Native Database requests,
this is the library containing objects on which to be operated.

438 Client Access Express Programming


cwbDB_SetLongFileName:

Purpose: Set the long file name to be used as a qualifier for a list request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetLongFileName(


cwbDB_RequestHandle request,
char *longFileName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *longFileName - input
Pointer to an ASCIIZ string containing the long file name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. This API is
not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 439


cwbDB_SetMaximumMembers:

Purpose: Set the maximum number of members for creating a file through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetMaximumMembers(


cwbDB_RequestHandle request,
signed short maxMembers,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
signed short maxMembers - input
Input value for maximum number of members. A value of -1 for this
parameter indicates no maximum.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests.

440 Client Access Express Programming


cwbDB_SetMemberName:

Purpose: Set the member name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetMemberName(


cwbDB_RequestHandle request,
char *memberName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *memberName - input
Pointer to an ASCIIZ string containing the member name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is also used for NDB requests when operating on a database file
member. This API is not valid for SQL requests.

Chapter 3. Express C/C++ APIs 441


cwbDB_SetMemberText:

Purpose: Set the text description for a member at will be added through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetMemberText(


cwbDB_RequestHandle request,
char *memberText,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *memberText - input
Pointer to an ASCIIZ string that contains the text description to be used when
adding a member.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests.

442 Client Access Express Programming


cwbDB_SetNamingConvention:

Purpose: Set the naming convention (SQL or AS/400 system) to be used by the
database access server.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetNamingConvention(


cwbDB_ConnectionHandle connection,
unsigned short newNamingConvention,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server
unsigned short newNamingConvention - input
Indicates the type of naming convention to use. SQL naming convention
(library.table) or AS/400 native naming convention (library/table).
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Invalid naming convention value.

Usage: Use one of the defined values:


CWBDB_PERIOD_NAME_CONV
CWBDB_SLASH_NAME_CONV

The cwbDB_ApplyAttributes API must be called after


cwbDB_SetNamingConvention in order for the new naming convention to take
affect.

Chapter 3. Express C/C++ APIs 443


cwbDB_SetNLSS:

Purpose: Sets the National Language Sort Sequence (NLSS) attribute of the Data
Access server.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetNLSS(


cwbDB_ConnectionHandle connection,
unsigned short NLSSTypeID,
char *tableOrLangID,
char *library,
cwbSV_ErrHandle errorHandle );

Parameters:
cwbDB_ConnectionHandle - input
Connection through which the attribute is to be set
unsigned short NLSSTypeID - input
The type of NLSS attribute. Possible values:
CWBDB_NLSS_SORT_HEX
CWBDB_NLSS_SORT_SHARED
CWBDB_NLSS_SORT_UNIQUE
CWBDB_NLSS_SORT_USER
char *tableOrLangID - input
Depends on value of the NLSSType parameter (above).
CWBDB_NLSS_SORT_HEX
This parameter is not used
CWBDB_NLSS_SORT_SHARED or CWBDB_NLSS_SORT_UNIQUE
This parameter represents the language feature code attribute ID for
the server. It is a required parameter.
CWBDB_NLSS_SORT_USER
This parameter represents the NLSS table name attribute. It is a
required parameter.
char *library - input
Depends on value of the NLSSType parameter (above).
CWBDB_NLSS_SORT_HEX
This parameter is not used.
CWBDB_NLSS_SORT_SHARED or CWBDB_NLSS_SORT_UNIQUE
This parameter is not used
CWBDB_NLSS_SORT_USER
This parameter represents the NLSS library name attribute. It is an
optional parameter.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextAPI. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.

444 Client Access Express Programming


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid connection handle.
CWBDB_INVALID_ARG_API
Invalid type, language ID, or table.

Usage: The cwbDB_ApplyAttributes API must be called after cwbDB_SetNLSS


in order for the new sort sequence to take affect.

Chapter 3. Express C/C++ APIs 445


cwbDB_SetNullable:

Purpose: Set the nullable indicator for a special column.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetNullable(


cwbDB_RequestHandle request,
unsigned short nullableInd,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short nullableInd - input
Integer that indicates whether special column is null capable.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call. Use one of the
defined values:
CWBDB_NOT_NULLABLE
CWBDB_NULLABLE

This API is not valid for NDB or SQL requests.

446 Client Access Express Programming


cwbDB_SetOverrideInformation:

Purpose: Set the overriding library, file, and member for an override database
operation.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetOverrideInformation(


cwbDB_RequestHandle request,
char *overrideLibraryName,
char *overrideFileName,
char *overrideMemberName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *overrideLibraryName - input
Pointer to an ASCIIZ string that contains the overriding library name.
char *baseFileName - input
Pointer to an ASCIIZ string that contains the overriding file name.
char *overrideMemberName - input
Pointer to an ASCIIZ string that contains the overriding member name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is used in preparation for cwbDB_OverrideFile. This API is not
valid for List or SQL requests.

Chapter 3. Express C/C++ APIs 447


cwbDB_SetPackageName:

Purpose: Set the SQL package name for a database request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetPackageName(


cwbDB_RequestHandle request,
char *packageName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *packageName - input
Pointer to an ASCIIZ string containing the SQL package name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: For catalog requests, this API is used prior to


cwbDB_RetrievePackageInformation or
cwbDB_RetrievePackageStatementInformation. For SQL requests, this API is used
to set the name of the SQL package to be used for preparing or executing SQL
statements. This is optional for SQL requests. This API is not valid for NDB
requests.

448 Client Access Express Programming


cwbDB_SetParameterMarkerBlock:

Purpose: Provides the data to be used for the parameter markers contained in a
prepared statement for a block of rows.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetParameterMarkerBlock(


cwbDB_RequestHandle request,
unsigned long numberOfRows,
cwbDB_FormatHandle format,
void *dataPointer,
signed short *indicators,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long numberOfRows - input
Number of sets of parameter marker data that is in the dataBuffer.
cwbDB_FormatHandle format - input
Handle to the format of the data being provided.
void *dataBuffer - input
Pointer to a buffer containing the data to be used for the parameter markers.
signed short *indicators - input
Pointer to a buffer containing the null indicators. If the value of the indicator is
less than zero, the value for the corresponding parameter marker is null.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 449


cwbDB_SetParameterMarkers:

Purpose: Provides the data to be used for the parameter markers contained in a
prepared statement.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetParameterMarkers(


cwbDB_RequestHandle request,
cwbDB_FormatHandle format,
void *dataBuffer,
signed short *indicators,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbDB_FormatHandle *format - input
Handle to the format of the data being provided.
void *dataBuffer - input
Pointer to a buffer containing the data to be used for the parameter markers.
signed short *indicators - input
Pointer to a buffer containing the null indicators. If the value of the indicator is
less than zero, the value for the corresponding parameter marker is null.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

450 Client Access Express Programming


cwbDB_SetPrepareOption:

Purpose: Set the option for doing a normal or enhanced prepare. Doing an
enhanced prepare will search the specified SQL package for the given statement. If
it is found, the statement will be used. If not, the statement will be prepared.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetPrepareOption(


cwbDB_RequestHandle request,
unsigned short prepareOption,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short prepareOption - input
Long integer specifying the type of prepare to be performed.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid prepareOption value.

Usage: Use one of the defined values:


CWBDB_NORMAL_PREPARE
CWBDB_ENHANCED_PREPARE

This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 451


cwbDB_SetPrimaryKeyFileName:

Purpose: Set the primary key file name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetPrimaryKeyFileName(


cwbDB_RequestHandle request,
char *fileName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *fileName - input
Pointer to an ASCIIZ string containing the primary key file name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

452 Client Access Express Programming


cwbDB_SetPrimaryKeyLibName:

Purpose: Set the primary key library name to be used in a request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetPrimaryKeyLibName(


cwbDB_RequestHandle request,
char *libName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *libName - input
Pointer to an ASCIIZ string containing the primary key library name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to a cwbDB_Retrieve* API call for a catalog
request. This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 453


cwbDB_SetRDBName:

Purpose: Set the Relational Database (RDB) name for a catalog request. This is the
RDB for which information is being requested.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetRDBName(


cwbDB_RequestHandle request,
char *RDBName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *RDBName - input
Pointer to an ASCIIZ string containing the RDB name.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is used prior to cwbDB_RetrieveDBInformation. This API is not


valid for SQL or NDB requests.

454 Client Access Express Programming


cwbDB_SetRecordLength:

Purpose: Set the record length in preparation for creating a file through the API.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetRecordLength(


cwbDB_RequestHandle request,
unsigned long recordLength,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned long recordLength - input
Length of records to be contained in the file to be created.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for List or SQL requests.

Chapter 3. Express C/C++ APIs 455


cwbDB_SetScrollableCursor:

Purpose: Indicate whether the cursor used by this request is scrollable.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetScrollableCursor(


cwbDB_RequestHandle request,
unsigned short scrollIndicator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short scrollIndicator - input
Input value for scroll indicator.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_INVALID_ARG_API
Invalid scrollIndicator value.

Usage: Use one of the defined values:


CWBDB_CURSOR_NOT_SCROLLABLE
CWBDB_CURSOR_SCROLLABLE

This API is not valid for NDB or catalog requests.

456 Client Access Express Programming


cwbDB_SetStatementName:

Purpose: Set the statement name to be used for this request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetStatementName(


cwbDB_RequestHandle request,
char *statementName,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *statementName - input
Pointer to an ASCIIZ string containing the statement name being used for an
SQL request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

Chapter 3. Express C/C++ APIs 457


cwbDB_SetStatementText:

Purpose: Set the statement text to be used for this request.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetStatementText(


cwbDB_RequestHandle request,
char *statementText,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
char *statementText - input
Pointer to an ASCIIZ string containing the statement text being used for an
SQL request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API is not valid for NDB or catalog requests.

458 Client Access Express Programming


cwbDB_SetStatementType:

Purpose: Set the type of SQL statement for which information is being requested.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetStatementType(


cwbDB_RequestHandle request,
unsigned short statementType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short statementType - input
Long integer that indicates type of SQL statement being used for a catalog
request.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.

Usage: This API may be used prior to making a


cwbDB_RetrieveSQLPackageStatement API call. Use one of the defined values:
CWBDB_ALL_STATEMENTS
CWBDB_DECLARE_STATEMENTS
CWBDB_SELECT_STATEMENTS
CWBDB_EXEC_STATEMENTS

This API is not valid for NDB or SQL requests.

Chapter 3. Express C/C++ APIs 459


cwbDB_SetStreamFetchSyncCount:

Purpose: Set the number of 32Kb blocks sent from the server to the client during a
stream fetch before a synchronizing handshake is required.

Syntax:

unsigned int CWB_ENTRY cwbDB_SetStreamFetchSyncCount(


cwbDB_RequestHandle request,
unsigned short syncCount,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
unsigned short syncCount - input
Unsigned short integer that indicates how many 32Kb flows from the server
will happen before a synchronizing handshake will happen.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid request handle.
CWBDB_STREAM_FETCH_NOT_COMPLETE
Stream fetch in process.

Usage: This API is not valid for NDB or Catalog requests. This API must be called
before the cwbDB_DynamicStreamFetch or the
cwbDB_ExtendedDynamicStreamFetch API is called.

460 Client Access Express Programming


cwbDB_SetTimeFormat:

Purpose: Set the format for time data returned from the AS/400. Time data on the
AS/400 are stored encoded and are returned to the client as character strings.
These character strings can be formatted in five different ways:
Format name Format Example
--------------- ---------- ---------------
Hours minutes seconds hh:mm:ss 13:30:05
USA hh:mm AM or PM 1:30 PM
ISO hh.mm.ss 13:30:05
IBM Europe hh.mm.ss 13:30:05
IBM Japan hh:mm:ss 13:30:05

Syntax:

unsigned int CWB_ENTRY cwbDB_SetTimeFormat(


cwbDB_ConnectionHandle connection,
unsigned short timeFormat,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short timeFormat - input
Indicates the format of time data.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: It is not valid to call this API after calling the cwbDB_StartServer API. Use
one of the defined values:
Format name Time format constant
--------------- -----------------------
Hours minutes seconds CWBDB_TIME_FMT_HMS
USA CWBDB_TIME_FMT_USA
ISO CWBDB_TIME_FMT_ISO
IBM Europe CWBDB_TIME_FMT_EUR
IBM Japan CWBDB_TIME_FMT_JIS

Chapter 3. Express C/C++ APIs 461


cwbDB_SetTimeSeparator:

Purpose: Set the character which separates the elements of time data returned from
the AS/400. Time data on the AS/400 are stored encoded and are returned to the
client as character strings. These character strings can have one of four different
time separator characters:
Date separator Character Example
--------------- ---------- ---------------
Colon : 11:10:03
Period . 11.10.03
Comma , 11,10,03
Blank 11 10 03

Syntax:

unsigned int CWB_ENTRY cwbDB_SetTimeSeparator(


cwbDB_ConnectionHandle connection,
unsigned short timeSeparator,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned short timeSeparator - input
Indicates the time data separator character.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.
CWBDB_INVALID_ARG_API
Value specified is not in range.

Usage: It is not valid to call this API after calling the cwbDB_StartServer API. Use
one of the defined values:
Time separator Time separator constant
--------------- -----------------------
Colon CWBDB_TIME_SEP_COLON
Period CWBDB_TIME_SEP_PERIOD
Comma CWBDB_TIME_SEP_COMMA
Blank CWBDB_TIME_SEP_BLANK

462 Client Access Express Programming


cwbDB_StartServer:

Purpose: Starts the communication between the client and the AS/400 server.

Syntax:

unsigned int CWB_ENTRY cwbDB_StartServer(


cwbDB_ConnectionHandle connection,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

Chapter 3. Express C/C++ APIs 463


cwbDB_StartServerDetailed:

Purpose: Starts the communication between the client and the AS/400 server.
Returns a more detailed return code than cwbDB_StartServer, but otherwise the
same.

Syntax:

unsigned int CWB_ENTRY cwbDB_StartServerDetailed(


cwbDB_ConnectionHandle connection,
unsigned long *returnCode,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
unsigned long *returnCode - output
Pointer to an unsigned long to receive the detailed return code.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None.

464 Client Access Express Programming


cwbDB_StopServer:

Purpose: Ends the communication between the client and the AS/400 server.

Syntax:

unsigned int CWB_ENTRY cwbDB_StopServer(


cwbDB_ConnectionHandle connection,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_ConnectionHandle connection - input
Handle to connection to AS/400 database access server.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: None

Chapter 3. Express C/C++ APIs 465


cwbDB_StoreRequestParameters:

Purpose: Sends the current parameters to the AS/400 to the stored by the database
access server. Those parameters can then be used by the request on subsequent
function calls.

Syntax:

unsigned int CWB_ENTRY cwbDB_StoreRequestParameters(


cwbDB_RequestHandle request,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDB_RequestHandle request - input
Handle to a request object.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Incorrect connection handle.

Usage: This API is used to store a set of parameters in a buffer on the AS/400.
This is useful if there is a set of common parameters that are to be used for
multiple functions. The API allows the application to reduce the amount of data
that needs to flow in order to perform all of the requests.

466 Client Access Express Programming


Example: Using SQL to access database functions
///////////////////////////////////////////////////////////////////////
//
// PRFTST.CPP
// CLIENT ACCESS DATA ACCESS SAMPLE PROGRAM - Block Fetch a whole table
// Usage: prftst systemname blocksize limit
// systemname - name of the AS/400 to run against
// blocksize - number of rows to bring down in each fetch call
// default: 1 row
// limit - total number of rows to bring down
// default: INT_MAX
// Input file: prftst.qry: Put the text of your input query in
// an ASCII file of this name. Limit: 500 characters,
// unless you change it. (See MAXSIZE constant.)
// Example: SELECT * FROM QIWS.QCUSTCDT
// Usage notes: If the blocksize exceeds the number of rows in the
// table, the entire table is fetched.
//
// Link with CWBAPI.LIB
//
///////////////////////////////////////////////////////////////////////

#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>

#include "CWBDB.H" // Header for Database access API's


#include "CWBSV.H" // Header for Serviceability API's
void scene18( char*, int, int );

void main( int argc, char *argv[] )


{
char sys[15] = "SYSTEMXX";
int block = 1;
int limit = INT_MAX;

if ( argc > 1 )
{
for( unsigned int i = 0; i<=strlen(argv[1]); i++ )
sys[i] = (char) toupper(argv[1][i]);
}

if ( argc > 2 )
{
block = atoi(argv[2]);
}
if ( argc > 3 )
{
limit = atoi(argv[3]);
}
scene18(sys, block, limit);
return;
}

void scene18( char *systemName, int blockSize, int fetchLimit )


{

FILE *infile, *outfile;


outfile = fopen("prftst.out","w");
char *cursorName = "CURSOR1";
char *statementName ="BTDB018";
const int MAXSIZE = 500;
char statementText[MAXSIZE] = "";
unsigned int rc;
int rowCount = 0;
unsigned long dataLength = 0;
char ch;

cwbDB_FormatHandle myFmt;
cwbDB_ConnectionHandle Conn;
cwbSV_ErrHandle errorHandle;
cwbDB_RequestHandle SQLReq;

cwbDB_DataHandle myData, ind, msgid, first, sec;


unsigned short hClass;
signed long hCode;

// Read the input file

int count = 0;
if ( (infile = fopen("prftst.qry","r")) != NULL) {
while ( (ch = getc(infile)) != EOF &&; ch != '\n' &&; count < MAXSIZE ) {
statementText[count] = ch;
count++;
}
count++;
statementText[count] = '\n';
} else {
cout << "Need input query parameter in prftst.qry." << endl;
return;
}
cout << "Block Fetch with data conversion" << endl << endl;

// Create a necessary handles

cwbDB_CreateDataHandle(&myData,; errorHandle);

cwbDB_CreateDataHandle(&ind,; errorHandle);

Chapter 3. Express C/C++ APIs 467


cwbDB_CreateDataHandle(&msgid,; errorHandle);

cwbDB_CreateDataHandle(&first,; errorHandle);

cwbDB_CreateDataHandle(&sec,; errorHandle);

cwbSV_CreateErrHandle(&errorHandle);;

cwbDB_CreateConnectionHandle(systemName, &Conn,; errorHandle);

cwbDB_CreateSQLRequestHandle(Conn, &SQLReq,; errorHandle);

cwbDB_CreateDataFormatHandle(Conn, &myFmt,; errorHandle);


cout << "Starting data access server on system: " << systemName << endl;

// Start the database access server

if ((rc = cwbDB_StartServer(Conn, errorHandle)) != 0)


{
cout << "Bad return code from the startServer call: " << rc << endl;
return;
}

// ************* Setup - prepare statement *************

if ((rc = cwbDB_SetStatementName(SQLReq, statementName, errorHandle)) != 0)


{
cout << "FAIL - set statement name failed with return code: " << rc
<< endl << endl;
return;
}

if ((rc = cwbDB_SetCursorName(SQLReq, cursorName, errorHandle)) != 0)


{
cout << "FAIL - set cursor name failed with return code: "
<< rc << endl << endl;
return;
}

if ((rc = cwbDB_StoreRequestParameters(SQLReq, errorHandle)) != 0)


{
cout << "FAIL - store parameters failed with return code: " << rc
<< endl << endl;
return;
}

if ((rc = cwbDB_SetStatementText(SQLReq, statementText, errorHandle)) != 0)


{
cout << "FAIL - set statement text failed with return code: " << rc
<< endl << endl;
return;
}

if ((rc = cwbDB_Prepare(SQLReq, errorHandle)) != 0)


{
cout << "FAIL - prepare request failed: " << rc
<< endl << endl;
return;
}

// ************* Open cursor *************

if ((rc = cwbDB_Open(SQLReq, CWBDB_READ, errorHandle)) != 0)


{
cout << "FAIL - open request failed: " << rc
<< endl << endl;
return;
}
// ************* Fetch data *************

if ((rc = cwbDB_SetCursorName(SQLReq, cursorName, errorHandle)) != 0)


{
cout << "FAIL - set cursor name failed with return code: "
<< rc << endl << endl;
return;
}

cwbDB_SetConversionIndicator(myFmt, 1, errorHandle);

// Loop through the block fetch until the limit is reached.


// If the limit is bigger than the total number of rows in the table,
// the fetch will eventually fail.

while (rowCount < fetchLimit) {

if ((cwbDB_ReturnData(SQLReq, myData, ind, myFmt, errorHandle)) != 0)


{
cout << "FAIL - request for data to be returned failed: " << rc
<< endl << endl;
return;
}

if ((rc = cwbDB_ReturnHostErrorInfo(SQLReq, &hClass,; &hCode,; msgid, first, sec,


errorHandle)) != 0)
{
cout << "FAIL - request for return host error info failed: " << rc
<< endl << endl;
}

if ((rc = cwbDB_SetBlockCount(SQLReq, blockSize, errorHandle)) != 0)


{
cout << "FAIL - set block size failed with return code: " << rc

468 Client Access Express Programming


<< endl << endl;
return;
}

cout << "Fetching a block of " << dec << blockSize << "." << endl;

if ((rc = cwbDB_Fetch(SQLReq, errorHandle)) != 0)


{
char* firsttxt;
char* sectxt;
char** pfirsttxt = &firsttxt;
char** psectxt = &sectxt;
cwbDB_GetDataPointer(first, pfirsttxt, errorHandle);
cwbDB_GetDataPointer(sec, psectxt, errorHandle);
cout << endl << "Host message class: " << hClass << endl;
cout << endl << "Host message code: " << hCode << endl;
cout << "FIRST LEVEL TEXT: " << endl;
cout << firsttxt << endl << endl;
cout << "SECOND LEVEL TEXT: " << endl;
cout << sectxt << endl << endl;

break;
}
else
{
cout << "Fetch call ENDED." << endl;

rowCount+=blockSize;

cout << "Total rows fetched so far: "<< dec << rowCount << "." << endl << endl;
if (blockSize <= 10) {
char *theData = NULL;
char **pmyData = &theData;
unsigned long len;
cwbDB_GetDataPointer(myData, pmyData, errorHandle);
cwbDB_GetDataLength(myData, &len,; errorHandle);
cout << "Fetched data: " << endl;
cout.write( theData, len );
cout << endl;
}
}

} // end while

// Stop the database access server


cwbDB_StopServer(Conn, errorHandle);

// Delete all the handles


cwbDB_DeleteDataHandle(myData, errorHandle);

cwbDB_DeleteDataHandle(ind, errorHandle);

cwbDB_DeleteDataHandle(msgid, errorHandle);

cwbDB_DeleteDataHandle(first, errorHandle);

cwbDB_DeleteDataHandle(sec, errorHandle);
cwbDB_DeleteDataFormatHandle(myFmt, errorHandle);

cwbDB_DeleteConnectionHandle(Conn, errorHandle);

cwbDB_DeleteSQLRequestHandle(SQLReq, errorHandle);

cwbSV_DeleteErrHandle(errorHandle);
}

Express Data Queues APIs


Use Client Access Express Data Queues application programming interfaces (APIs)
to provide easy access to AS/400 data queues. Data queues allow you to create
client/server applications that do not require the use of communications APIs.
Express Data Queues APIs required files:

Header file Import library Dynamic Link Library


cwbdq.h cwbapi.lib cwbdq.dll

Express Toolkit:
The Client Access Express Toolkit provides Data Queues documentation,
access to the cwbdq.h header file, and links to sample programs. To access
this information, open the Express Toolkit and select Data Queues —>
C/C++ APIs.
Express Data Queues APIs topics:
v “Data queues” on page 470

Chapter 3. Express C/C++ APIs 469


v “Ordering data queue messages”
v “Working with data queues”
v “Typical use of data queues” on page 471
v Express Data Queues APIs listing
v “Example: Using Data Queues APIs” on page 534
v “Express Data Queues APIs return codes” on page 24
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Data queues
A data queue is a system object that exists on the AS/400 system.
Benefits of using data queues:
Data queues provide many benefits to PC developers and AS/400
applications developers, including:
v They are a fast and efficient means of communication on the AS/400.
v They have low system overhead and require very little setup.
v They are efficient because a single data queue can be used by a batch job
to service several interactive jobs.
v The contents of a data queue message are free-format (fields are not
required), providing flexibility that is not provided by other system
objects.
v Access data queues through an AS/400 API and through CL commands,
which provides a straight-forward means of developing client/server
applications.

Ordering data queue messages


There are three ways to designate the order of messages on a data queue:
LIFO Last in, first out. The last message (newest) placed on the data queue will
be the first message taken off of the queue.
FIFO First in, first out. The first message (oldest) placed on the data queue will
be the first message taken off of the queue.
KEYED
Each message on the data queue has a key associated with it. A message
can be taken off of the queue only by requesting the key with which it is
associated.

Working with data queues


Work with data queues by using AS/400 CL commands or callable programming
interfaces. Access to data queues is available to all AS/400 applications regardless
of the programming language in which the application is written.

Use the following AS/400 system interfaces to work with data queues:
OS/400 commands:
CRTDTAQ
Creates a data queue and stores it in a specified library
DLTDTAQ
Deletes the specified data queue from the system
OS/400 application programming interfaces:

470 Client Access Express Programming


QSNDDTAQ
Send a message (record) to the specified data queue
QRCVDTAQ
Read a message (record) to the specified data queue
QCLRDTAQ
Clear all messages from the specified data queue
QMHQRDQD
Retrieve a data queue description
QMHRDQM
Retrieve an entry from a data queue without removing the entry

Typical use of data queues


A data queue is a powerful program-to-program interface. Programmers who are
familiar with programming on the AS/400 are accustomed to using queues. Data
queues simply represent a method that is used to pass information to another
program.

Because this interface does not require communications programming, use it either
for synchronous or for asynchronous (disconnected) processing.

Develop host applications and PC applications by using any supported language.


For example, a host application could use RPG while a PC application might use
C++. The queue is there to obtain input from one side and to pass input to the
other.

The following example shows how data queues might be used:


v A PC user might take telephone orders all day, and key each order into a
program, while the program places each request on AS/400 data queue.
v A partner program (either a PC program or an AS/400 program) monitors the
data queue and pulls information from queue. This partner program could be
simultaneously running, or started after peak user hours.
v It may or may not return input to the initiating PC program, or it may place
something on the queue for another PC or AS/400 program.
v Eventually the order is filled, the customer is billed, the inventory records are
updated, and information is placed on the queue for the PC application to direct
a PC user to call the customer with an expected ship date.

Objects

An application that uses the data queue function uses four objects. Each of these
objects is identified to the application through a handle. The objects are:
Queue object:
This object represents the AS/400 data queue.
Attribute:
This object describes the AS/400 data queue.
Data: Use these objects to write records to, and to read records from, the AS/400
data queue.
Read object:
Use this object only with the asynchronous read APIs. It uniquely identifies
a request to read a record from the AS/400 data queue. This handle is used

Chapter 3. Express C/C++ APIs 471


on subsequent calls to check if the data has been returned. See the
cwbDQ_AsyncRead API for more information.

Express Data Queues APIs listing


In the following table, Express Data Queues APIs are listed alphabetically, and
grouped according to function:

Function Express Data Queues APIs


Creating, deleting, and opening a data cwbDQ_CreateEx
queue cwbDQ_DeleteEx
cwbDQ_OpenEx
Use these APIs in conjunction with the
cwbCO_SysHandle System Object handle.
Accessing the AS/400 data queue cwbDQ_AsyncRead
cwbDQ_Cancel
After the cwbDQ_Open API is used to cwbDQ_CheckData
create a connection to a specific data queue, cwbDQ_Clear
the other APIs can be used to utilize it. Use cwbDQ_Close
the cwbDQ_Close API when the connection cwbDQ_Create
no longer is needed. cwbDQ_Delete
cwbDQ_GetLibName
cwbDQ_GetQueueAttr
cwbDQ_GetQueueName
cwbDQ_GetSysName
cwbDQ_Open
cwbDQ_Peek
cwbDQ_Read
cwbDQ_Write
Declarations for the attributes of a data cwbDQ_CreateAttr
queue cwbDQ_DeleteAttr
cwbDQ_GetAuthority
The attribute object is used when creating a cwbDQ_GetDesc
data queue or when obtaining the data cwbDQ_GetForceToStorage
queue attributes. cwbDQ_GetKeySize
cwbDQ_GetMaxRecLen
cwbDQ_GetOrder
cwbDQ_GetSenderID
cwbDQ_SetAuthority
cwbDQ_SetDesc
cwbDQ_SetForceToStorage
cwbDQ_SetKeySize
cwbDQ_SetMaxRecLen
cwbDQ_SetOrder
cwbDQ_SetSenderID

472 Client Access Express Programming


Function Express Data Queues APIs
Declarations for functions that use the data cwbDQ_CreateData
object for writing to and reading from a cwbDQ_DeleteData
data queue cwbDQ_GetConvert
cwbDQ_GetData
cwbDQ_GetDataAddr
cwbDQ_GetDataLen
cwbDQ_GetKey
cwbDQ_GetKeyLen
cwbDQ_GetRetDataLen
cwbDQ_GetRetKey
cwbDQ_GetRetKeyLen
cwbDQ_GetSearchOrder
cwbDQ_GetSenderInfo
cwbDQ_SetConvert
cwbDQ_SetData
cwbDQ_SetDataAddr
cwbDQ_SetKey
cwbDQ_SetSearchOrder

Chapter 3. Express C/C++ APIs 473


cwbDQ_AsyncRead
Purpose: Read a record from the AS/400 data queue object that is identified by
the specified handle. The AsyncRead will return control to the caller immediately.
This call is used in conjunction with the CheckData API. When a record is read
from a data queue, it is removed from the data queue. If the data queue is empty
for more than the specified wait time, the read is aborted, and the CheckData API
returns a value of CWBDQ_TIMED_OUT. You may specifying a wait time from 0
to 99,999 (in seconds) or forever (-1). A wait time of zero causes the CheckData
API to return a value of CWBDQ_TIMED_OUT on its initial call if there is no data
in the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_AsyncRead(


cwbDQ_QueueHandle queueHandle,
cwbDQ_Data data,
signed long waitTime,
cwbDQ_ReadHandle *readHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
cwbDQ_Data data - input
The data object to be read from the AS/400 data queue.
signed long waitTime - input
Length of time in seconds to wait for data, if the data queue is empty. A wait
time of -1 indicates to wait forever.
cwbDQ_ReadHandle * readHandle - output
Pointer to where the cwbDQ_ReadHandle will be written. This handle will be
used in subsequent calls to the cwbDQ_CheckData API.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_TIME
Invalid wait time.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_INVALID_SEARCH
Invalid search order.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_Open or cwbDQ_OpenEx
cwbDQ_CreateData

474 Client Access Express Programming


cwbDQ_Cancel
Purpose: Cancel a previously issued AsyncRead. This will end the read on the
AS/400 data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Cancel(


cwbDQ_ReadHandle readHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_ReadHandle readHandle - input
The handle that was returned by the AsyncRead API.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_READ_HANDLE
Invalid read handle.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_Open or cwbDQ_OpenEx
cwbDQ_CreateData
cwbDQ_AsyncRead

Chapter 3. Express C/C++ APIs 475


cwbDQ_CheckData
Purpose: Check if data was returned from a previously issued AsyncRead API.
This API can be issued multiple times for a single AsyncRead call. It will return 0
when the data actually has been returned.

Syntax:

unsigned int CWB_ENTRY cwbDQ_CheckData(


cwbDQ_ReadHandle readHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_ReadHandle readHandle - input
The handle that was returned by the AsyncRead API.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_READ_HANDLE
Invalid read handle.
CWBDQ_DATA_TRUNCATED
Data truncated.
CWBDQ_TIMED_OUT
Wait time expired and no data returned.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_QUEUE_DESTROYED
Queue was destroyed.
CWBDQ_NO_DATA
No data.
CWBDQ_CANNOT_CONVERT
Unable to convert data.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_Open or cwbDQ_OpenEx
cwbDQ_CreateData
cwbDQ_AsyncRead

If a time limit was specified on the AsyncRead, this API will return
CWBDQ_NO_DATA until data is returned (return code will be CWB_OK), or the
time limit expires (return code will be CWBDQ_TIMED_OUT).

476 Client Access Express Programming


cwbDQ_Clear
Purpose: Remove all messages from the AS/400 data queue object that is
identified by the specified handle. If the queue is keyed, messages for a particular
key may be removed by specifying the key and key length. These values should be
set to NULL and zero, respectively, if you want to clear all messages from the
queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Clear(


cwbDQ_QueueHandle queueHandle,
unsigned char *key,
unsigned short keyLength,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
unsigned char * key - input
Pointer to the key. The key may contain embedded NULLs, so it is not an
ASCIIZ string.
unsigned short keyLength - input
Length of the key in bytes.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_BAD_KEY_LENGTH
Length of key is not correct.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.

Usage: This function requires that you have previously issued:


cwbDQ_Open or cwbDQ_OpenEx

Chapter 3. Express C/C++ APIs 477


cwbDQ_Close
Purpose: End the connection with the AS/400 data queue object that is identified
by the specified handle. This will end the conversation with the AS/400 system.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Close(


cwbDQ_QueueHandle queueHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open or
cwbDQ_OpenEx function. This identifies the AS/400 data queue object.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.

Usage: This function requires that you previously issued the following APIs:
cwbDQ_Openor cwbDQ_OpenEx

478 Client Access Express Programming


cwbDQ_Create
Purpose: Create an AS/400 data queue object. After the object is created it can be
opened using the cwbDQ_Open API. It will have the attributes that you specify in
the attributes handle.

Note: This API is obsolete. Use “cwbDQ_CreateEx” on page 481.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Create(


char *queue,
char *library,
char *systemName,
cwbDQ_Attr queueAttributes,
cwbSV_ErrHandle errorHandle);

Parameters:
char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
char * library - input
Pointer to the library name contained in an ASCIIZ string. If this pointer is
NULL then the current library will be used (set library to ″*CURLIB″).
char * systemName - input
Pointer to the system name contained in an ASCIIZ string.
cwbDQ_Attr queueAttributes - input
Handle to the attributes for the data queue.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages are
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.
CWB_CONFIG_ERROR
A configuration error has occurred.

Chapter 3. Express C/C++ APIs 479


CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_BAD_QUEUE_NAME
Queue name is incorrect.
CWBDQ_BAD_LIBRARY_NAME
Library name is incorrect.
CWBDQ_BAD_SYSTEM_NAME
System name is incorrect.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_NO_AUTHORITY
No authority to library.
CWBDQ_QUEUE_EXISTS
Queue already exists.
CWBDQ_QUEUE_SYNTAX
Queue syntax is incorrect.
CWBDQ_LIBRARY_SYNTAX
Library syntax is incorrect.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_CreateAttr
cwbDQ_SetMaxRecLen

480 Client Access Express Programming


cwbDQ_CreateEx
Purpose: Create an AS/400 data queue object. After the object is created it can be
opened using the cwbDQ_OpenEx API. It will have the attributes that you specify
in the attributes handle.

Syntax:

unsigned int CWB_ENTRY cwbDQ_CreateEx(


cwbCO_SysHandle sysHandle,
const char *queue,
const char *library,
char *systemName,
cwbDQ_Attr queueAttributes,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbCO_SysHandle sysHandle - input
Handle to a system object
const char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
const char * library - input
Pointer to the library name contained in an ASCIIZ string. If this pointer is
NULL then the current library will be used (set library to ″*CURLIB″).
cwbDQ_Attr queueAttributes - input
Handle to the attributes for the data queue.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.
CWB_CONFIG_ERROR
A configuration error has occurred.

Chapter 3. Express C/C++ APIs 481


CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_BAD_QUEUE_NAME
Queue name is incorrect.
CWBDQ_BAD_LIBRARY_NAME
Library name is incorrect.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_NO_AUTHORITY
No authority to library.
CWBDQ_QUEUE_EXISTS
Queue already exists.
CWBDQ_QUEUE_SYNTAX
Queue syntax is incorrect.
CWBDQ_LIBRARY_SYNTAX
Library syntax is incorrect.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page being used.
CWB_API_ERROR
General API failure.
CWB_INVALID_HANDLE
Invalid system handle.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_CreateSystem
cwbDQ_CreateAttr
cwbDQ_SetMaxRecLen

482 Client Access Express Programming


cwbDQ_CreateAttr
Purpose: Create a data queue attribute object. The handle returned by this API
can be used to set the specific attributes you want for a data queue prior to using
it as input for the cwbDQ_Create or cwbDQ_CreateEx APIs. It also may be used
to examine specific attributes of a data queue after using it as input for the
cwbDQ_GetQueueAttr API.

Syntax:

cwbDQ_Attr CWB_ENTRY cwbDQ_CreateAttr(void);

Parameters:
None

Return Codes: The following list shows common return values.


cwbDQ_Attr — A handle to a cwbDQ_Attr object.
Use this handle to obtain and set attributes. After creation, an attribute
object will have the default values of:
v Maximum Record Length - 1000
v Order - FIFO
v Authority - LIBCRTAUT
v Force to Storage - FALSE
v Sender ID - FALSE
v Key Length - 0

Usage: None

Chapter 3. Express C/C++ APIs 483


cwbDQ_CreateData
Purpose: Create the data object. This data object can be used for both reading and
writing data to a data queue.

Syntax:

cwbDQ_Data CWB_ENTRY cwbDQ_CreateData(void);

Parameters:
None

Return Codes: The following list shows common return values.


cwbDQ_Data — A handle to the data object
After creation, a data object will have the default values of:
v data - NULL and length 0
v key - NULL and length 0
v sender ID info - NULL
v search order - NONE
v convert - FALSE

Usage: None

484 Client Access Express Programming


cwbDQ_Delete
Purpose: Remove all data from an AS/400 data queue and delete the data queue
object.

Note: This API is obsolete. Use “cwbDQ_DeleteEx” on page 487.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Delete(


char *queue,
char *library,
char *systemName,
cwbSV_ErrHandle errorHandle);

Parameters:
char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
char * library - input
Pointer to the library name contained in an ASCIIZ string. If this pointer is
NULL then the current library will be used (set library to ″*CURLIB″).
char * systemName - input
Pointer to the system name contained in an ASCIIZ string.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.
CWB_CONFIG_ERROR
A configuration error has occurred.
CWBDQ_QUEUE_NAME
Queue name is too long.
CWBDQ_LIBRARY_NAME
Library name is too long.

Chapter 3. Express C/C++ APIs 485


CWBDQ_SYSTEM_NAME
System name is too long.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_QUEUE_NOT_FOUND
Queue not found on system.
CWBDQ_NO_AUTHORITY
No authority to queue.
CWBDQ_QUEUE_SYNTAX
Queue syntax is incorrect.
CWBDQ_LIBRARY_SYNTAX
Library syntax is incorrect.

Usage: None

486 Client Access Express Programming


cwbDQ_DeleteEx
Purpose: Remove all data from an AS/400 data queue and delete the data queue
object.

Syntax:

unsigned int CWB_ENTRY cwbDQ_DeleteEx(


cwbCO_SysHandle sysHandle
const char *queue,
const char *library,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbCO_SysHandle - input
Handle to a system object.
const char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
const char * library - input
Pointer to the library name contained in an ASCIIZ string. If this pointer is
NULL then the current library will be used (set library to ″*CURLIB″).
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.
CWB_CONFIG_ERROR
A configuration error has occurred.
CWBDQ_BAD_QUEUE_NAME
Queue name is too long.
CWBDQ_BAD_LIBRARY_NAME
Library name is too long.

Chapter 3. Express C/C++ APIs 487


CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_QUEUE_NOT_FOUND
Queue not found on system.
CWBDQ_NO_AUTHORITY
No authority to queue.
CWBDQ_QUEUE_SYNTAX
Queue syntax is incorrect.
CWBDQ_LIBRARY_SYNTAX
Library syntax is incorrect.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page being used.
CWB_API_ERROR
General API failure.
CWB_INVALID_HANDLE
Invalid system handle.

Usage: This function requires that you previously have issued


cwbCO_CreateSystem.

488 Client Access Express Programming


cwbDQ_DeleteAttr
Purpose: Delete the data queue attributes.

Syntax:

unsigned int CWB_ENTRY cwbDQ_DeleteAttr(


cwbDQ_Attr queueAttributes);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

Chapter 3. Express C/C++ APIs 489


cwbDQ_DeleteData
Purpose: Delete the data object.

Syntax:

unsigned int CWB_ENTRY cwbDQ_DeleteData(


cwbDQ_Data data);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

490 Client Access Express Programming


cwbDQ_GetAuthority
Purpose: Get the attribute for the authority that other users will have to the data
queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetAuthority(


cwbDQ_Attr queueAttributes,
unsigned short *authority);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short * authority - output
Pointer to an unsigned short to where the authority will be written. This value
will be one of the following defined types:
CWBDQ_ALL
CWBDQ_EXCLUDE
CWBDQ_CHANGE
CWBDQ_USE
CWBDQ_LIBCRTAUT

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

Chapter 3. Express C/C++ APIs 491


cwbDQ_GetConvert
Purpose: Get the value of the convert flag for a data handle. The convert flag
determines if data sent to and recieved from the host is CCSID converted (for
example, between ASCII and EBCDIC).

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetConvert(


cwbDQ_Data data,
cwb_Boolean *convert);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
cwb_Boolean * convert - output
Pointer to a Boolean where the convert flag will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

492 Client Access Express Programming


cwbDQ_GetData
Purpose: Get the data attribute of the data object.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetData(


cwbDQ_Data data,
unsigned char *dataBuffer);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * data - output
Pointer to the data. The data may contain embedded NULLs, so it is not an
ASCIIZ string.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 493


cwbDQ_GetDataAddr
Purpose: Get the address of the location of the data buffer.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetDataAddr(


cwbDQ_Data data,
unsigned char **dataBuffer);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * * data - output
Pointer to where the buffer address will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
CWBDQ_ADDRESS_NOT_SET
Address not set with cwbDQ_SetDataAddr.

Usage: Use this function to retrieve the address of the location where the data is
stored. The data address must be set with the cwbDQ_SetDataAddr API,
otherwise, the return code CWBDQ_ADDRESS_NOT_SET will be returned.

494 Client Access Express Programming


cwbDQ_GetDataLen
Purpose: Get the data length attribute of the data object. This is the total length of
the data object. To obtain the length of data that was read, use the
cwbDQ_GetRetDataLen API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetDataLen(


cwbDQ_Data data,
unsigned long *dataLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned long * dataLength - output
Pointer to an unsigned long where the length of the data will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 495


cwbDQ_GetDesc
Purpose: Get the attribute for the description of the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetDesc(


cwbDQ_Attr queueAttributes,
char *description);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
char * description - output
Pointer to a 51 character buffer where the description will be written. The
description is an ASCIIZ string.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

496 Client Access Express Programming


cwbDQ_GetForceToStorage
Purpose: Get the attribute for whether records will be forced to auxiliary storage
when they are enqueued.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetForceToStorage(


cwbDQ_Attr queueAttributes,
cwb_Boolean *forceToStorage);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
cwb_Boolean * forceToStorage - output
Pointer to a Boolean where the force-to-storage indicator will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

Chapter 3. Express C/C++ APIs 497


cwbDQ_GetKey
Purpose: Get the key attribute of the data object, previously set by the
cwbDQ_SetKey API. This is the key that is used for writing data to a keyed data
queue. Along with the search order, this key is also used to read data from a keyed
data queue. The key that is associated with the record retrieved can be obtained by
calling the cwbDQ_GetRetKey API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetKey(


cwbDQ_Data data,
unsigned char *key);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * key - output
Pointer to the key. The key may contain embedded NULLS, so it is not an
ASCIIZ string.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

498 Client Access Express Programming


cwbDQ_GetKeyLen
Purpose: Get the key length attribute of the data object.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetKeyLen(


cwbDQ_Data data,
unsigned short *keyLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned short * keyLength - output
Pointer to an unsigned short where the length of the key will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 499


cwbDQ_GetKeySize
Purpose: Get the attribute for the key size in bytes.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetKeySize(


cwbDQ_Attr queueAttributes,
unsigned short *keySize);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short * keySize - output
Pointer to an unsigned short where the key size will written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

500 Client Access Express Programming


cwbDQ_GetLibName
Purpose: Retrieve the library name used with the cwbDQ_Open API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetLibName(


cwbDQ_QueueHandle queueHandle,
char *libName);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
char * libName - output
Pointer to a buffer where the library name will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.

Usage: This function requires that you have previously issued cwbDQ_Open.

Chapter 3. Express C/C++ APIs 501


cwbDQ_GetMaxRecLen
Purpose: Get the maximum record length for the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetMaxRecLen(


cwbDQ_Attr queueAttributes,
unsigned long *maxRecordLength);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a call to cwbDQ_CreateAttr.
unsigned long * maxRecordLength - output
Pointer to an unsigned long where the maximum record length will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

502 Client Access Express Programming


cwbDQ_GetOrder
Purpose: Get the attribute for the queue order. If the order is CWBDQ_SEQ_LIFO,
the last record written is the first record read (Last In First Out). If the order is
CWBDQ_SEQ_FIFO, the first record written is the first record read (First In First
Out). If the order is CWBDQ_SEQ_KEYED, the order in which records are read
from the data queue depends on the value of the search order attribute of the data
object and the key value specified for the cwbDQ_SetKey API. If multiple records
contain the key that satisfies the search order, a FIFO scheme is used among those
records.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetOrder(


cwbDQ_Attr queueAttributes,
unsigned short *order);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short * order - output
Pointer to an unsigned short where the order will be written. Possible values
are:
CWBDQ_SEQ_LIFO
CWBDQ_SEQ_FIFO
CWBDQ_SEQ_KEYED

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

Chapter 3. Express C/C++ APIs 503


cwbDQ_GetQueueAttr
Purpose: Retrieve the attributes of the AS/400 data queue object that is identified
by the specified handle. A handle to the data queue attributes will be returned. The
attributes then can be retrieved individually.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetQueueAttr(


cwbDQ_QueueHandle queueHandle,
cwbDQ_Attr queueAttributes,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
cwbDQ_Attr queueAttributes - input/output
The attribute object. This was the output from the cwbDQ_CreateAttr call. The
attributes will be filled in by this function, and you should call the
cwbDQ_DeleteAttr function to delete this object when you have retrieved the
attributes from it.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.

Usage: This function requires that you have previously issued the following APIs:
cwbDQ_Open or cwbDQ_OpenEx
cwbDQ_CreateAttr

504 Client Access Express Programming


cwbDQ_GetQueueName
Purpose: Retrieve the queue name used with the cwbDQ_Open API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetQueueName(


cwbDQ_QueueHandle queueHandle,
char *queueName);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
char * queueName - output
Pointer to a buffer where the queue name will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.

Usage: This function requires that you have previously issued cwbDQ_Open.

Chapter 3. Express C/C++ APIs 505


cwbDQ_GetRetDataLen
Purpose: Get the length of data that was returned. The returned data length will
be zero until a cwbDQ_Read or cwbDQ_Peek API is called.Then it will have the
length of the data that actually was returned.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetRetDataLen(


cwbDQ_Data data,
unsigned long *retDataLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned long * retDataLength - output
Pointer to an unsigned long where the length of the data returned will be
written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

506 Client Access Express Programming


cwbDQ_GetRetKey
Purpose: Get the returned key of the data object. This is the key that is associated
with the messages that are retrieved from a keyed data queue. If the search order
is a value other than CWBDQ_EQUAL, this key may be different than the key that
is used to retrieve the message.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetRetKey(


cwbDQ_Data data,
unsigned char *key);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * retKey - output
Pointer to the returned key. The key may contain embedded NULLs, so it is
not an ASCIIZ string.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 507


cwbDQ_GetRetKeyLen
Purpose: Get the returned key length attribute of the data object. This is the
length of the key that is returned by the cwbDQ_GetKey API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetRetKeyLen(


cwbDQ_Data data,
unsigned short *retKeyLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned short * retKeyLength - output
Pointer to an unsigned short where the length of the key will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

508 Client Access Express Programming


cwbDQ_GetSearchOrder
Purpose: Get the search order of the open attributes. The search order is used
when reading or peeking a keyed data queue to identify the relationship between
the key of the record to retrieve and the key value specified on the
cwbDQ_SetKey API. If the data queue order attribute is not
CWBDQ_SEQ_KEYED, this property is ignored.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetSearchOrder(


cwbDQ_Data data,
unsigned short *searchOrder);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned short * searchOrder - output
Pointer to an unsigned short where the order will be written. Possible values
are:
CWBDQ_NONE
CWBDQ_EQUAL
CWBDQ_NOT_EQUAL
CWBDQ_GT_OR_EQUAL
CWBDQ_GREATER
CWBDQ_LT_OR_EQUAL
CWBDQ_LESS

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 509


cwbDQ_GetSenderID
Purpose: Get the attribute for whether information about the sender is kept with
each record on the queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetSenderID(


cwbDQ_Attr queueAttributes,
cwb_Boolean *senderID);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes that are returned by a previous call to
cwbDQ_CreateAttr.
cwb_Boolean * senderID - output
Pointer to a Boolean where the sender ID indicator will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

510 Client Access Express Programming


cwbDQ_GetSenderInfo
Purpose: Get the Sender Information attribute of the open attributes. This
information only is available if the senderID attribute of the Data Queue was set
on creation.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetSenderInfo(


cwbDQ_Data data,
unsigned char *senderInfo);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * senderInfo - output
Pointer to a 36 character buffer where the sender information will be written.
This buffer contains:
Job Name (10 bytes)
User Name (10 bytes)
Job ID ( 6 bytes)
User Profile (10 bytes)

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

Chapter 3. Express C/C++ APIs 511


cwbDQ_GetSysName
Purpose: Retrieve the system name that is used with the cwbDQ_Open API.

Syntax:

unsigned int CWB_ENTRY cwbDQ_GetSysName(


cwbDQ_QueueHandle queueHandle,
char *systemName);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
char *systemName - output
Pointer to a buffer where the system name will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.

Usage: This function requires that you previously have issued cwbDQ_Open or
cwbDQ_OpenEx.

512 Client Access Express Programming


cwbDQ_Open
Purpose: Start a connection to the specified data queue. This will start a
conversation with the AS/400 system. If the connection is not successful, a
non-zero handle will be returned.

Note: This API is obsolete. Use “cwbDQ_OpenEx” on page 515.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Open(


char *queue,
char *library,
char *systemName,
cwbDQ_QueueHandle *queueHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
char * library - input
Pointer to the library name that is contained in an ASCIIZ string. If this pointer
is NULL, the library list will be used (set library to ″*LIBL″).
char * systemName - input
Pointer to the system name that is contained in an ASCIIZ string.
cwbDQ_QueueHandle * queueHandle - output
Pointer to a cwbDQ_QueueHandle where the handle will be returned. This
handle should be used in all subsequent calls.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_COMM_VERSION_ERROR
Data Queues will not run with this version of communications.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.

Chapter 3. Express C/C++ APIs 513


CWB_CONFIG_ERROR
A configuration error has occurred.
CWBDQ_BAD_QUEUE_NAME
Queue name is too long.
CWBDQ_BAD_LIBRARY_NAME
Library name is too long.
CWBDQ_BAD_SYSTEM_NAME
System name is too long.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_QUEUE_NOT_FOUND
Queue not found on system.
CWBDQ_NO_AUTHORITY
No authority to queue or library.
CWBDQ_DAMAGED_QUE
Queue is in unusable state.
CWBDQ_CANNOT_CONVERT
Data cannot be converted for this queue.

Usage: None

514 Client Access Express Programming


cwbDQ_OpenEx
Purpose: Start a connection to the specified data queue. This will start a
conversation with the AS/400 system. If the connection is not successful, a
non-zero handle will be returned.

Syntax:

unsigned int CWB_ENTRY cwbDQ_OpenEx(


cwbCO_SysHandle sysHandle
const char *queue,
const char *library,
char *systemName,
cwbDQ_QueueHandle *queueHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbCO_SysHandle sysHandle - input
Handle to a system object.
const char * queue - input
Pointer to the data queue name contained in an ASCIIZ string.
const char * library - input
Pointer to the library name that is contained in an ASCIIZ string. If this pointer
is NULL, the library list will be used (set library to ″*LIBL″).
cwbDQ_QueueHandle * queueHandle - output
Pointer to a cwbDQ_QueueHandle where the handle will be returned. This
handle should be used in all subsequent calls.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_COMM_VERSION_ERROR
Data Queues will not run with this version of communications.
CWB_INVALID_POINTER
Bad or null pointer.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.

Chapter 3. Express C/C++ APIs 515


CWB_CONFIG_ERROR
A configuration error has occurred.
CWBDQ_BAD_QUEUE_NAME
Queue name is too long.
CWBDQ_BAD_LIBRARY_NAME
Library name is too long.
CWBDQ_BAD_SYSTEM_NAME
System name is too long.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_USER_EXIT_ERROR
Error in user exit program.
CWBDQ_LIBRARY_NOT_FOUND
Library not found on system.
CWBDQ_QUEUE_NOT_FOUND
Queue not found on system.
CWBDQ_NO_AUTHORITY
No authority to queue or library.
CWBDQ_DAMAGED_QUE
Queue is in unusable state.
CWBDQ_CANNOT_CONVERT
Data cannot be converted for this queue.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page being used.
CWB_API_ERROR
General API failure.
CWB_INVALID_HANDLE
Invalid system handle.

Usage: This function requires that you previously have issued


cwbCO_CreateSystem.

516 Client Access Express Programming


cwbDQ_Peek
Purpose: Read a record from the AS/400 data queue object that is identified by
the specified handle. When a record is peeked from a data queue, it remains in the
data queue. You may wait for a record if the data queue is empty by specifying a
wait time from 0 to 99,999 or forever (-1). A wait time of zero will return
immediately if there is no data in the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Peek(


cwbDQ_QueueHandle queueHandle,
cwbDQ_Data data,
signed long waitTime,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open API. This
identifies the AS/400 data queue object.
cwbDQ_Data data - input
The data object to be read from the AS/400 data queue.
signed long waitTime - input
Length of time in seconds to wait for data, if the data queue is empty. A wait
time of -1 indicates to wait forever.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_TIME
Invalid wait time.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_INVALID_SEARCH
Invalid search order.
CWBDQ_DATA_TRUNCATED
Data truncated.
CWBDQ_TIMED_OUT
Wait time expired and no data returned.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_QUEUE_DESTROYED
Queue was destroyed.
CWBDQ_CANNOT_CONVERT
Unable to convert data.

Chapter 3. Express C/C++ APIs 517


Usage: This function requires that you have previously issued cwbDQ_Open or
cwbDQ_OpenEx and cwbDQ_CreateData.

518 Client Access Express Programming


cwbDQ_Read
Purpose: Read a record from the AS/400 data queue object that is identified by
the specified handle. When a record is read from a data queue, it is removed from
the data queue. You may wait for a record if the data queue is empty by specifying
a wait time from 0 to 99,999 or forever (-1). A wait time of zero will return
immediately if there is no data in the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Read(


cwbDQ_QueueHandle queueHandle,
cwbDQ_Data data,
long waitTime,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open function.
This identifies the AS/400 data queue object.
cwbDQ_Data data - input
The data object to be read from the AS/400 data queue.
long waitTime - input
Length of time in seconds to wait for data, if the data queue is empty. A wait
time of -1 indicates to wait forever.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_TIME
Invalid wait time.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_INVALID_SEARCH
Invalid search order.
CWBDQ_DATA_TRUNCATED
Data truncated.
CWBDQ_TIMED_OUT
Wait time expired and no data returned.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_QUEUE_DESTROYED
Queue was destroyed.
CWBDQ_CANNOT_CONVERT
Unable to convert data.

Chapter 3. Express C/C++ APIs 519


Usage: This function requires that you have previously issued cwbDQ_Open and
cwbDQ_CreateData.

520 Client Access Express Programming


cwbDQ_SetAuthority
Purpose: Set the attribute for the authority that other users will have to the data
queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetAuthority(


cwbDQ_Attr queueAttributes,
unsigned short authority);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short authority - input
Authority that other users on the AS/400 system have to access the data
queue. Use one of the following defined types for authority:
CWBDQ_ALL
CWBDQ_EXCLUDE
CWBDQ_CHANGE
CWBDQ_USE
CWBDQ_LIBCRTAUT

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_INVALID_AUTHORITY
Invalid queue authority.

Usage: None

Chapter 3. Express C/C++ APIs 521


cwbDQ_SetConvert
Purpose: Set the convert flag. If the flag is set, all data being written will be
converted from PC CCSID (for example, ASCII) to host CCSID (for example,
EBCDIC), and all data being read will be converted from host CCSID (for example,
EBCDIC) to PC CCSID (for example, ASCII). Default behavior is no conversion of
data.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetConvert(


cwbDQ_Data data,
cwb_Boolean convert);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
cwb_Boolean convert - input
Flag indicating if data written to and read from the queue will be CCSID
converted.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.

Usage: None

522 Client Access Express Programming


cwbDQ_SetData
Purpose: Set the data and data length attributes of the data object. The default is
to have no data with zero length. This function will make a copy of the data.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetData(


cwbDQ_Data data,
unsigned char *dataBuffer,
unsigned long dataLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * dataBuffer - input
Pointer to the data. The data may contain embedded NULLS, so it is not an
ASCIIZ string.
unsigned long dataLength - input
Length of the data in bytes.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
CWBDQ_BAD_DATA_LENGTH
Length of data is not correct.

Usage: Use this function if you want to write a small amount of data or you do
not want to manage the memory for the data in your application. Data will be
copied and this may affect your application’s performance.

Chapter 3. Express C/C++ APIs 523


cwbDQ_SetDataAddr
Purpose: Set the data and data length attributes of the data object. The default is
to have no data with zero length. This function will not copy the data.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetDataAddr(


cwbDQ_Data data,
unsigned char *dataBuffer,
unsigned long dataLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * dataBuffer - input
Pointer to the data. The data may contain embedded NULLS, so it is not an
ASCIIZ string.
unsigned long dataLength - input
Length of the data in bytes.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
CWBDQ_BAD_DATA_LENGTH
Length of data is not correct.

Usage: This function is better for large amounts of data, or if you want to manage
memory in your application. Data will not be copied so performance will be
improved.

524 Client Access Express Programming


cwbDQ_SetDesc
Purpose: Set the attribute for the description of the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetDesc(


cwbDQ_Attr queueAttributes,
char *description);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
char * description - input
Pointer to an ASCIIZ string that contains the description for the data queue.
The maximum length for the description is 50 characters.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or null pointer.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_INVALID_QUEUE_TITLE
Queue title is too long.

Usage: None

Chapter 3. Express C/C++ APIs 525


cwbDQ_SetForceToStorage
Purpose: Set the attribute for whether records will be forced to auxiliary storage
when they are enqueued.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetForceToStorage(


cwbDQ_Attr queueAttributes,
cwb_Boolean forceToStorage);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
cwb_Boolean forceToStorage - input
Boolean indicator of whether each record is forced to auxiliary storage when it
is enqueued.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

526 Client Access Express Programming


cwbDQ_SetKey
Purpose: Set the key and key length attributes of the data attributes. This is the
key that is used for writing data to a keyed data queue. In addition to the search
order, this key is used to read data from a keyed data queue. The default is to
have no key with zero length; this is the correct value for a non-keyed (LIFO or
FIFO) data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetKey(


cwbDQ_Data data,
unsigned char *key,
unsigned short keyLength);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned char * key - input
Pointer to the key. The key may contain embedded NULLS, so it is not an
ASCIIZ string.
unsigned short keyLength - input
Length of the key in bytes.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
CWBDQ_BAD_KEY_LENGTH
Length of key is not correct.

Usage: None

Chapter 3. Express C/C++ APIs 527


cwbDQ_SetKeySize
Purpose: Set the attribute for the key size in bytes.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetKeySize(


cwbDQ_Attr queueAttributes,
unsigned short keySize);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short keySize - input
Size in bytes of the key. This value should be zero if the order is LIFO or FIFO,
and between 1 and 256 for KEYED.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_KEY_LENGTH
Invalid key length.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

528 Client Access Express Programming


cwbDQ_SetMaxRecLen
Purpose: Set the maximum record length for the data queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetMaxRecLen(


cwbDQ_Attr queueAttributes,
unsigned long maxRecordLength);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned long maxLength - input
Maximum length for a data queue record. This value must be between 1 and
31744.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_INVALID_QUEUE_LENGTH
Invalid queue record length.

Usage: None

Chapter 3. Express C/C++ APIs 529


cwbDQ_SetOrder
Purpose: Set the attribute for the queue order. If the order is CWBDQ_SEQ_LIFO,
the last record written is the first record read (Last In First Out). If the order is
CWBDQ_SEQ_FIFO, the first record written is the first record read (First In First
Out). If the order is CWBDQ_SEQ_KEYED, the order in which records are read
from the data queue depends on the value of the search order attribute of the data
object and the key value specified for the cwbDQ_SetKey API. If multiple records
contain the key that satisfies the search order, a FIFO scheme is used among those
records.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetOrder(


cwbDQ_Attr queueAttributes,
unsigned short order);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
unsigned short order - input
Order in which new entries will be enqueued. Use one of the following
defined types for order:
CWBDQ_SEQ_LIFO
CWBDQ_SEQ_FIFO
CWBDQ_SEQ_KEYED

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.
CWBDQ_INVALID_ORDER
Invalid queue order.

Usage: None

530 Client Access Express Programming


cwbDQ_SetSearchOrder
Purpose: Set the search order of the open attributes. The default is no search
order. If the cwbDQ_SetKey API is called, the search order is changed to equal.
Use this API to set it to something else. The search order is used when reading or
peeking a keyed data queue to identify the relationship between the key of the
record to retrieve and the key value specified on the cwbDQ_SetKey API. If the
data queue order attribute is not CWBDQ_SEQ_KEYED, this property is ignored.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetSearchOrder(


cwbDQ_Data data,
unsigned short searchOrder);

Parameters:
cwbDQ_Data data - input
Handle of the data object that was returned by a previous call to
cwbDQ_CreateData.
unsigned short searchOrder - input
Order to use when reading from a keyed queue. Possible values are:
CWBDQ_NONE
CWBDQ_EQUAL
CWBDQ_NOT_EQUAL
CWBDQ_GT_OR_EQUAL
CWBDQ_GREATER
CWBDQ_LT_OR_EQUAL
CWBDQ_LESS

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_DATA_HANDLE
Invalid data handle.
CWBDQ_INVALID_SEARCH
Invalid search order.

Usage: None

Chapter 3. Express C/C++ APIs 531


cwbDQ_SetSenderID
Purpose: Set the attribute for whether information about the sender is kept with
each record on the queue.

Syntax:

unsigned int CWB_ENTRY cwbDQ_SetSenderID(


cwbDQ_Attr queueAttributes,
cwb_Boolean senderID);

Parameters:
cwbDQ_Attr queueAttributes - input
Handle of the data queue attributes returned by a previous call to
cwbDQ_CreateAttr.
cwb_Boolean senderID - input
Boolean indicator of whether information about the sender is kept with record
on the queue.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_INVALID_ATTRIBUTE_HANDLE
Invalid attributes handle.

Usage: None

532 Client Access Express Programming


cwbDQ_Write
Purpose: Write a record to the AS/400 data queue object that is identified by the
specified handle. Writing with commit ON means that your application will not
have control returned to it until after the message has been enqueued.

Syntax:

unsigned int CWB_ENTRY cwbDQ_Write(


cwbDQ_QueueHandle queueHandle,
cwbDQ_Data data,
cwb_Boolean commit,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbDQ_QueueHandle queueHandle - input
Handle that was returned by a previous call to the cwbDQ_Open or
cwbDQ_OpenEx functions. This identifies the AS/400 data queue object.
cwbDQ_Data data - input
The data object to be written to the AS/400 data queue.
cwb_Boolean commit - input
Boolean flag indicating if the data should be committed on write.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBDQ_BAD_DATA_LENGTH
Length of data is not correct.
CWBDQ_INVALID_MESSAGE_LENGTH
Invalid message length.
CWBDQ_INVALID_QUEUE_HANDLE
Invalid queue handle.
CWBDQ_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBDQ_CANNOT_CONVERT
Unable to convert data.

Usage: This function requires that you previously have issued cwbDQ_Open or
cwbDQ_OpenEx, and cwbDQ_CreateData.

Chapter 3. Express C/C++ APIs 533


Example: Using Data Queues APIs
// Sample Data Queues application

#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h>

// Include the necessary DQ Classes


#include <stdlib.h>
#include <iostream.h>
#include "cwbdq.h"

/**********************************************************************/

void main()
{

cwbDQ_Attr queueAttributes;
cwbDQ_QueueHandle queueHandle;
cwbDQ_Data queueData;

// Create an attribute object


if ( (queueAttributes = cwbDQ_CreateAttr()) == 0 )
return;

// Set the maximum record length to 100


if ( cwbDQ_SetMaxRecLen(queueAttributes,
100) != 0 )
return;

// Set the order to First-In-First-Out


if (cwbDQ_SetOrder(queueAttributes, CWBDQ_SEQ_FIFO) != 0 )
return;

// Create the data queue DTAQ in library QGPL on system SYS1


if ( cwbDQ_Create(_TEXT("DTAQ"),
_TEXT("QGPL"),
_TEXT("SYSNAMEXXX"),
queueAttributes,
NULL) != 0 )
return;

// Delete the attributes


if ( cwbDQ_DeleteAttr( queueAttributes ) != 0 )
return;

// Open the data queue


if ( cwbDQ_Open(_TEXT("DTAQ"),
_TEXT("QGPL"),
_TEXT("SYSNAMEXXX"),
&queueHandle,
NULL) != 0 )

return;

// Create a data object


if ( (queueData = cwbDQ_CreateData()) == 0 )
return;

// Set the data length and the data


if ( cwbDQ_SetData(queueData, (unsigned char*)"Test Data!", 10) != 0 )
return;

// Write the data to the data queue


if ( cwbDQ_Write(queueHandle, queueData, CWB_TRUE, NULL) != 0 )

534 Client Access Express Programming


return;

// Delete the data object


if ( cwbDQ_DeleteData(queueData) != 0 )
return;

// Close the data queue


if ( cwbDQ_Close(queueHandle) != 0 )
return;

Express data transformation and national language support (NLS) APIs


“Express data transformation APIs”
Client Access Express data transformation application programming
interfaces (APIs) enable your client/server applications to transform
numeric data between AS/400 and PC formats. Transformation may be
required when you send and receive numeric data to and from the AS/400.
Data transformation APIs support transformation of many numeric
formats.
“Express national language support (NLS) APIs” on page 556
Client Access Express national language support APIs enable your
applications to get and save (query and change) the Client Access Express
settings that are relevant to national language support. You can add
convenient functions into your Client Access applications, including the
capability to:
v Select from a list of installed national languages.
v Convert character data from one code page to another. This permits
computers that use different code pages, such as personal computers
and the AS/400, to share information.
v Automatically replace the translatable text (caption and control names)
within dialog boxes. This expands the size of the controls according to
the text that is associated with them. The size of the dialog-box frame
also is adjusted automatically.

Express data transformation APIs

Express data transformation APIs required files:

Header file Import library Dynamic Link Library


cwbdt.h cwbapi.lib cwbdt.dll

Express Toolkit:
The Client Access Express Toolkit provides data transformation
documentation, access to the cwbdt.h header file, and links to sample
programs. To access this information, open the Express Toolkit and select
Data Manipulation —> C/C++ APIs.
Express data transformation APIs topics:
v Express data transformation APIs listing
v “Example: Using data transformation APIs” on page 556
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Chapter 3. Express C/C++ APIs 535


Express data transformation API listing
Note: Express data transformation APIs that accept strings are provided in
Unicode versions. In these APIs, ″ASCII″ is replaced by ″Wide″ (for example,
cwbDT_ASCII11ToBin4 has a Unicode version: cwbDT_Wide11ToBin4).
These APIs are indicated in the table that follows. The Unicode versions
have different syntax, parameters and return values than their ASCII
counterparts.

See “OEM, ANSI, and Unicode considerations” on page 10 and the cwbdt.h
header file for details.

Express data transformation API Unicode version


cwbDT_ASCII11ToBin4 cwbDT_Wide11ToBin4
cwbDT_ASCII6ToBin2 cwbDT_Wide6ToBin2
cwbDT_ASCIIPackedToPacked None
cwbDT_ASCIIToHex cwbDT_WideToHex
cwbDT_ASCIIToPacked cwbDT_WideToPacked
cwbDT_ASCIIToZoned cwbDT_WideToZoned
cwbDT_ASCIIZonedToZoned None
cwbDT_Bin2ToASCII6 cwbDT_Bin2ToWide6
cwbDT_Bin2ToBin2 None
cwbDT_Bin4ToASCII11 cwbDT_Bin4ToWide11
cwbDT_Bin4ToBin4 None
cwbDT_EBCDICToEBCDIC None
cwbDT_HexToASCII cwbDT_HexToWide
cwbDT_PackedToASCII cwbDT_PackedToWide
cwbDT_PackedToASCIIPacked None
cwbDT_PackedToPacked None
cwbDT_ZonedToASCII cwbDT_ZonedToWide
cwbDT_ZonedToASCIIZoned None
cwbDT_ZonedToZoned None

536 Client Access Express Programming


cwbDT_ASCII11ToBin4:

Purpose: Translates (exactly) 11 ASCII numeric characters to a 4-byte integer stored


most significant byte first. (The source string is not expected to be
zero-terminated.) This function can be used for translating ASCII numeric data to
the AS/400 integer format.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCII11ToBin4(


char *target,
char *source);

Parameters:
char * target - output
Pointer to the target (4 byte integer).
char * source - input
Pointer to the source (11 byte ASCII).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
CWB_BUFFER_OVERFLOW
Overflow error.
other Offset of the first untranslated character plus one.

Usage: The target data will be stored with the Most Significant Byte first. This is
the format that the AS/400 uses and is the opposite of the format that is used by
the Intel x86 processors. Valid formats for the ASCII source data are as follows:
[blankspaces][sign][blankspaces][digits] or
[sign][blankspaces][digits][blankspaces]

Examples:
" + 123"
"- 123 "
" +123 "
" 123"
" -123"
"+123 "

Chapter 3. Express C/C++ APIs 537


cwbDT_ASCII6ToBin2:

Purpose: Translates (exactly) 6 ASCII numeric characters to a 2-byte integer stored


most significant byte first. (The source string is not expected to be
zero-terminated.) This function can be used for translating ASCII numeric data to
the AS/400 integer format.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCII6ToBin2(


char *target,
char *source);

Parameters:
char * target - output
Pointer to the target (2 byte integer).
char * source - input
Pointer to the source (6 byte ASCII).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
CWB_BUFFER_OVERFLOW
Overflow error.
other Offset of the first untranslated character plus one.

Usage: The target data will be stored with the Most Significant Byte first. This is
the format that the AS/400 uses and is the opposite of the format that is used by
Intel x86 processors. Valid formats for the ASCII source data are as follows:
[blankspaces][sign][blankspaces][digits] or
[sign][blankspaces][digits][blankspaces]

Examples:
" + 123"
"- 123 "
" +123 "
" 123"
" -123"
"+123 "

538 Client Access Express Programming


cwbDT_ASCIIPackedToPacked:

Purpose: Translates data from ASCII packed format to packed decimal. This
function can be used for translating data from ASCII files to the AS/400 system
format.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCIIPackedToPacked(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. This function checks that each half-byte of the packed decimal data is
in the range of 0 to 9. The only exception is the last half-byte which contains the
sign indicator (which can be 0x3 or 0xb).

Chapter 3. Express C/C++ APIs 539


cwbDT_ASCIIToHex:

Purpose: Translates data from ASCII (hex representation) to binary. One byte is
stored in the target for each two bytes in the source.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCIIToHex(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source (ASCII hex) data.
unsigned long length - input
Number of bytes of source data to translate/2.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: For ’length’ bytes of source data ’length’/2 bytes of target data will be
stored. The caller must make sure that there is adequate space to hold the target
information.

540 Client Access Express Programming


cwbDT_ASCIIToPacked:

Purpose: Translates ASCII numeric data to packed decimal format. This function
can be used for translating ASCII text data for use on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCIIToPacked(


char *target,
char *source,
unsigned long length,
unsigned long decimalPosition);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data. Must be zero terminated.
unsigned long length - input
Number of bytes of target data to translate.
unsigned long decimalPosition - input
Position of the decimal point.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
CWB_BUFFER_OVERFLOW
Overflow error.
CWB_NOT_ENOUGH_MEMORY
Unable to allocate temporary memory.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. The sign half-byte will be set to 0xd to indicate a negative number
and hex 0xc to indicate a positive number. 0 <= decimalPosition < (length * 2).
Valid formats for the ASCII numeric data are as follows:
[blankspaces][sign][blankspaces][digits] or
[sign][blankspaces][digits][blankspaces] or
[sign][digits][.digits][blankspaces] or
[blankspaces][sign][digits][.digits][blankspaces]

Examples:
" + 123\0"
"- 123 \0"
" +123 \0"
" 123\0"
" -12.3\0"
"+1.23 \0"

Chapter 3. Express C/C++ APIs 541


cwbDT_ASCIIToZoned:

Purpose: Translates ASCII numeric data to EBCDIC zoned decimal format. This
function can be used for translating ASCII text data for for use on the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCIIToZoned(


char *target,
char *source,
unsigned long length,
unsigned long decimalPosition);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data. Must be zero terminated.
unsigned long length - input
Number of bytes of target data to translate.
unsigned long decimalPosition - input
Position of the decimal point.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
CWB_BUFFER_OVERFLOW
Overflow error.
CWB_NOT_ENOUGH_MEMORY
Unable to allocate temporary memory.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the
information. The sign half-byte will be set to 0xd to indicate a negative number
and hex 0xc to indicate a positive number. 0 <= decimalPosition <= length. Valid
formats for the ASCII numeric data are as follows:
[blankspaces][sign][blankspaces][digits] or
[sign][blankspaces][digits][blankspaces] or
[sign][digits][.digits][blankspaces] or
[blankspaces][sign][digits][.digits][blankspaces]

Examples:
" + 123\0"
"- 123 \0"
" +123 \0"
" 123\0"
" -12.3\0"
"+1.23 \0"

542 Client Access Express Programming


cwbDT_ASCIIZonedToZoned:

Purpose: Translates data from ASCII zoned decimal format to EBCDIC zoned
decimal. This function can be used for translating data from ASCII files for use on
the AS/400.

Syntax:

unsigned int CWB_ENTRY cwbDT_ASCIIZonedToZoned(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The left half of each byte (0x3) in the ASCII zoned decimal format will be
converted to 0xf in the left half-byte of the EBCDIC zoned data except for the last
byte (sign). This function checks that the left half of each byte in the ASCII zoned
decimal data must be 0x3 except for the last byte. The high half of the last byte
must be 0x3 or 0xb. The right half of each byte in the ASCII zoned decimal data
must be in the range 0-9.

Chapter 3. Express C/C++ APIs 543


cwbDT_Bin2ToASCII6:

Purpose: Translates a 2-byte integer stored most significant byte first to (exactly) 6
ASCII numeric characters. (The target will not be zero terminated.) This function
can be used for translating numeric data from an AS/400 to ASCII.

Syntax:

unsigned int CWB_ENTRY cwbDT_Bin2ToASCII6(


char *target,
char *source);

Parameters:
char * target - output
Pointer to the target (6 byte) area.
char * source - input
Pointer to the source (2 byte integer).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.

Usage: The source data is assumed to be stored with the Most significant Byte
first. This is the format that the AS/400 uses and is the opposite of the format used
by the Intel x86 processes.

544 Client Access Express Programming


cwbDT_Bin2ToBin2:

Purpose: Reverses the order of bytes in a 2-byte integer. This function can be used
for translating a 2-byte integer to or from the AS/400 format.

Syntax:

unsigned int CWB_ENTRY cwbDT_Bin2ToBin2(


char *target,
char *source);

Parameters:
char * target - output
Pointer to the target (2 byte integer).
char * source - input
Pointer to the source (2 byte integer).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.

Usage: The source data and the target data must not overlap. The following
example shows the result of the translation:
Source data: 0x1234
Target data: 0x3412

Chapter 3. Express C/C++ APIs 545


cwbDT_Bin4ToASCII11:

Purpose: Translates a 4-byte integer stored most significant byte first to (exactly) 11
ASCII numeric characters. (The target will not be zero terminated.) This function
can be used for translating numeric data from an AS/400 to ASCII.

Syntax:

unsigned int CWB_ENTRY cwbDT_Bin4ToASCII11(


char *target,
char *source );

Parameters:
char * target - output
Pointer to the target (11 byte) area.
char * source - input
Pointer to the source (4 byte integer).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.

Usage: The source data is assumed to be stored with the Most Significant Byte
first. This is the format that the AS/400 uses and is the opposite of the format used
by the Intel x86 processors.

546 Client Access Express Programming


cwbDT_Bin4ToBin4:

Purpose: Reverses the order of bytes in a 4-byte integer. This function can be used
for translating a 4-byte integer to or from the AS/400 format.

Syntax:

unsigned int CWB_ENTRY cwbDT_Bin4ToBin4(


char *target,
char *source);

Parameters:
char * target - output
Pointer to the target (4 byte integer).
char * source - input
Pointer to the source (4 byte integer).

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.

Usage: The source data and the target data must not overlap. The following
example shows the result of the translation:
Source data: 0x12345678
Target data: 0x78563412

Chapter 3. Express C/C++ APIs 547


cwbDT_EBCDICToEBCDIC:

Purpose: ’Translates’ (copies unless character value less than 0x40 is encountered)
EBCDIC data to EBCDIC.

Syntax:

unsigned int CWB_ENTRY cwbDT_EBCDICToEBCDIC(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of target data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information.

548 Client Access Express Programming


cwbDT_HexToASCII:

Purpose: Translates binary data to the ASCII hex representation. Two ASCII
characters are stored in the target for each byte of source data.

Syntax:

unsigned int CWB_ENTRY cwbDT_HexToASCII(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target (ASCII hex) data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.

Usage: For ’length’ bytes of source data ’length’*2 bytes of target data will be
stored. The caller must make sure that there is adequate space to hold the target
information.

Chapter 3. Express C/C++ APIs 549


cwbDT_PackedToASCII:

Purpose: Translates data from packed decimal format to ASCII numeric data. This
function can be used for translating data from the the AS/400 for use in ASCII text
format.

Syntax:

unsigned int CWB_ENTRY cwbDT_PackedToASCII(


char *target,
char *source,
unsigned long length,
unsigned long decimalPosition);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.
unsigned long decimalPosition - input
Position of the decimal point.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. This function checks that each half-byte of the packed decimal data is
in the range of 0 to 9. The only exception is the last half-byte which contains the
sign indicator. 0 <= decimalPosition < (length * 2).

550 Client Access Express Programming


cwbDT_PackedToASCIIPacked:

Purpose: Translates data from packed decimal format to ASCII packed format. This
function can be used for translating data from the AS/400 for use in ASCII format.

Syntax:

unsigned int CWB_ENTRY cwbDT_PackedToASCIIPacked(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. This function checks that each half-byte of the packed decimal data is
in the range of 0 to 9. The only exception is the last half-byte which contains the
sign indicator (which can be 0-9, 0xd, or 0xb).

Chapter 3. Express C/C++ APIs 551


cwbDT_PackedToPacked:

Purpose: Translates packed decimal data to packed decimal. This function can be
used for transferring data from the AS/400 system to no-conversion files and back.

Syntax:

unsigned int CWB_ENTRY cwbDT_PackedToPacked(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. This function checks that each half-byte of the packed decimal data is
in the range of 0 to 9. The only exception is the last half-byte which contains the
sign indicator.

552 Client Access Express Programming


cwbDT_ZonedToASCII:

Purpose: Translates EBCDIC zoned decimal data to ASCII numeric format. This
function can be used for translating data from the AS/400 for use in ASCII text
format.

Syntax:

unsigned int CWB_ENTRY cwbDT_ZonedToASCII(


char *target,
char *source,
unsigned long length,
unsigned long decimalPosition);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.
unsigned long decimalPosition - input
Position of the decimal point.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
CWB_BUFFER_OVERFLOW
Overflow error.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. The high half of the last byte of the zoned data indicates the sign of
the number. If the high half-byte is 0xb or 0xd, then a negative number is
indicated. Any other value indicates a positive number. This function checks that
the high half of each byte of zoned data must be 0xf except for the last byte. The
low half of each byte of zoned data must be in the range 0-9. 0 <= decimalPosition
< length.

Chapter 3. Express C/C++ APIs 553


cwbDT_ZonedToASCIIZoned:

Purpose: Translates data from EBCDIC zoned decimal format to ASCII zoned
decimal format. This function can be used for translating data from the AS/400 for
use in ASCII files.

Syntax:

unsigned int CWB_ENTRY cwbDT_ZonedToASCIIZoned(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. The left half-byte (0xf) in the EBCDIC zoned decimal data will be
converted to 0x3 in the left half-byte of the ASCII zoned decimal data except for
the last byte (sign). The high half of the last byte of the EBCDIC zoned decimal
data indicates the sign of the number. If the high half-byte is 0xb or 0xb then a
negative number is indicated, any other value indicates a positive number. This
function checks that the high half of each byte of EBCDIC zoned decimal data
must be 0xf except for the last byte. The low half of each byte of EBCDIC zoned
decimal data must be in the range 0-9.

554 Client Access Express Programming


cwbDT_ZonedToZoned:

Purpose: Translates data from zoned decimal format to zoned decimal. This
function can be used for translating data from the AS/400 for use in no-conversion
files and vice-versa.

Syntax:

unsigned int CWB_ENTRY cwbDT_ZonedToZoned(


char *target,
char *source,
unsigned long length);

Parameters:
char * target - output
Pointer to the target data.
char * source - input
Pointer to the source data.
unsigned long length - input
Number of bytes of source data to translate.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWB_INVALID_POINTER
NULL pointer was passed by caller.
other Offset of the first untranslated character plus one.

Usage: The caller must make sure that there is adequate space to hold the target
information. The high half of the last byte of the zoned data indicates the sign of
the number. If the high half-byte is 0xb or 0xb then a number is indicated, any
other value indicates a positive number. This function checks that the high half of
each byte of zoned data must be 0xf except for the last byte. The low half of each
byte of zoned data must be in the range 0-9.

Chapter 3. Express C/C++ APIs 555


Example: Using data transformation APIs
/*******************************************************************/
/* Sample Data Transform Program using cwbDT_Bin4ToBin4 to reverse */
/* the order of bytes in a 4-byte integer. */
/*******************************************************************/

#include <iostream.h>
#include "cwbdt.h"

void main()
{
unsigned int returnCode;
long source,
target;

cout << "Enter source number:\n";

while (cin >> source) {


cout << "Source in Dec = " << dec << source;
cout << "\nSource in Hex = " << hex << source << '\n';
if (((returnCode = cwbDT_Bin4ToBin4((char *)&target,(char *)&source)) == CWB_OK)) {
cout << "Target in Dec = " << dec << target;
cout << "\nTarget in Hex = " << hex << target << '\n';
} else {
cout << "Conversion failed, Return code = " << returnCode << '\n' ;
}; /* endif */
cout << "\nEnter source number:\n";

}; /* endwhile */

Express national language support (NLS) APIs


AS/400 business computing systems support many national languages, through
national language support (NLS). NLS allows users to work on an AS/400 system
in the language of their choice. The AS/400 system also ensures that the data that
is sent to and received from the system appears in the form and order that is
expected. By supporting many different languages, the system operates as
intended, from both a linguistic and a cultural point of view.

All AS/400 systems use a common set of program code, regardless of which
language you use on the system. For example, the program code on a U.S. English
AS/400 system and the program code on a Spanish AS/400 system are identical.
Different sets of textual data are used, however, for different languages. Textual
data is a collective term for menus, displays, lists, prompts, options, on-line help
information, and messages. This means that you see Help for the description of the
function key for on-line help information on a U.S. English system, while you see
Ayuda on a Spanish system. Using the same program code with different sets of
textual data allows the AS/400 system to support more than one language on a
single system.

Note: It is essential to build national language support considerations into the


design of the program right from the start. It is much harder to add NLS or
DBCS support after a program has been designed or coded.

556 Client Access Express Programming


Express NLS APIs required files:

NLS API type Header file Import library Dynamic Link


Library
General cwbnl.h cwbapi.lib cwbnl.dll
Conversion cwbnlcnv.h cwbnl1.dll
Dialog-box cwbnldlg.h cwbnldlg.dll

Express Toolkit:
The Client Access Express Toolkit provides NLS documentation, access to
the NLS APIs header files, and links to sample programs. To access this
information, open the Express Toolkit and select Data Manipulation —>
C/C++ APIs.
Express NLS APIs topics:
v “Coded character sets”
v Express NLS APIs listing
v “Example: Express NLS APIs” on page 587
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Coded character sets


Graphic characters are printable or displayable symbols, such as letters, numbers,
and punctuation marks. A collection of graphic characters is called a
graphic-character set, and often simply a character set. Each language requires its own
graphic-character set to be printed or displayed properly. Characters are encoded
according to a code page, which is a table that assigns graphic and control
characters to specific values called code points.

Code pages are classified into many types according to the encoding scheme. Two
important encoding schemes for Client Access are the Host and PC code pages.
Unicode also is becoming an important encoding scheme. Unicode is a 16-bit
worldwide character encoding scheme that is gaining popularity on both the Host
and the personal computer.
v Host code pages are encoded in accordance with IBM Standard of Extended
BCD Interchange Code (EBCDIC) and usually used by S/390 and AS/400.
v PC Code pages are encoded based on ANSI X3.4, ASCII and usually used by
IBM Personal Computers.

Express NLS APIs listing


The Client Access Express national language support application programming
interfaces (APIs) are listed in alphabetical order. They provide necessary
information for their use. They are grouped into three functional categories:
v Express general national language support APIs
v Express conversion national language support APIs
v Express dialog-box national language support APIs

Express general NLS APIs list: Client Access Express is translated into many
languages. One or more of these languages can be installed on the personal
computer. The following Express general NLS APIs allow an application to:
v Get a list of installed languages
v Get the current language setting
v Save the language setting
cwbNL_FindFirstLang

Chapter 3. Express C/C++ APIs 557


cwbNL_FindNextLang
cwbNL_GetLang
cwbNL_GetLangName
cwbNL_GetLangPath
cwbNL_SaveLang

558 Client Access Express Programming


cwbNL_FindFirstLang:

Purpose: Returns the first available language.

Syntax:

unsigned int CWB_ENTRY cwbNL_FindFirstLang(


char *mriBasePath,
char *resultPtr,
unsigned short resultLen,
unsigned short *requiredLen,
unsigned long *searchHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
char * mriBasePath - input
Pointer to the mriBasePath, e.g. C:\Program Files\IBM\ClientAccess/400 If
NULL, the mriBasePath of the ClientAccess/400 product is used.
char * resultPtr - output
Pointer to the buffer to contain the result.
unsigned short resultLen - input
Length of the result buffer. Recommended size is CWBNL_MAX_LANG_SIZE.
unsigned short * requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
unsigned long * searchHandle - output
Search handle to be passed on subsequent calls to cwbNL_FindNextLang.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_FILE_NOT_FOUND
File not found.
CWB_PATH_NOT_FOUND
Path not found.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.

Usage: The result buffer will contain a language.

Chapter 3. Express C/C++ APIs 559


cwbNL_FindNextLang:

Purpose: Returns the next available language.

Syntax:

unsigned int CWB_ENTRY cwbNL_FindNextLang(


char *resultPtr,
unsigned short resultLen,
unsigned short *requiredLen,
unsigned long *searchHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
char * resultPtr - output
Pointer to the buffer to contain the result.
unsigned short resultLen - input
Length of the result buffer. Recommended size is CWBNL_MAX_LANG_SIZE.
unsigned short * requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
unsigned long * searchHandle - output
Search handle to be passed on subsequent calls to cwbNL_FindNextLang.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API. The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NO_MORE_FILES
No more files are found.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.

Usage: The result buffer will contain a language.

560 Client Access Express Programming


cwbNL_GetLang:

Purpose: Get the current language setting.

Syntax:

unsigned int CWB_ENTRY cwbNL_GetLang(


char *mriBasePath,
char *resultPtr,
unsigned short resultLen,
unsigned short *requiredLen,
cwbSV_ErrHandle errorHandle);

Parameters:
char * mriBasePath - input
Pointer to the mriBasePath, e.g. C:\Program Files\IBM\ClientAccess/400. If
NULL, the mriBasePath of the ClientAccess/400 product is used.
char * resultPtr - output
Pointer to the buffer to contain the result.
unsigned short resultLen - input
Length of the result buffer. Recommended size is CWBNL_MAX_LANG_SIZE.
unsigned short * requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API. The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Buffer too small to contain result.

Usage: The result buffer will contain the name of the language subdirectory. This
language subdirectory contains the language-specific files. This language
subdirectory name also can be passed to cwbNL_GetLangName.

Chapter 3. Express C/C++ APIs 561


cwbNL_GetLangName:

Purpose: Return the descriptive name of a language setting.

Syntax:

unsigned int CWB_ENTRY cwbNL_GetLangName(


char *lang,
char *resultPtr,
unsigned short resultLen,
unsigned short *requiredLen,
cwbSV_ErrHandle errorHandle);

Parameters:
char * lang - input
Address of the ASCIIZ string representing the language.
char * resultPtr - output
Pointer to the buffer to contain the result.
unsigned short resultLen - input
Length of the result buffer. Recommended size is CWBNL_MAX_NAME_SIZE.
unsigned short * requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API. The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.

Usage: The language must be a value returned from one of the following APIs:
cwbNL_GetLang
cwbNL_FindFirstLang
cwbNL_FindNextLang

562 Client Access Express Programming


cwbNL_GetLangPath:

Purpose: Return the complete path for language files.

Syntax:

unsigned int CWB_ENTRY cwbNL_GetLangPath(


char *mriBasePath,
char *resultPtr,
unsigned short resultLen,
unsigned short *requiredLen,
cwbSV_ErrHandle errorHandle);

Parameters:
char * mriBasePath - input
Pointer to the mriBasePath, for example C:\Program
Files\IBM\ClientAccess/400. If NULL, the mriBasePath of the
ClientAccess/400 product is used.
char * resultPtr - output
Pointer to the buffer to contain the result.
unsigned short resultLen - input
Length of the result buffer. Recommended size is CWBNL_MAX_PATH_SIZE.
unsigned short * requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API. The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_PATH_NOT_FOUND
Path not found.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.

Usage: The result buffer will contain the complete path of the language
subdirectory. Language files should be loaded from this path.

Chapter 3. Express C/C++ APIs 563


cwbNL_SaveLang:

Purpose: Save the language setting in the product registry.

Syntax:

unsigned int CWB_ENTRY cwbNL_SaveLang(


char *lang,
cwbSV_ErrHandle errorHandle);

Parameters:
char * lang - input
Address of the ASCIIZ string representing the language.
cwbSV_ErrHandle errorHandle - input
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle() API. The messages may be retrieved through the
cwbSV_GetErrText() API. If the parameter is set to zero, no messages will be
retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: The language must be a value returned from one of the following APIs:
cwbNL_GetLang
cwbNL_FindFirstLang
cwbNL_FindNextLang

The following APIs are affected by this call:


cwbNL_GetLang
cwbNL_GetLangPath

564 Client Access Express Programming


Express conversion NLS APIs list: The following Express conversion NLS APIs
allow applications to:
v Convert character data from one code page to another
v Determine the current code page setting
v Determine the last CCSID setting
v Convert code page values to and from code character set identifiers (CCSID)
cwbNL_CCSIDToCodePage
cwbNL_CodePageToCCSID
cwbNL_Convert
cwbNL_ConvertCodePages
cwbNL_CreateConverter
cwbNL_DeleteConverter
cwbNL_GetCodePage
cwbNL_GetANSICodePage
cwbNL_GetHostCCSID

Chapter 3. Express C/C++ APIs 565


cwbNL_CCSIDToCodePage:

Purpose: Map CCSIDs to code pages.

Syntax:

unsigned int CWB_ENTRY cwbNL_CCSIDToCodePage(


unsigned long CCSID,
unsigned long *codePage,
cwbSV_ErrHandle errorHandle);

Parameters:
unsigned long CCSID - input
CCSID to convert to a code page.
unsigned long * codePage - output
The resulting code page.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: None

566 Client Access Express Programming


cwbNL_CodePageToCCSID:

Purpose: Map code pages to CCSIDs.

Syntax:

unsigned int CWB_ENTRY cwbNL_CodePageToCCSID(


unsigned long codePage,
unsigned long *CCSID,
cwbSV_ErrHandle errorHandle);

Parameters:
unsigned long codePage - input
Code page to convert to a CCSID.
unsigned long * CCSID - output
The resulting CCSID.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: None

Chapter 3. Express C/C++ APIs 567


cwbNL_Convert:

Purpose: Convert strings by using a previously opened converter.

Syntax:

unsigned int CWB_ENTRY cwbNL_Convert(


cwbNL_Converter theConverter,
unsigned long sourceLength,
unsigned long targetLength,
char *sourceBuffer,
char *targetBuffer,
unsigned long *numberOfErrors,
unsigned long *firstErrorIndex,
unsigned long *requiredLen,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbNL_Converter theConverter - output
Handle to the previously opened converter.
unsigned long sourceLength - input
Length of the source buffer.
unsigned long targetLength - input
Length of the target buffer. If converting from an ASCII code page that
contains DBCS characters, note that the resulting data could contain shift-out
and shift-in bytes. Therefore, the targetBuffer may need to be larger than the
sourceBuffer.
char *sourceBuffer - input
Buffer containing the data to convert.
char *targetBuffer - output
Buffer to contain the converted data.
unsigned long *numberOfErrors - output
Contains the number of characters that could not be converted properly.
unsigned long *firstErrorIndex - output
Contains the offset of the first character in the source buffer that could not be
converted properly.
unsigned long *requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.

568 Client Access Express Programming


CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.

Usage: None

Chapter 3. Express C/C++ APIs 569


cwbNL_ConvertCodePages:

Purpose: Convert strings from one code page to another. This API combines the
following three converter APIs for the default conversion:
v cwbNL_CreateConverter
v cwbNL_Convert
v cwbNL_DeleteConverter

Syntax:

unsigned int CWB_ENTRY cwbNL_ConvertCodePages(


unsigned long sourceCodePage,
unsigned long targetCodePage,
unsigned long sourceLength,
unsigned long targetLength,
char *sourceBuffer,
char *targetBuffer,
unsigned long *numberOfErrors,
unsigned long *positionOfFirstError,
unsigned long *requiredLen,
cwbSV_ErrHandle errorHandle);

Parameters:
unsigned long sourceCodePage - input
Code page of the data in the source buffer.
unsigned long targetCodePage - input
Code page to which the data should be converted.
unsigned long sourceLength - input.
Length of the source buffer
unsigned long targetLength - input.
Length of the target buffer
char *sourceBuffer - input
Buffer containing the data to convert.
char *targetBuffer - output
Buffer to contain the converted data.
unsigned long *numberOfErrors - output
Contains the number of characters that could not be converted properly.
unsigned long *positionOfFirstError - output
Contains the offset of the first character in the source buffer that could not be
converted properly.
unsigned long *requiredLen - output
Actual length of the result. If requiredLen > resultLen, the return value will be
CWB_BUFFER_OVERFLOW.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.

570 Client Access Express Programming


CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWBNL_ERR_CNV_UNSUPPORTED
An error occurred while attempting to convert the characters. No
conversion was done. The most common reason is that a conversion table
is missing. Conversion tables are either installed with Client Access
Express, or retrieved from the default AS/400 system when needed. There
may have been some problem communicating with the default AS/400
system.
CWBNL_ERR_CNV_ERR_STATUS
This return code is used to indicate that while the requested conversion is
supported, and the conversion completed, there were some characters that
did not convert properly. Either the source buffer contained null characters,
or the characters do not exist in the target code page. Applications can
choose to ignore this return code or treat it as a warning.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: The following values may be specified on the sourceCodePage and the
targetCodePage parameters:

Value Meaning
CWBNL_CP_UNICODE_F200 UCS2 Version 1.1 UNICODE
CWBNL_CP_UNICODE UCS2 Current Version UNICODE
CWBNL_CP_AS400 AS/400 host code page
CWBNL_CP_CLIENT_OEM OEM client code page
CWBNL_CP_CLIENT_ANSI ANSI client code page
CWBNL_CP_CLIENT Generic client code page. Default is
CWBNL_CP_CLIENT_OEM. CWBNL_CP_CLIENT is set to
CWBNL_CP_CLIENT_ANSI when CWB_ANSI is defined, to
CWBNL_CP_CLIENT_UNICODE when CWB_UNICODE is
defined and to CWBNL_CP_CLIENT_OEM when
CWB_OEM is defined.

Chapter 3. Express C/C++ APIs 571


cwbNL_CreateConverter:

Purpose: Create a cwbNL_Converter to be used on subsequent calls to


cwbNL_Convert().

Syntax:

unsigned int CWB_ENTRY cwbNL_CreateConverter(


unsigned long sourceCodePage,
unsigned long targetCodePage,
cwbNL_Converter *theConverter,
cwbSV_ErrHandle errorHandle,
unsigned long shiftInShiftOutStatus,
unsigned long padLength,
char *pad);

Parameters:
unsigned long sourceCodePage - input
Code page of the source data.
unsigned long targetCodePage - input
Code page to which the data should be converted.
cwbNL_Converter * theConverter - output
The newly created converter.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.
unsigned long shiftInShiftOutStatus - input
Indicates whether the shift-in and shift-out bytes are part of the input or
output data. 0 - False, no shift-in and shift-out bytes are part of the data string.
1 - True, shift-in and shift-out characters are part of the data string.
unsigned long padLength - input
Length of pad characters. 0 - No pad characters for this conversion request 1 -
1 byte of pad character. This is valid only if the target code page is either SBCS
or DBCS code page 2 - 2 bytes of pad characters. This is valid only if the code
page is not a single-byte code page.
char * pad - input
The character or characters for padding.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWBNL_ERR_CNV_UNSUPPORTED
An error occurred while attempting to convert the characters. No
conversion was done. The most common reason is that a conversion table
is missing. Conversion tables are either installed with Client Access

572 Client Access Express Programming


Express, or retrieved from the default AS/400 system when needed. There
may have been some problem communicating with the default AS/400
system.
CWBNL_ERR_CNV_ERR_STATUS
This return code is used to indicate that while the requested conversion is
supported, and the conversion completed, there were some characters that
did not convert properly. Either the source buffer contained null characters,
or the characters do not exist in the target code page. Applications can
choose to ignore this return code or treat it as a warning.
CWBNL_ERR_CNV_INVALID_SISO_STATUS
Invalid SISO parameter.
CWBNL_ERR_CNV_INVALID_PAD_LENGTH
Invalid Pad Length parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: The following values may be specified on the sourceCodePage and the
targetCodePage parameters:

Value Meaning
CWBNL_CP_UNICODE_F200 UCS2 Version 1.1 UNICODE
CWBNL_CP_UNICODE UCS2 Current Version UNICODE
CWBNL_CP_AS400 AS/400 host code page
CWBNL_CP_CLIENT_OEM OEM client code page
CWBNL_CP_CLIENT_ANSI ANSI client code page
CWBNL_CP_CLIENT Generic client code page. Default is
CWBNL_CP_CLIENT_OEM. CWBNL_CP_CLIENT is set to
CWBNL_CP_CLIENT_ANSI when CWB_ANSI is defined, to
CWBNL_CP_CLIENT_UNICODE when CWB_UNICODE is
defined and to CWBNL_CP_CLIENT_OEM when
CWB_OEM is defined.

Instead of calling cwbNL_ConvertCodePages multiple times with the same code


pages:
cwbNL_ConvertCodePages(850, 500, ...);
cwbNL_ConvertCodePages(850, 500, ...);
cwbNL_ConvertCodePages(850, 500, ...);

It is more efficient to create a converter and use it multiple times:


cwbNL_CreateConverter(850, 500, &conv, ...);
cwbNL_Convert(conv, ...);
cwbNL_Convert(conv, ...);
cwbNL_Convert(conv, ...);
cwbNL_DeleteConverter(conv, ...);

Chapter 3. Express C/C++ APIs 573


cwbNL_DeleteConverter:

Purpose: Delete a cwbNL_Converter.

Syntax:

unsigned int CWB_ENTRY cwbNL_DeleteConverter(


cwbNL_Converter theConverter,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbNL_Converter theConverter - input
A previously created converter.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle0 API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Invalid handle.

Usage: None

574 Client Access Express Programming


cwbNL_GetCodePage:

Purpose: Get the current code page of the client system.

Syntax:

unsigned int CWB_ENTRY cwbNL_GetCodePage(


unsigned long *codePage,
cwbSV_ErrHandle errorHandle);

Parameters:
unsigned long * codePage - output
Returns the current code page of the client system or the OEM code page
character conversion override value, if one is specified on the Language tab of
the Client Access Properties dialog.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: None

Chapter 3. Express C/C++ APIs 575


cwbNL_GetANSICodePage:

Purpose: Get the current ANSI code page of the client system.

Syntax:

unsigned int CWB_ENTRY cwbNL_GetANSICodePage(


unsigned long *codePage,
cwbSV_ErrHandle errorHandle);

Parameters:
unsigned long * codePage - output
Returns the current ANSI code page of the client system or the ANSI code
page character conversion override value, if one is specified on the Language
tab of the Client Access Properties dialog.
cwbSV_ErrHandle errorHandle - output
Handle to an error object. Any returned messages will be written to this object.
It is created with the cwbSV_CreateErrHandle API. The messages may be
retrieved with the cwbSV_GetErrText API. If the parameter is set to zero, no
messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Invalid handle.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: None

576 Client Access Express Programming


cwbNL_GetHostCCSID:

Purpose: Returns the associated CCSID of a given host system or the managing
system or the EBCDIC code page character conversion override value, if one is
specified on the Language tab of the Client Access Properties dialog.

Syntax:

unsigned long CWB_ENTRY cwbNL_GetHostCCSID(


char * system,
unsigned long * CCSID );

Parameters:
char * system - input
The name of the host system. If NULL, the managing system is used.
unsigned * CCSID - output
Length of the result buffer.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWBNL_DEFAULT_HOST_CCSID_USED
Host CCSID 500 is returned

Usage: This API does not make or require an active connection to the host system
to retrieve the associated CCSID value. However, it does depend on a prior
successful connection to the host system. If no prior successful connection was
made to the host system, the API determines the most appropriate associated host
CCSID by using an internal mapping table.

Chapter 3. Express C/C++ APIs 577


Express dialog-box NLS API list: Express dialog-box NLS APIs are interfaces that
are used to manipulate the translatable text within dialog boxes.

The following Express dialog-box NLS APIs allow applications to:


v Replace translatable text with a dialog box
v Expand dialog-box controls according to the text
cwbNL_CalcControlGrowthXY
cwbNL_CalcDialogGrowthXY
cwbNL_GrowControlXY
cwbNL_GrowDialogXY
cwbNL_LoadDialogStrings
cwbNL_LoadMenu
cwbNL_LoadMenuStrings
cwbNL_SizeDialog
Usage notes
This module works ONLY on the following kinds of dialog-box controls:
v Static text
v Button
v Group box
v Edit box
v Check box
v Radio button
It does NOT work on complex controls such as Combo box.

578 Client Access Express Programming


cwbNL_CalcControlGrowthXY:

Purpose: Routine to calculate the growth factor of an individual control within a


dialog box.

Syntax:

unsigned int CWB_ENTRY cwbNL_CalcControlGrowthXY(


HWND windowHandle,
HDC hDC,
float* growthFactorX,
float* growthFactorY);

Parameters:
HWND windowHandle - input
Window handle of the control for which to calculate the growth factor.
HDC hDC - input
Device context. Used by GetTextExtentPoint32 to determine extent needed for
the translated string in the control.
float* growthFactorX - output
+/- growth to the width needed to contain the string for the control.
float* growthFactorY - output
+/- growth to the height needed to contain the string for the control.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion

Usage: It is assumed that the translated text has been loaded into the control prior
to calling this function. A control that does not contain text will return a 1.00
growth factor. This means that it does not need to change size.

Chapter 3. Express C/C++ APIs 579


cwbNL_CalcDialogGrowthXY:

Purpose: Routine to calculate the growth factor of a dialog box. All of the controls
within the dialog box will looked at to determine how much the dialog-box size
needs to be adjusted.

Syntax:

unsigned int CWB_ENTRY cwbNL_CalcDialogGrowthXY(


HWND windowHandle,
float* growthFactorX,
float* growthFactorY);

Parameters:
HWND windowHandle - input
Window handle of the dialog box for which to calculate the growth factor.
float* growthFactorX - output
+/- growth to the width needed to contain the string for all of the controls in
the dialog box.
float* growthFactorY - output
+/- growth to the height needed to contain the string for all of the controls in
the dialog box.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion

Usage: It is assumed that the translated text has been loaded into the controls
prior to calling this function.

580 Client Access Express Programming


cwbNL_GrowControlXY:

Purpose: Routine to grow an individual control within a dialog box.

Syntax:

unsigned int CWB_ENTRY cwbNL_GrowControlXY(


HWND windowHandle,
HWND parentWindowHandle,
float growthFactorX,
float growthFactorY,
cwb_Boolean growAllControls);

Parameters:
HWND windowHandle - input
Window handle of the control to be resized.
HWND parentWindowHandle - input
Window handle of the dialog box that contains the controls.
float growthFactorX - input
Multiplication factor for growing the width of the control. 1.00 = Stay same
size. 1.50 = 1 1/2 times original size.
float growthFactorY - input
Multiplication factor for growing the height of the control. 1.00 = Stay same
size. 1.50 = 1 1/2 times original size.
cwb_Boolean growAllControls - input
CWB_TRUE = All controls will be resized by the growthFactor. CWB_FALSE =
Only controls with text will be resized.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion

Usage: Care should be used to not pass in a growth factor that will cause a control
to not fit on the physical display.

Chapter 3. Express C/C++ APIs 581


cwbNL_GrowDialogXY:

Purpose: Internal routine to growth the dialog box and its controls proportionally
based off of a growth factor that is input.

Syntax:

unsigned int CWB_ENTRY cwbNL_GrowDialogXY(


HWND windowHandle,
float growthFactorX,
float growthFactorY,
cwb_Boolean growAllControls);

Parameters:
HWND windowHandle - input
Window handle of the window owning the controls.
float growthFactorX - input
Multiplication factor for growing the dialog box, ie. 1.00 = Stay same size, 1.50
= 1 1/2 times original size.
float growthFactorY - input
Multiplication factor for growing the dialog box, ie. 1.00 = Stay same size, 1.50
= 1 1/2 times original size.
cwb_Boolean growAllControls - input
CWB_TRUE = All controls will be resized by the growthFactor, CWB_FALSE =
Only controls with text will be resized.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.

Usage: It is assumed that the translated text has been loaded into the controls
prior to calling this function. The dialog-box frame will not be allowed to grow
larger than the desktop window size.

582 Client Access Express Programming


cwbNL_LoadDialogStrings:

Purpose: This routine will control the replacement of translatable text within a
dialog box. This includes dialog control text as well as the dialog-box caption.

Syntax:

unsigned int CWB_ENTRY cwbNL_LoadDialogStrings(


HINSTANCE MRIHandle,
HWND windowHandle,
int nCaptionID,
USHORT menuID,
HINSTANCE menuLibHandle,
cwb_Boolean growAllControls);

Parameters:
HINSTANCE MRIHandle - input
Handle of the module containing the strings for the dialog.
HWND windowHandle - input
Window handle of the dialog box.
int nCaptionID - input
ID of the caption string for the dialog box
USHORT menuID - input
ID of the menu for the dialog box.
HINSTANCE menuLibHandle - input
Handle of the module containing the menu for the dialog.
cwb_Boolean growAllControls - input
CWB_TRUE = All controls will be resized by the growthFactor CWB_FALSE =
Only controls with text will be resized.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion.
CWBNL_DLG_MENU_LOAD_ERROR
Could not load the menu.
CWBNL_DLG_INVALID_HANDLE
Incorrect MRIHandle.

Usage: This process begins by enumerating, replacing the text of, and horizontally
adjusting, all dialog controls within the dialog box, and finally right-adjusting the
dialog box itself, relative to the adjusted controls therein. These adjustments are
made only if the current window extents do not fully encompass the expansion
space required for the text or all controls. After all of the text substitution has been
completed, if a menu ID has been passed, it will be loaded and attached to the
dialog box. It is suggested that this routine is called for every dialog-box procedure
as the first thing done during the INITDLG message processing.

Chapter 3. Express C/C++ APIs 583


cwbNL_LoadMenu:

Purpose: This routine will control the loading of the given menu from a module
and replacing the translatable text within the menu.

Syntax:

HWND CWB_ENTRY cwbNL_LoadMenu(


HWND windowHandle,
HINSTANCE menuResourceHandle,
USHORT menuID,
HINSTANCE MRIHandle);

Parameters:
HWND windowHandle - input
Window handle of the dialog box that contains the menu.
HINSTANCE menuResourceHandle - input
Handle of the resource dll containing the menu.
USHORT menuID - input
ID of the menu for the dialog box.
HINSTANCE MRIHandle - input
Handle of the resource dll containing the strings for the menu.

Return Codes: The following list shows common return values.


HINSTANCE
Handle of the menu.

Usage: None

584 Client Access Express Programming


cwbNL_LoadMenuStrings:

Purpose: This routine will control the replacement of translatable text within a
menu.

Syntax:

unsigned int CWB_ENTRY cwbNL_LoadMenuStrings(


HWND WindowHandle,
HINSTANCE menuHandle,
HINSTANCE MRIHandle);

Parameters:
HWND windowHandle - input
Window handle of the dialog box that contains the menu.
HMODULE menuHandle - input
Handle of the menu for the dialog.
HMODULE MRIHandle - input
Handle of the resource DLL containing the strings for the menu.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion

Usage: None

Chapter 3. Express C/C++ APIs 585


cwbNL_SizeDialog:

Purpose: This routine will control the sizing of the dialog box and its child
controls. The expansion amount is based off of the length of the text extent and the
length of each control. The growth of the dialog box and its controls will be
proportional. By setting the growAllControls to FALSE, only controls with text will
expand or contract. This allows the programmer the flexibility of non-translatable
fields to remain the same size. This may be appropriate for dialogs that contain
drop-down lists, combo-boxes, or spin buttons.

Syntax:

unsigned int CWB_ENTRY cwbNL_SizeDialog(


HWND windowHandle,
cwb_Boolean growAllControls);

Parameters:
HWND windowHandle - input
Window handle of the window owning the controls.
cwb_Boolean growAllControls - input
CWB_TRUE = All controls will be resized by the growthFactor, CWB_FALSE =
Only controls with text will be resized.

Return Codes: The following list shows common return values.


CWB_OK
Successful Completion

Usage: This routine assumes that the translated text has already been loaded into
the dialog-box controls. If the text has not been loaded into the controls, use
cwbNL_LoadDialog.

586 Client Access Express Programming


Example: Express NLS APIs
/* National Language Support Code Snippet */
/* Used to demonstrate how the APIs would be run. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CWBNL.H"
#include "CWBNLCNV.H"
#include "CWBSV.H"
cwbSV_ErrHandle errhandle;

/* Return the message text associated with the top-level */


/* error identified by the error handle provided. Since */
/* all APIs that fail use the error handle, this was moved */
/* into a separate routine. */
void resolveErr(cwbSV_ErrHandle errhandle)
{
static unsigned char buf[ BUFSIZ ];
unsigned long retlen;
unsigned int rc;
if ((rc = cwbSV_GetErrText(errhandle, buf, (unsigned long) BUFSIZ, &retlen)) != CWB_OK)
printf("cwbSV_GetErrText() Service API failed with return code 0x%x.\n", rc);
else
printf("%s\n", (char *) buf);
}

void main(void){
/* define some variables
-------------------- */
int SVrc = 0;
int NLrc = 0;
char *myloadpath = "";
char *resultPtr;
char *mylang;
unsigned short resultlen;
unsigned short reqlen;
unsigned long searchhandle;
unsigned long codepage;
unsigned long trgtpage;
char *srcbuf = "Change this string";
char *trgtbuf;
unsigned long srclen;
unsigned long trgtlen;
unsigned long nmbrerrs;
unsigned long posoferr;
unsigned long rqdlen;
unsigned long ccsid;

/* Create an error message object and return a handle to */


/* it. This error handle can be passed to APIs that */
/* support it. If an error occurs, the error handle can */
/* be used to retrieve the message text associated with */
/* the API error. */
SVrc = cwbSV_CreateErrHandle(&errhandle);
if (SVrc != CWB_OK) {
printf("cwbSV_CreateErrHandle failed with return code %d.\n", SVrc);
}

/* Retreive the current language setting. */


resultlen = CWBNL_MAX_LANG_SIZE+1;
resultPtr = (char *) malloc(resultlen * sizeof(char));
NLrc = cwbNL_GetLang(myloadpath, resultPtr, resultlen, &reqlen, errhandle);
if (NLrc != CWB_NO_ERR) {
if (NLrc == CWB_BUFFER_TOO_SMALL)
printf("GetLang buffer too small, recommended size %d.\n", reqlen);
resolveErr(errhandle);
}
printf("GetLang API returned %s.\n", resultPtr);
mylang = (char *) malloc(resultlen * sizeof(char));
strcpy(mylang, resultPtr);

/* Retrieve the descriptive name of a language setting. */


resultlen = CWBNL_MAX_NAME_SIZE+1;
resultPtr = (char *) realloc(resultPtr, resultlen * sizeof(char));
NLrc = cwbNL_GetLangName(mylang, resultPtr, resultlen, &reqlen, errhandle);
if (NLrc != CWB_NO_ERR) {
if (NLrc == CWB_BUFFER_TOO_SMALL)
printf("GetLangName buffer too small, recommended size %d.\n", reqlen);
resolveErr(errhandle);
}
printf("GetLangName API returned %s.\n", resultPtr);

/* Return the complete path for language files. */


resultlen = CWBNL_MAX_PATH_SIZE+1;
resultPtr = (char *) realloc(resultPtr, resultlen * sizeof(char));
NLrc = cwbNL_GetLangPath(myloadpath, resultPtr, resultlen, &reqlen, errhandle);
if (NLrc != CWB_NO_ERR) {
if (NLrc == CWB_BUFFER_TOO_SMALL)
printf("GetLangPath buffer too small, recommended size %d.\n", reqlen);
resolveErr(errhandle);
}
printf("GetLangPath API returned %s.\n", resultPtr);

/* Get the code page of the current process. */


NLrc = cwbNL_GetCodePage(&codepage, errhandle);
if (NLrc != CWB_NO_ERR) {
resolveErr(errhandle);
}
printf("GetCodePage API returned %u.\n", codepage);

/* Convert strings from one code page to another. This */


/* API combines three converter APIs for the default */
/* conversion. The three converter APIs it combines are: */
/* cwbNL_CreateConverter */
/* cwbNL_Convert */
/* cwbNL_DeleteConverter */
srclen = strlen(srcbuf) + 1;
trgtlen = srclen;
trgtpage = 437;
trgtbuf = (char *) malloc(trgtlen * sizeof(char));

Chapter 3. Express C/C++ APIs 587


printf("String to convert is %s.\n",srcbuf);
NLrc = cwbNL_ConvertCodePages(codepage, trgtpage, srclen,
trgtlen, srcbuf, trgtbuf, &nmbrerrs, &posoferr, &rqdlen,
errhandle);
if (NLrc != CWB_NO_ERR) {
resolveErr(errhandle);
printf("number of errors detected is %u.\n", nmbrerrs);
printf("location of first error is %u.\n", posoferr);
}
printf("ConvertCodePages API returned %s.\n", trgtbuf);

/* Map a code page to the corresponding CCSID. */


NLrc = cwbNL_CodePageToCCSID(codepage, &ccsid, errhandle);
if (NLrc != CWB_NO_ERR) {
resolveErr(errhandle);
}
printf("CodePageToCCSID returned %u.\n", ccsid);

cwbSV_DeleteErrHandle(errhandle);

Express Directory Update APIs


What is Express Directory Update?
The Client Access Express Directory Update function allows users to
specify PC directories for updating from a configured network server or
from multiple networked servers. This permits users to load non-Client
Access Express software products on a server in the network, and to keep
those files updated on PCs. Directory Update is an optionally installable
Client Access Express component.
How to install Express Directory Update:
To install Directory Update, follow these steps when you install
Client Access Express, or when you run Selective Setup if Client
Access already is installed:
1. Select the Express Optional Components check box.
2. Expand the view and make sure that the Directory Update
subcomponent also is selected.
3. Follow the prompts to completion.
Express Directory Update C/C++ APIs:
Client Access Express Directory Update C/C++ application programming
interfaces (APIs) allow software developers to add, change and delete
update entries that are used by the Express Directory Update function.

Note: Express Directory Update APIs do not actually perform the updates.
They are for configuration purposes only. The task of updating files
is handled exclusively by the Directory Update application.

Express Directory Update APIs enable the:


v Creation of update entries.
v Deletion of update entries.
v Modification of update entries.
v Retrieval of information from update entries.
v Retrieval of information such as return codes. For example, only one
application can access the Update entries at a time. If you get a return
code that indicates locked, use the information to find the name of the
application that has the entries open.

IMPORTANT: The Express client does not include support for network drives or
for universal naming conventions. This now is provided by the
AS/400 NetServer function. Network drives that you previously
mapped by using Client Access should be mapped by using
AS/400 NetServer support. Set up the AS/400 NetServer that
comes with OS/400 V4R2 and beyond in order to perform file
serving to the AS/400.

588 Client Access Express Programming


NetServer information resources:
v AS/400 NetServer topic of the AS/400 Information
Center

v IBM AS/400 NetServer Home Page


Express Directory Update APIs required files:

Header file Import library Dynamic Link Library


cwbup.h cwbapi.lib cwbup.dll

Express Toolkit:
The Client Access Express Toolkit provides Directory Update
documentation, access to the cwbup.h header file, and links to sample
programs. To access this information, open the Express Toolkit and select
Directory Update —> C/C++ APIs.
Express Directory Update APIs topics:
v “Typical use of Express Directory Update APIs”
v “Requirements for Directory Update entries”
v “Options for Directory Update entries” on page 590
v “Directory Update package files syntax and format” on page 591
v Express Directory Update APIs listing
v “Directory Update sample program” on page 592
v “Express Directory Update APIs return codes” on page 25
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Typical use of Express Directory Update APIs


Express Directory Update APIs typically are used for creating and configuring
update entries that are used to update files from a mapped network drive. It is
important to note that the Update APIs do not actually update the files, but rely on
the Directory Update executable file to do this.

For example, files on the AS/400 system might contain customer names and
addresses. The files on your AS/400 system are your master files that are updated
as new customers are added, deleted, or have a name or address change. The same
files on your networked personal computers are used to perform selective market
mailings (by zip code, state, age, number of children and so on). The files on the
AS/400 system are your master files, and you want them secure, but you need to
provide the data for work.

You could write a program that uses Directory Update APIs to create and
configure update entries, which would update the files located on your networked
personal computers.

Requirements for Directory Update entries


The following are required for Directory Update entries:
Description:
A description displayed by the Directory Update application to show users
what is being updated.

Chapter 3. Express C/C++ APIs 589


Source path:
The path of the source or ″master″ files. For example:
E:\MYSOURCE

or
\\myserver\mysource
Target path:
The path of the files with which you wish to keep synchronized with the
master files. For example:
C:\mytarget

Options for Directory Update entries


The following are optional for Directory Update entries:
Package files:
PC files that contain information on other files to be updated. See
“Directory Update package files syntax and format” on page 591 for more
information. Package files are added to update entries by using the
“cwbUP_AddPackageFile” on page 594 API.
Callback DLL:
A DLL provided by the application programmer that Directory Update will
call into during different stages of the update process. This allows
programmers to perform application unique processing during the
different stages of an update. A callback DLL is added to an update entry
using the “cwbUP_SetCallbackDLL” on page 609 API.
The different stages of update when Directory Update may call into the
callback DLL are:
Pre-update:
This is when Directory Update is about to begin its processing of
an update entry. The following entry point prototype must be in
the callback DLL: unsigned long _declspec(dllexport)
cwbUP_PreUpdateCallback();
Post-update:
This is when Directory Update has completed moving the files.
The following entry point prototype must be in the callback DLL:
unsigned long _declspec(dllexport) cwbUP_PostUpdateCallback();
Pre-migration:
This is when Directory Update is about to begin version-to-version
migration of an update entry. Version-to-version migrations are
triggered by QPTFIDX files. The following entry point prototype
must be in the callback DLL: unsigned long _declspec(dllexport)
cwbUP_PreMigrationCallback();
Post-migration:
This is when Directory Update has completed processing of a
version-to-version migration of an update entry. The following
entry point prototype must be in the callback DLL: unsigned long
_declspec(dllexport) cwbUP_PostMigrationCallback();
Attributes:
Set the type or mode of the update to be performed. Combinations of the
attributes are allowed. Attributes are:

590 Client Access Express Programming


File-driven update:
The files in the target directory are compared to the files in the
source directory. Target files with dates older than the source files
are updated. No new files will be created in the target.
Package-driven update:
The package files listed in the update entry are scanned for files to
be updated. The dates of the files that are listed in the package file
are compared between the source and the target directories. The
source files with newer dates are updated or moved into the target
directory. If a file that is listed in the package file does not exist in
the target, but exists in the source, the file is created in the target
directory.
Subdirectory update:
Subdirectories under the target directory are included in the
update.
Onepass update:
Updates occur directly from source to target. If this is not specified,
updates occur in two passes. The first pass of the update will copy
the files to be updated into a temporary directory. Then the PC is
restarted. On restart, the files are copied to the target directory.
This is useful for locked files.
Backlevel update:
This controls if updates will occur if the source files are older than
the target files.

Directory Update package files syntax and format


Package files contain information that specifies and describes which target files
users want to be kept current with source files.
Package files syntax:
PKGF Description text
MBRF PROG1.EXE
MBRF INFO.TXT
MBRF SUBDIR\SHEET.XLS
DLTF PROG2.EXE

Note: Text must start in the first row and column of the file. Each package file
must begin with the PKGF keyword.
Package files format:
Package files consist of the following elements:
PKGF description (optional):
This identifier indicates that the file is a package file. If this tag is
not found in the first four characters of the file, Directory Update
will not process the file while searching for files to update. A
description is optional.
MBRF filename:
This identifies a file as part of the package to be updated. A path
name also can be specified; this indicates that the file is in a
subdirectory of the source directory.
The path should not contain the drive letter, or begin with a
back-slash character (\). When you begin the update function, you

Chapter 3. Express C/C++ APIs 591


specify a target directory; the path that is specified in the package
file is considered a subdirectory of this target directory.
DLTF filename:
This identifies a file to be deleted from the target directory. A path
name also can be specified; this indicates that the file is in a
subdirectory of the target directory. As with the MBRF identifier,
you should not specify a drive letter or begin with a back-slash
character (\).
Related topic:
See “Directory Update sample program” for sample Directory Update APIs
and detailed explanations of their attributes.

Directory Update sample program


A Directory Update C/C++ sample program is available when you link to the

Client Access Express Toolkit – Directory Update Web page . Select


dirupdat.exe for a description of the sample, and to download the samples.

The sample program demonstrates creating, configuring, and deleting Directory


Update entries.

See the Client Access User’s Guide for more information.

Express Directory Update API listing


Note: It is essential that “cwbUP_FreeLock” on page 600 is called when your
application no longer is accessing the update entries. If cwbUP_FreeLock is
not called, other applications will not be able to access or modify the update
entries.

The following Express Directory Update APIs are listed alphabetically, and are
grouped by function:

Function Express Directory Update APIs


Create an update entry cwbUP_CreateUpdateEntry
Delete an update entry cwbUP_DeleteEntry
Obtain access to an update entry cwbUP_FindEntry
cwbUP_FreeLock
cwbUP_GetEntryHandle
Free resources that are associated with an
entry handle cwbUP_FreeEntryHandle
Change an update entry cwbUP_AddPackageFile
cwbUP_RemovePackageFile
cwbUP_SetCallbackDLL
cwbUP_SetDescription
cwbUP_SetEntryAttributes
cwbUP_SetSourcePath
cwbUP_SetTargetPath
Obtain information from an update entry cwbUP_GetCallbackDLL
cwbUP_GetDescription
cwbUP_GetEntryAttributes
cwbUP_GetSourcePath
cwbUP_GetTargetPath

592 Client Access Express Programming


Function Express Directory Update APIs
Retrieve general Directory Update
information cwbUP_GetLockHolderName

Chapter 3. Express C/C++ APIs 593


cwbUP_AddPackageFile
Purpose: Adds a package file to the package file list in the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_AddPackageFile(


cwbUP_EntryHandle entryHandle,
char *entryPackage);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or
cwbUP_FindEntry.
char * entryPackage - input
Pointer to a null-terminated string that contains the name of a package file to
be added to the update entry. Do not include the path for this file. The
package file must exist in the source and target paths.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL was passed as an address.
CWBUP_TOO_MANY_PACKAGES
Maximum number of package files already exist for this entry.
CWBUP_STRING_TOO_LONG
The package file name is longer than CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

594 Client Access Express Programming


cwbUP_CreateUpdateEntry
Purpose: Creates a new update entry and passes back a handle to it.

Syntax:

unsigned int CWB_ENTRY cwbUP_CreateUpdateEntry(


char * entryDescription,
char * entrySource,
char * entryTarget,
cwbUP_EntryHandle *entryHandle);

Parameters:
char * entryDescription - input
Points to a null-terminated string that contains a description to identify the
update entry.
char * entrySource - input
Points to a null-terminated string that contains the source for the update entry.
This can be either a drive and path, or a UNC name.
char * entryTarget - input
Points to a null-terminated strings that contains the target for the update entry.
This can be either a drive and path, or a UNC name.
cwbUP_EntryHandle * entryHandle - input/output
Pointer to a cwbUP_EntryHandle where the handle will be returned. This
handle must be used in subsequent calls to the update entry APIs.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as an address.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.
CWBUP_TOO_MANY_ENTRIES
The maximum number of update entries already exist. No more can be
created.
CWBUP_STRING_TOO_LONG
An input string is longer than the maximum of CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: When you use this call, and have completed your processing of the update
entry, you must call cwbUP_FreeEntryHandle. This call will ″unlock″ the entry,
and free resources that are associated with it.

Chapter 3. Express C/C++ APIs 595


cwbUP_DeleteEntry
Purpose: Deletes the update entry from the update entry list.

Syntax:

unsigned int CWB_ENTRY cwbUP_DeleteEntry(


cwbUP_EntryHandle entryHandle);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or
cwbUP_FindEntry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: After this call, you do not need to call cwbUP_FreeEntryHandle. The
entry is ″freed″ when the entry is successfully deleted. If you retrieved the first
update entry by using the cwbUP_GetEntryHandle API, and then called this API
to delete the entry, all of the update entries would shift one position to fill the slot
left by the delete. So, if you then wanted to get the next update item, you would
pass the same index that you did on the previous cwbUP_GetEntryHandle API
call.

596 Client Access Express Programming


cwbUP_FindEntry
Purpose: Gets a handle to an existing update entry by using entrySource and
entryTarget as the search parameters.

Syntax:

unsigned int CWB_ENTRY cwbUP_FindEntry(


char * entrySource,
char * entryTarget,
unsigned long *searchStart,
cwbUP_EntryHandle *entryHandle);

Parameters:
char * entrySource - input
Points to a null-terminated string that contains the source for the update entry.
This can be either a drive and path, or a UNC name. This string will be used
to search for a */ matching update entry.
char * entryTarget - input
Points to a null-terminated string that contains the target for the update entry.
This can be either a drive and path, or a UNC name. This string will be used
to search for a matching update entry.
unsigned long * searchStart - input/output
Pointer to an index into the list of update entries to begin the search at. This
would be used in cases where multiple update entries may have matching
source and targets. You would use this parameter to ″skip″ over entries in the
search, and continue on searching for a matching update entry that is after
searchStart in the list. On successful return, searchStart will be set to the
position in the list where the update entry was found. This should be set to
CWBUP_SEARCH_FROM_BEGINNING if you want to search all update
entries.
cwbUP_EntryHandle * entryHandle - input/output
Pointer to a cwbUP_EntryHandle where the handle will be returned. This
handle must be used in subsequent calls to the update entry APIs.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as an address.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.
CWBUP_SEARCH_POSITION_ERROR
Search starting position is not valid.
CWBUP_ENTRY_NOT_FOUND
No update entry matched search value.
CWBUP_STRING_TOO_LONG
An input string is longer than the maximum of CWBUP_MAX_LENGTH.

Usage: The handle that is returned from this call will be used for accessing the
update entry with other Update APIs. When you use this call, and have completed
your processing of the update entry, you must call cwbUP_FreeEntryHandle. This

Chapter 3. Express C/C++ APIs 597


call will ″unlock″ the entry, and free resources with which it is associated.

598 Client Access Express Programming


cwbUP_FreeEntryHandle
Purpose: Frees an entry handle and all resources with which is is associated.

Syntax:

unsigned int CWB_ENTRY cwbUP_FreeEntryHandle(


cwbUP_EntryHandle entryHandle);

Parameters:
cwbUP_EntryHandle entryHandle - input
The entry handle that is to be freed.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid or has already been

Usage: After this call you can no longer access the update entry. To access the
update entry or another update entry, you would need to get a new entry handle.

Chapter 3. Express C/C++ APIs 599


cwbUP_FreeLock
Purpose: Frees the lock to the update entries. This should be called when the
application is done accessing the update entries. If this is not called, other
applications will not be able to access the update entries.

Syntax:

unsigned int CWB_ENTRY cwbUP_FreeLock();

Parameters:
None

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBUP_UNLOCK_WARNING
Application did not have the update entries locked.

Usage: A lock to the update entries is obtained whenever an application accesses


or changes an update entry. When the application no longer needs to access the
update entries, the application should call this API.

600 Client Access Express Programming


cwbUP_GetCallbackDLL
Purpose: Gets the fully qualified name of the callback DLL for an update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetCallbackDLL(


cwbUP_EntryHandle entryHandle,
char *dllPath,
unsigned long bufferLength,
unsigned long *actualLength);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * dllPath - input/output
Pointer to a buffer that will receive the fully qualified name of the DLL that
will be called when individual stages of the update occur.
unsigned long bufferLength - input
Length of the dllPath buffer. Space should be included for the null termination
character. If the buffer is not large enough to hold the entire DLL name, an
error will be returned and the actualLength parameter will be set to the
number of bytes the dllPath buffer needs to be.
unsigned long * actualLength - input/output
Pointer to a length variable that will be set to the size of the buffer needed to
contain the fully qualified DLL name.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWB_BUFFER_OVERFLOW
Buffer is too small to hold return data.

Usage: None

Chapter 3. Express C/C++ APIs 601


cwbUP_GetDescription
Purpose: Gets the description of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetDescription(


cwbUP_EntryHandle entryHandle,
char *entryDescription,
unsigned long bufferLength,
unsigned long *actualLength);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entryDescription - input/output
Pointer to a buffer that will receive the description of the update entry.
unsigned long bufferLength - input
Length of the buffer. An extra byte should be included for the null termination
character. If the buffer is not large enough to hold the entire description, an
error will be returned and the actualLength parameter will be set to the
number of bytes the entryDescription buffer needs to be to contain the data.
unsigned long * actualLength - input/output
Pointer to a length variable that will be set to the size of the buffer needed to
contain the description.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWB_BUFFER_OVERFLOW
Buffer is too small to hold return data.

Usage: None

602 Client Access Express Programming


cwbUP_GetEntryAttributes
Purpose: Gets the attributes of the update entry. These include: one pass update,
file driven update, package driven update, and update subdirectories. Any
combination of these is valid.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetEntryAttributes(


cwbUP_EntryHandle entryHandle,
unsigned long *entryAttributes);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
unsigned long * entryAttributes - input/output
Pointer to area to receive the attribute values. (See defines section for values)

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.

Usage: The value that is contained in entryAttributes after this call is made may
be a combination of the attribute flags that are listed near the top of this file.

Chapter 3. Express C/C++ APIs 603


cwbUP_GetEntryHandle
Purpose: Gets a handle to an existing update entry at a given position in the list.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetEntryHandle(


unsigned long entryPosition,
cwbUP_EntryHandle *entryHandle);

Parameters:
unsigned long entryPosition - input
Index into the update entry list of the entry for which you want to retrieve a
handle. (Pass in 1 if you wish to retrieve the first update entry)
cwbUP_EntryHandle * entryHandle - input/output
Pointer to a cwbUP_EntryHandle where the handle will be returned. This
handle must be used in subsequent calls to the update entry APIs.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL was passed as an address.
CWBUP_ENTRY_NOT_FOUND
No update entry at the given position.
CWBUP_POSITION_INVALID
Position that is given is not in range.

Usage: The handle that is returned from this call will be used for accessing the
update entry with other Update APIs. When you use this call, and have completed
your processing of the update entry, you must call cwbUP_FreeEntryHandle. This
call will ″unlock″ the entry, and free resources that are associated with it. You must
call cwbUP_FreeEntryHandle once for each time that you call an API that returns
an entry handle.

604 Client Access Express Programming


cwbUP_GetLockHolderName
Purpose: Gets the name of the program that currently has the update entries in a
locked state.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetLockHolderName(char *lockHolder,


unsigned long bufferLength,
unsigned long *actualLength);

Parameters:
char * lockHolder - input/output
Pointer to a buffer that will receive the name of the application that is
currently locking the update entries.
unsigned long bufferLength - input
Length of the buffer. An extra byte should be included for the null termination
character. If the buffer is not large enough to hold the entire name, an error
will be returned and the actualLength parameter will be set to the number of
bytes the lockHolder buffer needs to be to contain the data.
unsigned long * actualLength - input/output
Pointer to a length variable that will be set to the size of the buffer needed to
contain the application name.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWB_BUFFER_OVERFLOW
Buffer is too small to hold return data.

Usage: None

Chapter 3. Express C/C++ APIs 605


cwbUP_GetSourcePath
Purpose: Gets the source path of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetSourcePath(


cwbUP_EntryHandle entryHandle,
char *entrySource,
unsigned long bufferLength,
unsigned long *actualLength);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entrySource - input/output
Pointer to a buffer that will receive the source path of the update entry.
unsigned long bufferLength - input
Length of the buffer. An extra byte should be included for the null termination
character. If the buffer is not large enough to hold the entire source path, an
error will be returned and the actualLength parameter will be set to the
number of bytes the entrySource buffer needs to be to contain the data.
unsigned long * actualLength - input/output
Pointer to a length variable that will be set to the size of the buffer needed to
contain the source path.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWB_BUFFER_OVERFLOW
Buffer is too small to hold return data.

Usage: None

606 Client Access Express Programming


cwbUP_GetTargetPath
Purpose: Gets the target path of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_GetTargetPath(


cwbUP_EntryHandle entryHandle,
char *entryTarget,
unsigned long bufferLength,
unsigned long *actualLength);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entryTarget - input/output
Pointer to a buffer that will receive the target path of the update entry.
unsigned long bufferLength - input
Length of the buffer. An extra byte should be included for the null termination
character. If the buffer is not large enough to hold the entire target path, an
error will be returned and the actualLength parameter will be set to the
number of bytes the entryTarget buffer needs to be to contain the data.
unsigned long * actualLength - input/output
Pointer to a length variable that will be set to the size of the buffer needed to
contain the target path.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWB_BUFFER_OVERFLOW
Buffer is too small to hold return data.

Usage: None

Chapter 3. Express C/C++ APIs 607


cwbUP_RemovePackageFile
Purpose: Removes a package file from the list of package files that belong to an
update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_RemovePackageFile(


cwbUP_EntryHandle entryHandle,
char *entryPackage);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entryPackage - input
Pointer to a null-terminated string that contains the package file name that is
to be removed from the package file list.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWBUP_PACKAGE_NOT_FOUND
The package file was not found.
CWBUP_STRING_TOO_LONG
The package file string is longer than the maximum of
CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

608 Client Access Express Programming


cwbUP_SetCallbackDLL
Purpose: Sets the fully qualified name of the callback DLL for an update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_SetCallbackDLL(


cwbUP_EntryHandle entryHandle,
char *dllPath);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or
cwbUP_FindEntry.
char * dllPath - input
Pointer to a null-terminated string that contains the fully qualified name of the
DLL that will be called when individual stages of the update occur.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWBUP_STRING_TOO_LONG
The callback DLL string is longer than the maximum of
CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

Chapter 3. Express C/C++ APIs 609


cwbUP_SetDescription
Purpose: Sets the description of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_SetDescription(


cwbUP_EntryHandle entryHandle,
char *entryDescription);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entryDescription - input
Pointer to a null-terminated string that contains the full description to be
associated with the update entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWBUP_STRING_TOO_LONG
The description string is longer than the maximum of
CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

610 Client Access Express Programming


cwbUP_SetEntryAttributes
Purpose: Sets any of the following attribute values of the update entry:
CWBUP_FILE_DRIVEN
Updates are based on file date comparisons between target and source
files.
CWBUP_PACKAGE_DRIVEN
Updates are based on contents of the package file(s), and comparisons of
their files’ dates between target and source.
CWBUP_SUBDIRECTORY
Update compares and updates directories under the given path.
CWBUP_ONEPASS
Updates occur directly in one pass. If this isn’t specified, updates occur in
two passes. The first pass copies the files to be updated to a temporary
directory, and then when the PC is rebooted, the files are copied to the
target directory.
CWBUP_BACKLEVEL_OK
If this is set, updates will occur if the dates of the files on the source and
target don’t match. If this is not set, updates will only occur if the source
file is more recent than the target file.

Any combination of these values is valid.

Syntax:

unsigned int CWB_ENTRY cwbUP_SetEntryAttributes(


cwbUP_EntryHandle entryHandle,
unsigned long entryAttributes);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
unsigned long entryAttributes - input
Combination of the attribute values. (See defines section for values)

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: An example of this call follows:

rc = cwbUP_SetEntryAttributes(entryHandle, CWBUP_FILEDRIVEN |
CWBUP_ONEPASS );

Chapter 3. Express C/C++ APIs 611


This call would result in the update entry being file driven and the update would
occur in one pass.

612 Client Access Express Programming


cwbUP_SetSourcePath
Purpose: Sets the source path of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_SetSourcePath(


cwbUP_EntryHandle entryHandle,
char *entrySource);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entrySource - input
Pointer to a null-terminated string that contains the full source path for the
update entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWBUP_STRING_TOO_LONG
The source path string is longer than the maximum of
CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

Chapter 3. Express C/C++ APIs 613


cwbUP_SetTargetPath
Purpose: Sets the target path of the update entry.

Syntax:

unsigned int CWB_ENTRY cwbUP_SetTargetPath(


cwbUP_EntryHandle entryHandle,
char *entryTarget);

Parameters:
cwbUP_EntryHandle entryHandle - input
Handle that was returned by a previous call to
cwbUP_CreateUpdateEntryHandle, cwbUP_GetUpdateEntryHandle, or to
cwbUP_FindEntry.
char * entryTarget - input
Pointer to a null-terminated string that contains the full target path for the
update entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Update entry handle is not valid.
CWB_INVALID_POINTER
NULL passed as an address parameter.
CWBUP_STRING_TOO_LONG
The target path string is longer than the maximum of
CWBUP_MAX_LENGTH.
CWBUP_ENTRY_IS_LOCKED
Another application is currently changing the update entry list. No
changes are allowed at this time.

Usage: None

614 Client Access Express Programming


Express PC5250 emulation APIs
The Client Access Express PC5250 emulator provides desktop users with a
graphical user interface for existing AS/400 applications. PC5250 allows users to
easily and transparently interact with data and applications that are stored on the
AS/400. PC5250 provides C/C++ application programming interfaces (APIs) for
enabling workstation programs to interact with AS/400 host systems.
Express PC5250 C/C++ APIs:
Emulator high-level language API (EHLLAPI)
A simple, single-entry point interface that interprets the emulator
screen.
Personal communications session API (PCSAPI)
Use this interface to start, stop, and control emulator sessions.
Host Access Class Library (HACL)
This interface provides a set of classes and methods for developing
applications that access host information at the data-stream level.
Express emulation APIs required files:

Emulation interface Header file Import library Dynamic Link


Library
Standard HLLAPI hapi_c.h pscal32.lib pcshll.dll
pcshll32.dll
Enhanced HLLAPI ehlapi32.h ehlapi32.lib ehlapi32.dll
Windows EHLLAPI whllapi.h whllapi.lib whllapi.dll
whlapi32.lib whllapi32.dll
HACL interface eclall.hpp pcseclva.lib pcseclva.dll
pcseclvc.lib pcseclvc.dll
PCSAPI interface pcsapi.h pcscal32.lib pcsapi.dll
pcsapi32.dll

Express Toolkit:
The Client Access Express Toolkit provides Emulator interfaces
documentation, access to header files, and links to sample applications. To
access this information, open the Express Toolkit and select Emulation —>
C/C++ APIs.

IBM Lightweight Directory Access Protocol (LDAP) APIs


LDAP is a protocol for accessing online directory services directly over TCP/IP. It
provides TCP/IP access to X.500 directories, as well as other stand-alone LDAP
servers. LDAP APIs provide for both synchronous and asynchronous access to a
directory.

LDAP is a global directory service. It is based on a client/server model. One or


more LDAP servers contain data that form the LDAP directory tree. An LDAP
client connects to an LDAP server, and makes a request for information. The server
responds either with an answer, or with a pointer to where the client can obtain
more information. Typically, this is another LDAP server. Regardless of the LDAP
server, the client always is presented with the same view of the directory: A name
presented to one LDAP server references the identical entry that would be
referenced at another LDAP server.

Chapter 3. Express C/C++ APIs 615


LDAP APIs required files:

Header file Import library Dynamic Link Library


ldap.h ldap.lib ldap.dll

Note: Applications that use the previous versions ldape.lib and ldape.dll
will not run on Client Access Express. Copy ldap.dll to ldape.dll,
and ldap.lib to ldape.lib.
Express Toolkit:
The Client Access Express Toolkit provides LDAP documentation, access to
the ldap.h header file, and links to sample programs. To access this
information, open the Express Toolkit and select Directory —> C/C++
APIs.
IBM Lightweight Directory Access Protocol (LDAP) topics:
v “IBM LDAP client incompatibility”
v “LDAP version support”
v “LDAP APIs overview” on page 617
v LDAP utilities APIs listing
v LDAP APIs listing
v “Distinguished names format” on page 696
v “LDAP Data Interchange Format (LDIF)” on page 697
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10
Additional LDAP information resources:
v Directory Services (LDAP) topic in the AS/400 Information Center

v IBM AS/400 Directory Services (LDAP) Web site

IBM LDAP client incompatibility


LDAP may operate incorrectly with products that use the IBM SecureWay
Directory Client. For example, the application may fail to load LDAP.DLL. This
problem occurs when there are multiple copies of LDAP.DLL in the PATH. Client
Access Express installs the DLL in the Windows system directory, while the IBM
SecureWay Directory Client installs the DLL in another location.

The copy of LDAP.DLL that is installed in the Windows system directory is for
customer applications that use the LDAP APIs. Client Access Express does not use
this copy of the DLL. Another copy is installed in a Client Access directory.

If you do not use LDAP APIs, or if you experience problems when Client Access
installs LDAP.DLL in the Windows system directory, IBM recommends that you
rename or delete the LDAP.DLL that is located in the system directory.

Note: To avoid this conflict, a future release of Client Access no longer will include
the LDAP APIs. Operations Navigator plug-ins that use LDAP.DLL will load
the DLL that is installed in the Client Access\ldap directory.

LDAP version support


Enhancements that were made to the LDAP toolkit include support for both LDAP
Version 2 and LDAP Version 3 APIs and protocols.

616 Client Access Express Programming


The LDAP API provides typical directory functions such as read, write, and search.
Support for LDAP Version 3 APIs and protocols includes the following features:
v Controls and extended operations
v LDAP V3 referrals
v Improved internationalization with UTF-8 support for distinguished names and
for strings that are passed into, and returned from, the LDAP APIs

Note: This is true only when running as an LDAP V3 application. When


running as an LDAP V2 application, distinguished names and strings
limit remains as the IA5 character set.

With this toolkit, an application that uses the ldap_open API defaults to the LDAP
V2 protocol. In this way, existing LDAP applications will continue to work, and
can interoperate with both LDAP V2 servers and LDAP V3 servers.

An application that uses the ldap_init API defaults to the LDAP V3 protocol (with
optional bind). An LDAP V3 application will not necessarily interoperate with an
LDAP server that supports only LDAP V2 protocols.

Note that an application can use the ldap_set_option API to change its LDAP
protocol version. Do this after using ldap_open or ldap_init but before issuing a
bind or other operation that results in contacting the server.

LDAP APIs overview


The design of LDAP APIs provides a suite of functions for use in developing
directory-enabled applications. Directory-enabled applications typically will
connect to one or more directories and perform various directory-related
operations, such as:
v Adding entries
v Searching the directory and obtaining the resulting list of entries
v Deleting entries
v Updating entries
v Renaming entries

The type of information that is managed in the directory depends on the nature of
the application. It is common practice to use directories to provide public access to
information about people, including:
v Telephone numbers
v E-mail addresses
v Fax numbers
v Mailing addresses

Increasingly, programmers use directories to manage and publish other types of


information, including:
v Configuration information
v Public key certificates (that are managed by certification authorities)
v Access-control information

LDAP APIs provide for both synchronous and asynchronous access to a directory.
Asynchronous access makes it easy for your application to do other work while
waiting for the results of potentially lengthy directory operations to return.

Complete sample programs are provided that perform the following operations:
v “ldapsearch” on page 633 (searches the directory)
v “ldapmodify” on page 626 (changes information in the directory)

Chapter 3. Express C/C++ APIs 617


v “ldapdelete” on page 623 (deletes information from the directory)
v “ldapmodrdn” on page 630 (changes the relative distinguished name of an entry
in the directory)
LDAP APIs overview topics:
v “Performing an LDAP search”
v “Displaying LDAP search results”
v “Uniform resource locators (URLs)”
v “LDAP Secure Sockets Layer (SSL) support”

Performing an LDAP search


Follow these steps to perform an LDAP search:
1. Make a connection to an LDAP server by calling ldap_init (or ldap_ssl_init to
establish a secure connection over Secure Sockets Layer).
2. Perform an LDAP bind operation by calling ldap_simple_bind. The bind
operation authenticates the directory server. Note that the LDAP V3 API and
protocol permits the bind to be skipped, which obtains the access rights that
are associated with anonymous access.
3. Next, call one of the synchronous or asynchronous routines to perform other
operations (for example, ldap_search_s or ldap_search that is followed by
ldap_result).
Interpret the results that are returned from these routines by calling the LDAP
parsing routines, which include operations including:
v ldap_first_entry, ldap_next_entry
v ldap_get_dn
v ldap_first_attribute, ldap_next_attribute
v ldap_get_values
4. Stop the LDAP association by calling ldap_unbind.
5. Use the ldap_set_rebind_proc routine to define the entry-point of a routine that
calls the LDAP bind operation that is needed when handling a client referral to
another server.

Displaying LDAP search results


Access the results that are obtained from the LDAP search routines by completing
the following steps.
1. Call ldap_first_entry and ldap_next_entry to step through the returned entries.
2. Call ldap_first_attribute and ldap_next_attribute to step through an entry’s
attributes.
3. Call ldap_get_values to retrieve a given attribute’s value.
4. Call printf to display the values.

Uniform resource locators (URLs)


Use the ldap_url routines to do the following:
v Test a URL to determine whether it is an LDAP URL
v Parse LDAP URLs into their component pieces
v Initiate searches directly by using an LDAP URL

LDAP Secure Sockets Layer (SSL) support


Using a Secure Socket Layer (SSL) interface extends the LDAP API to support
connections. Use this to provide strong authentication between the client and
server, as well as data encryption of LDAP messages that flow between the client
and the LDAP server. Use the ldap_ssl_client_init API to start the SSL function,
and the ldap_ssl_init API to create a secure SSL connection.

618 Client Access Express Programming


Note: Some of the material that is contained in this document is derived from the
LDAP man pages. The University of Michigan LDAP reference
implementation (Version 3.3) provided these pages.

LDAP utilities APIs listing


LDAP utilities are shipped with Client Access as part of the LDAP client. They
consist of LDAP tools and sample source code, and include code descriptions,
options, formatting instructions and examples. Access the LDAP utilities HTML
source file, apihead.htm, through the following path:
/QIBM/ProdData/OS400/DirSrv/UserTools/Windows/doc

Link to any of the following LDAP utilities APIs:


v “ldapadd”
v “ldapdelete” on page 623
v “ldapmodrdn” on page 630
v “ldapsearch” on page 633
v “LDAP controls” on page 638

ldapadd
ldapadd is the LDAP add-entry tool.
ldapadd topics:
v “ldapadd synopsis”
v “ldapadd description”
v “ldapadd options” on page 620
v “ldapadd input format” on page 621
v “Alternative ldapadd input format” on page 621
v “Examples: Using ldapadd” on page 621
v “ldapadd notes” on page 622
v “ldapadd SSL notes” on page 622
v “ldapadd diagnostics” on page 623
Related topics:
v “ldapmodify” on page 626
v “ldapdelete” on page 623
v “ldapmodrdn” on page 630
v “ldapsearch” on page 633
v “IBM Lightweight Directory Access Protocol (LDAP) APIs” on page 615
v “ldap_add” on page 643
v “ldap_delete” on page 651
v “ldap_modify” on page 676
v “ldap_rename” on page 681
v “ldap_ssl” on page 689
v “LDAP Data Interchange Format (LDIF)” on page 697

ldapadd synopsis: ldapadd [-b] [-c] [-r] [-n] [-v] [-F] [-R] [-d debuglevel] [-D
binddn] [-w passwd] [-h ldaphost] [-p ldapport] [-f file] [-Z] [-K keyfile] [-P
keyfilepw] [-N certificatename]

ldapadd description: ldapmodify is a shell-accessible interface to the ldap_modify


and ldap_add library calls. ldapadd is accomplished as a renamed version of
ldapmodify. When started as ldapadd the -a (add-new entry) flag turns on
automatically.

Chapter 3. Express C/C++ APIs 619


ldapmodify opens a connection to an LDAP server, binds, and changes or adds
entries. The entry information is read from standard input or from file through the
use of the -f option.

ldapadd options:
-b Assume that any values that start with a slash (/) are binary values, and that
the actual value is in a file whose path is specified in the place where values
normally appear.
-c Continuous operation mode. Errors are reported, but ldapmodify will continue
with modifications. The default is to exit after reporting an error.
-r Replace existing values by default.
-n Show what would be done, but do not actually modify entries. Useful for
debugging in conjunction with -v.
-v Use verbose mode, with many diagnostics written to standard output.
-R Specifies that referrals are not to be automatically followed.
-d debuglevel
Set the LDAP debugging level to debuglevel.
-D binddn
Use binddn to bind to the LDAP directory. binddn should be a
string-represented destinguished name (see “Distinguished names format” on
page 696).
-w passwd
Use passwd as the password for simple authentication.
-h ldaphost
Specify an alternate host on which the LDAP server is running.
-p ldapport
Specify an alternate TCP port where the LDAP server is listening. The default
LDAP port is 389. If not specified and Z is specified, the default LDAP SSL
port 636 is used.
-f file
Read the entry modification information from an ldif file instead of from
standard input. If an ldif file is not specified, you must use standard input to
specify the update records in ldif format.
-Z Use a secure SSL connection to communicate with the LDAP server. The Z
option is not supported by non-SSL versions of this tool.
-K keyfile
Specify the name of the SSL key ring file. If the key ring file is not in the
current directory, specify the fully-qualified key ring filename. If a key ring
filename is not specified, this utility will look for the presence of the
SSL_KEYRING environment variable with an associated filename. Otherwise,
no key ring file will be used for server authentication and default trusted
certification authority roots will be used. The key ring file typically contains
one or more certificates of certification authorities (CAs) that are trusted by the
client. These types of X.509 certificates are also known as trusted roots. See
“ldapadd SSL notes” on page 622 and ldap_ssl_start for more information
about SSL and certificates. This parameter is ignored if Z is not specified.
-P keyfilepw
Specify the key ring password. This password is required to access the

620 Client Access Express Programming


encrypted information in the key ring file (including the private key). This
parameter is ignored if Z is not specified.
-N certificatename
Specify the label associated with the client certificate in the key ring file. Note
that if the LDAP server is configured to perform Server Authentication, a client
certificate is not required. If the LDAP server is configured to perform Client
and Server Authentication, a client certificate is required. certificatename is not
required if a default certificate/private key pair has been designated as the
default (using mkkf). Similarly, certificatename is not required if there is a single
certificate/private key pair in the designated key ring file. This parameter is
ignored if Z is not specified.

ldapadd input format: The contents of file, (or by not giving a standard input
with a f flag on the command line), should conform to the “LDAP Data
Interchange Format (LDIF)” on page 697 format.

Alternative ldapadd input format: An alternative input format is supported for


compatibility with older versions of ldapmodify. This format consists of one or more
entries that are separated by blank lines, where each entry looks like the following:

Distinguished Name (DN)


attr=value
[attr=value ...]

where attr is the name of the attribute and value is the value.

By default, values are added. If the - r command line flag is given, the default is to
replace existing values with the new one. Note that it is permissible for a given
attribute to appear more than once (for example, to add more than one value for
an attribute). Also note that you can use a trailing ′\\’ to continue values across
lines and preserve newlines in the value itself. (This is useful for changing QUIPU
iattr attributes among others).

attr should be preceded by a - to remove a value. Omit the ′=’ and value to remove
an entire attribute.

Precede attr with a + to add a value in the presence of the r flag.

Examples: Using ldapadd: Assuming that the file /tmp/entrymods exists and has
the contents:

dn: cn=Modify Me, o=University of Michigan, c=US


changetype: modify
replace: mail
mail: modme@terminator.rs.itd.umich.edu
-
add: title
title: Grand Poobah
-
add: jpegPhoto
jpegPhoto: /tmp/modme.jpeg
-
delete: description
-

The command

Chapter 3. Express C/C++ APIs 621


ldapmodify -b -r -f /tmp/entrymods

will perform all the following functions.


v Replace the contents of the ″Modify Me″ entry’s mail attribute with the value
″modme@terminator.rs.itd.umich.edu″.
v Add a title of ″Grand Poobah″.
v Add the contents of the file ″/tmp/modme.jpeg″ as a jpegPhoto.
v Completely remove the description attribute.
You can perform the same modifications as above by using the older ldapmodify
inout format:

cn=Modify Me, o=University of Michigan, c=US


mail=modme@terminator.rs.itd.umich.edu
+title=Grand Poobah
+jpegPhoto=/tmp/modme.jpeg
-description

and the command

ldapmodify -b -r -f /tmp/entrymods

Assuming that the file /tmp/newentry exists and has the contents:
dn: cn=Barbara Jensen, o=University of Michigan, c=US
objectClass: person
cn: Barbara Jensen
cn: Babs Jensen
sn: Jensen
title: the world's most famous mythical manager
mail: bjensen@terminator.rs.itd.umich.edu
uid: bjensen

the command
ldapadd -f /tmp/entrymods

will add a new entry for Babs Jensen, using the values from the file
/tmp/newentry.

Assuming that the file /tmp/newentry exists and has the contents:
dn: cn=Barbara Jensen, o=University of Michigan, c=US
changetype: delete

the command
ldapmodify -f /tmp/entrymods

will remove Babs Jensen’s entry.

ldapadd notes: If entry information are not supplied from file through the use of
the -f option, the ldapmodify command will wait to read entries from standard
input. To break out of the wait, use Ctrl+C.

ldapadd SSL notes: The SSL-related functions that are described for this utility
are supported for the SSL versions of this utility only. Non-SSL versions, such as
those shipped with the Telstra LDAP/X.500 Directory Server do not include SSL
support.

622 Client Access Express Programming


The SSL versions of these utilities include RSA software.

The contents of a client’s key database file are managed with the ikmgui utility. The
ikmgui utility is used to define the set of trusted certification authorities (CAs) that
the client can trust. You can establish a trust relationship with LDAP servers that
use certificates that are issued by one of the CAs that are marked as trusted.
Accomplish this by doing the following:
1. Obtain certificates from trusted CAs.
2. Store them in the key ring file.
3. Marking them as ″trusted.″

If the LDAP servers that are accessed by the client use server authentication, it is
sufficient to define one or more trusted root certificates in the key ring file. With
server authentication, the client can know that the target LDAP server is issued a
certificate by one of the trusted CAs. In addition, all LDAP transactions that flow
over the SSL connection with the server are encrypted. (This includes the LDAP
credentials that are supplied on the ldap_bind).

For example, if the LDAP server uses a high-assurance Verisign certificate, you
should obtain a CA certificate from Verisign, import it into your key ring file, and
mark it as trusted. If the LDAP server is using a self-signed mkkf server certificate,
the administrator of the LDAP server can supply you with a copy of the server’s
certificate request file. Import the certificate request file into your key ring file and
mark it as trusted.
v Verisign is a registered trademark of Verisign, Inc.
v RSA is a trademark of RSA Data Security, Inc.
v Telstra is a registered trademarks of Telstra, Inc.
v View500 is a registered trademarks of Telstra, Inc.

ldapadd diagnostics: Exit status is 0 if no errors occur. Errors result in a non-zero


exit status and a diagnostic message that is written to standard error.

ldapdelete
ldapdelete is the LDAP delete-entry tool.
ldapdelete topics:
v “ldapdelete synopsis” on page 624
v “ldapdelete description” on page 624
v “ldapdelete options” on page 624
v “Examples: Using ldapdelete” on page 625
v “ldapdelete notes” on page 625
v “ldapdelete SSL notes” on page 625
v “ldapdelete diagnostics” on page 626
Related topics:
v “ldapadd” on page 619
v “ldapmodify” on page 626
v “ldapdelete”
v “ldapmodrdn” on page 630
v “ldapsearch” on page 633
v “IBM Lightweight Directory Access Protocol (LDAP) APIs” on page 615
v “ldap_add” on page 643
v “ldap_delete” on page 651

Chapter 3. Express C/C++ APIs 623


ldapdelete synopsis: ldapdelete [-n] [-v] [-c] [-R] [-d debuglevel] [-f file] [-D
binddn] [-w passwd] [-h ldaphost] [-p ldapport] [-Z] [-K keyfile] [-P keyfilepw]
[-N certificatename] [-b searchbase] [dn]...

ldapdelete description: ldapdelete is a shell-accessible interface to the ldapdelete


library call.

ldapdelete opens a connection to an LDAP server, binds, and deletes one or more
entries. If one or more dn arguments are provided, entries with those distinguished
names are deleted. Each dn should be a string-represented distinguished name (see
“Distinguished names format” on page 696). By providing no dn arguments, a list
of distinguished names is read from standard input (or from file when using the -f
flag).

ldapdelete options:
-n Show what would be done, but do not actually modify entries. Useful for
debugging in conjunction with -v.
-v Use verbose mode, with many diagnostics written to standard output.
-c Continuous operation mode. Errors are reported, but ldapdelete will continue
with deletions. The default is to exit after reporting an error.
-R Specifies that referrals are not to be automatically followed.
-d debuglevel
Set the LDAP debugging level to debuglevel.
-f file
Read a series of lines from file, performing one LDAP delete for each line. In
this case, the filter given on the command line is treated as a pattern where the
first occurrence of % is replaced with a line from file.
-D binddn
Use binddn to bind to the LDAP directory. binddn should be a
string-represented distinguished name (see “Distinguished names format” on
page 696).
-w passwd
Use passwd as the password for simple authentication.
-h ldaphost
Specify an alternate host on which the LDAP server is running.
-p ldapport
Specify an alternate TCP port where the LDAP server is listening. The default
LDAP port is 389. If not specified and Z is specified, the default LDAP SSL
port 636 is used.
-Z Use a secure SSL connection to communicate with the LDAP server. The Z
option is not supported by non-SSL versions of this tool.
-K keyfile
Specify the name of the SSL key ring file. If the key ring file is not in the
current directory, specify the fully-qualified key ring filename. If a key ring
filename is not specified, this utility will look for the presence of the
SSL_KEYRING environment variable with an associated filename. Otherwise,
no key ring file will be used for server authentication and default trusted
certification authority roots will be used. The key ring file typically contains
one or more certificates of certification authorities (CAs) that are trusted by the
client. These types of X.509 certificates are also known as trusted roots. Also

624 Client Access Express Programming


see “ldapadd SSL notes” on page 622 and ldap_ssl_start for more information
about SSL and certificates. This parameter is ignored if Z is not specified.
-P keyfilepw
Specify the key ring password. This password is required to access the
encrypted information in the key ring file (including the private key). This
parameter is ignored if Z is not specified.
-N certificatename
Specify the label associated with the client certificate in the key ring file. Note
that if the LDAP server is configured to perform Server Authentication, a client
certificate is not required. If the LDAP server is configured to perform Client
and Server Authentication, a client certificate is required. certificatename is not
required if a default certificate/private key pair has been designated as the
default (using mkkf). Similarly, certificatename is not required if there is a single
certificate/private key pair in the designated key ring file. This parameter is
ignored if Z is not specified.
-b searchbase
Use searchbase as the starting point for the search instead of the default. If -b is
not specified, this utility will examine the LDAP_BASEDN environment
variable for a searchbase definition.
-dn
Specifies one or more dn arguments. Each dn should be a string-represented
distinguished name (see “Distinguished names format” on page 696).

Examples: Using ldapdelete: The following command:


ldapdelete "cn=Delete Me, o=University of Michigan, c=US

attempts to delete the entry named with commonName ″Delete Me″ directly below
the University of Michigan organizational entry. It may be necessary to supply a
binddn and passwd for deletion to are allowed (refer to the -D and -w options).

ldapdelete notes: If no dn arguments are provided, the ldapdelete command will


wait to read a list of distinguished names from standard input. To break out of the
wait, use Ctrl+C.

ldapdelete SSL notes: The SSL-related functions that are described for this utility
are supported for the SSL versions of this utility only. Non-SSL versions, such as
those shipped with the Telstra LDAP/X.500 Directory Server do not include SSL
support.

The SSL versions of these utilities include RSA software.

The contents of a client’s key database file is managed with the ikmgui utility. The
ikmgui utility is used to define the set of trusted certification authorities (CAs) that
the client can trust. You can establish a trust relationship with LDAP servers that
use certificates that are issued by one of the CAs that are marked as trusted.
Accomplish this by doing the following.
1. Obtain certificates from trusted CAs.
2. Store them in the key ring file.
3. Mark them as ″trusted.″

If the LDAP servers that are accessed by the client use server authentication, it is
sufficient to define one or more trusted root certificates in the key ring file. With
server authentication, the client can know that the target LDAP server is issued a

Chapter 3. Express C/C++ APIs 625


certificate by one of the trusted CAs. In addition, all LDAP transactions that flow
over the SSL connection with the server is encrypted. (This includes the LDAP
credentials that are supplied on the ldap_bind).

For example, if the LDAP server uses a high-assurance Verisign certificate, you
should obtain a CA certificate from Verisign, import it into your key ring file, and
mark it as trusted. If the LDAP server is using a self-signed mkkf server certificate,
the administrator of the LDAP server can supply you with a copy of the server’s
certificate request file. Import the certificate request file into your key ring file and
mark it as trusted.
v Verisign is a registered trademark of Verisign, Inc.
v RSA is a trademark of RSA Data Security, Inc.
v Telstra is a registered trademarks of Telstra, Inc.
v View500 is a registered trademarks of Telstra, Inc.

ldapdelete diagnostics: Exit status is 0 if no errors occur. Errors result in a


non-zero exit status and a diagnostic message that is written to standard error.

ldapmodify
ldapmodify is the LDAP change-entry tool.
ldapmodify topics:
v “ldapmodify synopsis”
v “ldapmodify description” on page 627
v “ldapmodify options” on page 627
v “ldapmodify input format” on page 628
v “Alternative ldapmodify input format” on page 628
v “Examples: Using ldapmodify” on page 628
v “ldapmodify notes” on page 630
v “ldapmodify SSL notes” on page 630
v “ldapmodify diagnostics” on page 630
Related topics:
v “ldapadd” on page 619
v “ldapdelete” on page 623
v “ldapmodrdn” on page 630
v “ldapsearch” on page 633
v “IBM Lightweight Directory Access Protocol (LDAP) APIs” on page 615
v “ldap_add” on page 643
v “ldap_delete” on page 651
v “ldap_modify” on page 676
v “ldap_rename” on page 681
v “ldap_ssl” on page 689
v “LDAP Data Interchange Format (LDIF)” on page 697
v “ldap_get_dn” on page 662

ldapmodify synopsis: ldapmodify [-a] [-b] [-c] [-r] [-n] [-v] [-F] [-R] [-d
debuglevel] [-D binddn] [-w passwd] [-h ldaphost] [-p ldapport] [-f file] [-Z] [-K
keyfile] [-P keyfilepw] [-N certificatename]

626 Client Access Express Programming


ldapmodify description: ldapmodify is a shell-accessible interface to the
ldap_modify and ldap_addlibrary calls. ldapadd is put into effect as a renamed
version of ldapmodify. When started as ldapadd the -a (add-new entry) flag turns
on automatically.

ldapmodify opens a connection to an LDAP server, binds, and changes or adds


entries. The entry information is read from standard input or from file through the
use of the -f option.

ldapmodify options:
-a Add new entries. The default for ldapmodify is to modify existing entries. If
invoked as ldapadd, this flag is always set.
-b Assume that any values that start with a ′/’ are binary values and that the
actual value is in a file whose path is specified in the place where values
normally appear.
-c Continuous operation mode. Errors are reported, but ldapmodify will continue
with modifications. The default is to exit after reporting an error.
-r Replace existing values by default.
-n Show what would be done, but do not actually modify entries. Useful for
debugging in conjunction with -v.
-v Use verbose mode, with many diagnostics written to standard output.
-F Force application of all changes regardless of the contents of input lines that
begin with replica: (by default, replica: lines are compared against the LDAP
server host and port in use to decide if a replog record should actually be
applied).
-R Specifies that referrals are not to be automatically followed.
-d debuglevel
Set the LDAP debugging level to debuglevel.
-D binddn
Use binddn to bind to the LDAP directory. binddn should be a
string-represented distinguished name (see “Distinguished names format” on
page 696).
-w passwd
Use passwd as the password for simple authentication.
-h ldaphost
Specify an alternate host on which the LDAP server is running.
-p ldapport
Specify an alternate TCP port where the LDAP server is listening. The default
LDAP port is 389. If not specified and Z is specified, the default LDAP SSL
port 636 is used.
-f file
Read the entry modification information from an ldif file instead of from
standard input. If an ldif file is not specified, you must use standard input to
specify the update records in ldif format.
-Z Use a secure SSL connection to communicate with the LDAP server. The Z
option is not supported by non-SSL versions of this tool.
-K keyfile
Specify the name of the SSL key ring file. If the key ring file is not in the

Chapter 3. Express C/C++ APIs 627


current directory, specify the fully-qualified key ring filename. If a key ring
filename is not specified, this utility will look for the presence of the
SSL_KEYRING environment variable with an associated filename. Otherwise,
no key ring file will be used for server authentication and default trusted
certification authority roots will be used. The key ring file typically contains
one or more certificates of certification authorities (CAs) that are trusted by the
client. These types of X.509 certificates are also known as trusted roots. See
“ldapadd SSL notes” on page 622 and ldap_ssl_start for more information
about SSL and certificates. This parameter is ignored if Z is not specified.
-P keyfilepw
Specify the key ring password. This password is required to access the
encrypted information in the key ring file (including the private key). This
parameter is ignored if Z is not specified.
-N certificatename
Specify the label associated with the client certificate in the key ring file. Note
that if the LDAP server is configured to perform Server Authentication, a client
certificate is not required. If the LDAP server is configured to perform Client
and Server Authentication, a client certificate is required. certificatename is not
required if a default certificate/private key pair has been designated as the
default (using mkkf). Similarly, certificatename is not required if there is a single
certificate/private key pair in the designated key ring file. This parameter is
ignored if Z is not specified.

ldapmodify input format: The contents of file, (or standard input if no f flag is
given on the command line), should conform to the “LDAP Data Interchange
Format (LDIF)” on page 697 format.

Alternative ldapmodify input format: An alternative input format is supported


for compatibility with older versions of ldapmodify. This format consists of one or
more entries that are separated by blank lines, where each entry looks like the
following:
Distinguished Name (DN)
attr=value
[attr=value ...]

where attr is the name of the attribute and value is the value.

By default, values are added. If the - r command line flag is given, the default is to
replace existing values with the new one. Note that it is permissible for a given
attribute to appear more than once (for example, to add more than one value for
an attribute). Also note that you can use a trailing ′\\’ to continue values across
lines and preserve newlines in the value itself. (This is useful for modifying
QUIPU iattr attributes among others).

attr should be preceded by a - to remove a value. Omit the ′=’ and value to remove
an entire attribute.

Precede attr with a + to add a value in the presence of the r flag.

Examples: Using ldapmodify: Assuming that the file /tmp/entrymods exists and
has the contents:
dn: cn=Modify Me, o=University of Michigan, c=US
changetype: modify
replace: mail
mail: modme@terminator.rs.itd.umich.edu
-

628 Client Access Express Programming


add: title
title: Grand Poobah
-
add: jpegPhoto
jpegPhoto: /tmp/modme.jpeg
-
delete: description
-

The command
ldapmodify -b -r -f /tmp/entrymods

will complete the following tasks.


v Replace the contents of the ″Modify Me″ entry’s mail attribute with the value
″modme@terminator.rs.itd.umich.edu″.
v Add a title of ″Grand Poobah″.
v Add the contents of the file ″/tmp/modme.jpeg″ as a jpegPhoto.
v Completely remove the description attribute.
You can perform the same modifications as above by using the older ldapmodify
inout format:
cn=Modify Me, o=University of Michigan, c=US
mail=modme@terminator.rs.itd.umich.edu
+title=Grand Poobah
+jpegPhoto=/tmp/modme.jpeg
-description

and the command


ldapmodify -b -r -f /tmp/entrymods

Assuming that the file /tmp/newentry exists and has the contents:
dn: cn=Barbara Jensen, o=University of Michigan, c=US
objectClass: person
cn: Barbara Jensen
cn: Babs Jensen
sn: Jensen
title: the world's most famous mythical manager
mail: bjensen@terminator.rs.itd.umich.edu
uid: bjensen

the command
ldapadd -f /tmp/entrymods

will add a new entry for Babs Jensen, using the values from the file
/tmp/newentry.

Assuming that the file /tmp/newentry exists and has the contents:
dn: cn=Barbara Jensen, o=University of Michigan, c=US
changetype: delete

the command
ldapmodify -f /tmp/entrymods

will remove Babs Jensen’s entry.

Chapter 3. Express C/C++ APIs 629


ldapmodify notes: If entry information does not are supplied from file through
the use of the -f option, the ldapmodify command will wait to read entries from
standard input. To break out of the wait, use Ctrl+C.

ldapmodify SSL notes: The SSL-related functions that are described for this
utility are supported for the SSL versions of this utility only. Non-SSL versions,
such as those shipped with the Telstra LDAP/X.500 Directory Server do not
include SSL support.

The SSL versions of these utilities include RSA software.

The contents of a client’s key database file is managed with the ikmgui utility. The
mkkf utility is used to define the set of trusted certification authorities (CAs) that
the client can trust. You can establish a trust relationship with LDAP servers that
use certificates that are issued by one of the CAs that are marked as trusted.
Accomplish this by doing the following.
1. Obtain certificates from trusted CAs.
2. Store them in the key ring file.
3. Mark them as ″trusted.″

If the LDAP servers that are accessed by the client use server authentication, it is
sufficient to define one or more trusted root certificates in the key ring file. With
server authentication, the client can know that the target LDAP server is issued a
certificate by one of the trusted CAs. In addition, all LDAP transactions that flow
over the SSL connection with the server are encrypted. (This includes the LDAP
credentials that are supplied on the ldap_bind.

For example, if the LDAP server uses a high-assurance Verisign certificate, you
should obtain a CA certificate from Verisign, import it into your key ring file, and
mark it as trusted. If the LDAP server is using a self-signed mkkf server certificate,
the administrator of the LDAP server can supply you with a copy of the server’s
certificate request file. Import the certificate request file into your key ring file and
mark it as trusted.
v Verisign is a registered trademark of Verisign, Inc.
v RSA is a trademark of RSA Data Security, Inc.
v Telstra is a registered trademarks of Telstra, Inc.
v View500 is a registered trademarks of Telstra, Inc.

ldapmodify diagnostics: Exit status is 0 if no errors occur. Errors result in a


non-zero exit status and a diagnostic message that is written to standard error.

ldapmodrdn
ldapmodrdn is the LDAP change-entry RDN tool.
ldapmodrdn topics:
v “ldapmodrdn synopsis” on page 631
v “ldapmodrdn description” on page 631
v “ldapmodrdn options” on page 631
v “ldapmodrdn input format” on page 632
v “Examples: Using ldapmodrdn” on page 632
v “ldapmodrdn notes” on page 632
v “ldapmodrdn SSL notes” on page 633
v “ldapmodrdn diagnostics” on page 633
Related topics:

630 Client Access Express Programming


v “ldapadd” on page 619
v “ldapmodify” on page 626
v “ldapdelete” on page 623
v “ldapmodrdn” on page 630
v “ldapsearch” on page 633
v “IBM Lightweight Directory Access Protocol (LDAP) APIs” on page 615
v “ldap_add” on page 643
v “ldap_delete” on page 651

ldapmodrdn synopsis: ldapmodrdn [-r] [-n] [-v] [-c] [-R] [-d debuglevel] [-D
binddn] [-w passwd] [-h ldaphost] [-p ldapport] [-f file] [-Z] [-K keyfile] [-P
keyfilepw] [-N certificatename]

ldapmodrdn description: ldapmodrdn is a shell-accessible interface to the


ldap_modrdn library call.

ldapmodrdn opens a connection to an LDAP server, binds, and changes the RDN
of entries. The entry information is read from standard input, from file through the
use of the - f option, or from the command-line pair dn and rdn.

See “Distinguished names format” on page 696 for information about relative
distinguished names and distinguished names.

ldapmodrdn options:
-r Remove old RDN values from the entry. Default is to keep old values.
-n Show what would be done, but do not actually modify entries. Useful for
debugging in conjunction with -v.
-v Use verbose mode, with many diagnostics written to standard output.
-c Continuous operation mode. Errors are reported, but ldapmodify will continue
with modifications. The default is to exit after reporting an error.
-R Specifies that referrals are not to be automatically followed.
-d debuglevel
Set the LDAP debugging level to debuglevel.
-D binddn
Use binddn to bind to the LDAP directory. binddn should be a
string-represented distinguished name (see “Distinguished names format” on
page 696).
-w passwd
Use passwd as the password for simple authentication.
-h ldaphost
Specify an alternate host on which the LDAP server is running.
-p ldapport
Specify an alternate TCP port where the LDAP server is listening. The default
LDAP port is 389. If not specified and Z is specified, the default LDAP SSL
port 636 is used.
-f file
Read the entry modification information from an ldif file instead of from
standard input. If an ldif file is not specified, you must use standard input to
specify the update records in ldif format.

Chapter 3. Express C/C++ APIs 631


-Z Use a secure SSL connection to communicate with the LDAP server. The Z
option is not supported by non-SSL versions of this tool.
-K keyfile
Specify the name of the SSL key ring file. If the key ring file is not in the
current directory, specify the fully-qualified key ring filename. If a key ring
filename is not specified, this utility will look for the presence of the
SSL_KEYRING environment variable with an associated filename. Otherwise,
no key ring file will be used for server authentication and default trusted
certification authority roots will be used. The key ring file typically contains
one or more certificates of certification authorities (CAs) that are trusted by the
client. These types of X.509 certificates are also known as trusted roots. See
“ldapadd SSL notes” on page 622 and ldap_ssl_start for more information
about SSL and certificates. This parameter is ignored if Z is not specified.
-P keyfilepw
Specify the key ring password. This password is required to access the
encrypted information in the key ring file (including the private key). This
parameter is ignored if Z is not specified.
-N certificatename
Specify the label associated with the client certificate in the key ring file. Note
that if the LDAP server is configured to perform Server Authentication, a client
certificate is not required. If the LDAP server is configured to perform Client
and Server Authentication, a client certificate is required. certificatename is not
required if a default certificate/private key pair has been designated as the
default (using mkkf). Similarly, certificatename is not required if there is a single
certificate/private key pair in the designated key ring file. This parameter is
ignored if Z is not specified.

ldapmodrdn input format: by giving the command-line arguments dn and rdn,


rdn will replace the RDN of the entry that is specified by the DN, dn.

Otherwise, the contents of file, (or by not giving a standard input with a - f flag),
should consist of one or more entries.
Distinguished Name (DN)
Relative Distinguished Name (RDN)

One or more blank lines may be used to separate each DN/RDN pair.

Examples: Using ldapmodrdn: Assuming that the file /tmp/entrymods exists and
has the contents:
cn=Modify Me, o=University of Michigan, c=US
cn=The New Me

the command
ldapmodrdn -r -f /tmp/entrymods

will change the RDN of the ″Modify Me″ entry from ″Modify Me″ to ″The New
Me″ and the old cn, ″Modify Me″ will be removed.

ldapmodrdn notes: The ldapmodrdn command will wait to read entries from
standard input under the following conditions.
v When entry information does not are supplied from file through the use of the -f
option.
v When entry information does not are supplied from the command-line pair dn
and rdn.

632 Client Access Express Programming


To break out of the wait, use Ctrl+C.

ldapmodrdn SSL notes: The SSL-related functions that are described for this
utility are supported for the SSL versions of this utility only. Non-SSL versions,
such as those shipped with the Telstra LDAP/X.500 Directory Server do not
include SSL support.

The SSL versions of these utilities include RSA software.

The contents of a client’s key database file is managed with the ikmgui utility. The
ikmgui utility is used to define the set of trusted certification authorities (CAs) that
the client can trust. You can establish a trust relationship with LDAP servers that
use certificates that are issued by one of the CAs that are marked as trusted.
Accomplish this by doing the following.
1. Obtain certificates from trusted CAs.
2. Store them in the key ring file.
3. Mark them as ″trusted.″

If the LDAP servers that are accessed by the client use server authentication, it is
sufficient to define one or more trusted root certificates in the key ring file. With
server authentication, the client can know that the target LDAP server is issued a
certificate by one of the trusted CAs. In addition, all LDAP transactions that flow
over the SSL connection with the server are encrypted. (This includes the LDAP
credentials that are supplied on the ldap_bind.

For example, if the LDAP server uses a high-assurance Verisign certificate, you
should obtain a CA certificate from Verisign, import it into your key ring file, and
mark it as trusted. If the LDAP server is using a self-signed mkkf server certificate,
the administrator of the LDAP server can supply you with a copy of the server’s
certificate request file. Import the certificate request file into your key ring file and
mark it as trusted.
v Verisign is a registered trademark of Verisign, Inc.
v RSA is a trademark of RSA Data Security, Inc.
v Telstra is a registered trademarks of Telstra, Inc.
v View500 is a registered trademarks of Telstra, Inc.

ldapmodrdn diagnostics: Exit status is 0 if no errors occur. Errors result in a


non-zero exit status and a diagnostic message that is written to standard error.

ldapsearch
ldapsearch is the LDAP search tool.
ldapsearch topics:
v “ldapsearch synopsis” on page 634
v “ldapsearch description” on page 634
v “ldapsearch options” on page 634
v “ldapsearch output format” on page 636
v “Examples: Using ldapsearch” on page 636
v “ldapsearch SSL notes” on page 637
v “ldapsearch diagnostics” on page 638
Related topics:
v “ldapadd” on page 619
v “ldapmodify” on page 626
v “ldapmodrdn” on page 630
v “ldap_add” on page 643

Chapter 3. Express C/C++ APIs 633


v “ldap_delete” on page 651
v “LDAP Data Interchange Format (LDIF)” on page 697

ldapsearch synopsis: ldapsearch [-3] [-n] [-v] [-t] [-A] [-B] [-L] [-R] [-d
debuglevel] [-F sep] [-f file] [-D binddn] [-w bindpasswd] [-h ldaphost] [-p
ldapport] [-Z] [-K keyfile] [-P keyfilepw] [-N certificatename] [-b searchbase] [-s
scope ] [-a deref] [-l time limit] [-z size limit] filter [attrs....]

ldapsearch description: ldapsearch is a shell-accessible interface to the ldap_search


library call.

ldapsearch opens a connection to an LDAP server, binds, and performs a search by


using the filter filter. The fileter should conform to the string representation for
LDAP filters (see “ldap_search” on page 685 for more information on filters).

If ldapsearch finds one or more entries, the attributes that are specified by attrs are
retrieved, and the entries and values are printed to standard output. If no attrs are
listed, all attributes are returned.

ldapsearch options:
-3 Specifies that ldapsearch should run as an LDAP V3 application. This consists
of using ldap_init and ldap_simple_bind_s instead of ldap_open
andldap_bind_s.
-n Show what would be done, but do not actually modify entries. Useful for
debugging in conjunction with -v.
-v Use verbose mode, with many diagnostics written to standard output.
-t Write retrieved values to a set of temporary files. This is useful for dealing
with non-ASCII values such as jpegPhoto or audio.
-A Retrieve attributes only (no values). This is useful when you just want to see if
an attribute is present in an entry and are not interested in the specific values.
-B Do not suppress display of non-ASCII values. This is useful when dealing with
values that appear in alternate characters sets such as ISO-8859.1. This option
is implied by -L (see below).
-L Display search results in ldif format. This option also turns on the -B option,
and causes the -F option to be ignored.
-R Specifies that referrals are not to be automatically followed.
-d debuglevel
Set the LDAP debugging level to debuglevel.
-F sep
Use sep as the field separator between attribute names and values. The default
separator is ′=’, unless the -L flag has been specified, in which case this option
is ignored.
-f file
Read a series of lines from file, performing one LDAP search for each line. In
this case, the filter given on the command line is treated as a pattern where the
first occurrence of %s is replaced with a line from file. If file is a single -
character, then the lines are read from standard input.

634 Client Access Express Programming


-D binddn
Use binddn to bind to the LDAP directory. binddn should be a
string-represented distinguished name (see “Distinguished names format” on
page 696).
-w passwd
Use passwd as the password for simple authentication.
-h ldaphost
Specify an alternate host on which the LDAP server is running.
-p ldapport
Specify an alternate TCP port where the LDAP server is listening. The default
LDAP port is 389. If not specified and Z is specified, the default LDAP SSL
port 636 is used.
-Z Use a secure SSL connection to communicate with the LDAP server. The Z
option is not supported by non-SSL versions of this tool.
-K keyfile
Specify the name of the SSL key ring file. If the key ring file is not in the
current directory, specify the fully-qualified key ring filename. If a key ring
filename is not specified, this utility will look for the presence of the
SSL_KEYRING environment variable with an associated filename. Otherwise,
no key ring file will be used for server authentication and default trusted
certification authority roots will be used. The key ring file typically contains
one or more certificates of certification authorities (CAs) that are trusted by the
client. These types of X.509 certificates are also known as trusted roots. See
“ldapadd SSL notes” on page 622 and ldap_ssl_start for more information
about SSL and certificates. This parameter is ignored if Z is not specified.
-P keyfilepw
Specify the key ring password. This password is required to access the
encrypted information in the key ring file (including the private key). This
parameter is ignored if Z is not specified.
-N certificatename
Specify the label associated with the client certificate in the key ring file. Note
that if the LDAP server is configured to perform Server Authentication, a client
certificate is not required. If the LDAP server is configured to perform Client
and Server Authentication, a client certificate is required. certificatename is not
required if a default certificate/private key pair has been designated as the
default (using mkkf). Similarly, certificatename is not required if there is a single
certificate/private key pair in the designated key ring file. This parameter is
ignored if Z is not specified.
-b searchbase
Use searchbase as the starting point for the search instead of the default. If -b is
not specified, this utility will examine the LDAP_BASEDN environment
variable for a searchbase definition.
-s scope
Specify the scope of the search. scope should be one of base, one, or sub to
specify a base object, one-level, or subtree search. The default is sub.
-a deref
Specify how aliases dereferencing is done. deref should be one of never,
always, search, or findto specify that aliases are never dereferenced, always
dereferenced, dereferenced when searching, or dereferenced only when locating
the base object for the search. The default is to never dereference aliases.

Chapter 3. Express C/C++ APIs 635


-l timelimit
Wait at most timelimit seconds for a search to complete.
-z sizelimit
Limit the results of the search to at most sizelimit entries. This makes it possible
to place an upper bound on the number of entries that are returned for a
search operation.

ldapsearch output format: If one or more entries are found, each entry is written
to standard output in the form:
Distinguished Name (DN)
attributename=value
attributename=value
attributename=value
...

Multiple entries are separated with a single blank line. If the -F option is used to
specify a separator character, it is used instead of the ′=’ character. By using the -t
option, the name of a temporary file is used in place of the actual value. By giving
the -A option, only the ″attributename″ part is written.

Examples: Using ldapsearch: The following command performs a subtree search (


by using the default search base) for entries with a commonName of ″mark smith″:
ldapsearch "cn=mark smith" cn telephoneNumber

The commonName and telephoneNumber values are retrieved and printed to


standard output. The output might look something like this if two entries are
found:
cn=Mark D Smith, ou="College of Literature, Science,
and the Arts",
ou=Students, ou=People, o=University of Michigan, c=US
cn=Mark Smith
cn=Mark David Smith
cn=Mark D Smith 1
cn=Mark D Smith
telephoneNumber=+1 313 555-9489

cn=Mark C Smith, ou=Information Technology Division,


ou=Faculty and Staff,
ou=People, o=University of Michigan, c=US
cn=Mark Smith
cn=Mark C Smith 1
cn=Mark C Smith
telephoneNumber=+1 313 555-2277

The following command performs a subtree search by using the default search
base for entries with user ID of ″mcs″:
ldapsearch -t "uid=mcs" jpegPhoto audio

The jpegPhoto and audio values are retrieved and written to temporary files. The
output might look like this if one entry with one value for each of the requested
attributes are found:
cn=Mark C Smith, ou=Information Technology Division,
ou=Faculty and Staff,
ou=People, o=University of Michigan, c=US
audio=/tmp/ldapsearch-audio-a19924
jpegPhoto=/tmp/ldapsearch-jpegPhoto-a19924

The following command performs a one-level search at the c=US level for all
organizations whose organizationName begins with university:

636 Client Access Express Programming


ldapsearch -L -s one -b "c=US" "o=university*" o description

Search results display in the LDIF format (see ldif for more information on LIDF
format). The organizationName and description attribute values are retrieved and
printed to standard output, resulting in output similar to this:
dn: o=University of Alaska Fairbanks, c=US
o: University of Alaska Fairbanks
description: Preparing Alaska for a brave new tomorrow
description: leaf node only

dn: o=University of Colorado at Boulder, c=US


o: University of Colorado at Boulder
description: No personnel information
description: Institution of education and research

dn: o=University of Colorado at Denver, c=US


o: University of Colorado at Denver
o: UCD
o: CU/Denver
o: CU-Denver
description: Institute for Higher Learning and Research

dn: o=University of Florida, c=US


o: University of Florida
o: UFl
description: Shaper of young minds

And so forth...

ldapsearch SSL notes: The SSL-related functions that are described for this utility
are supported for the SSL versions of this utility only. Non-SSL versions, such as
those shipped with the Telstra LDAP/X.500 Directory Server do not include SSL
support.

The SSL versions of these utilities include RSA software.

The contents of a client’s key ring file is managed with the ikmgui utility. The
ikmgui utility is used to define the set of trusted certification authorities (CAs) for
the client to trust.
To establish a trust relationship with LDAP servers:
Follow these steps to establish a trust relationship with LDAP servers that
use certificates which are issued by trusted CAs:
1. Obtain certificates from trusted CAs.
2. Store them in the key ring file.
3. Mark them as ″trusted.″

If the LDAP servers that are accessed by the client use server authentication, it is
sufficient to define one or more trusted root certificates in the key ring file. With
server authentication, the client can know that the target LDAP server is issued a
certificate by one of the trusted CAs. In addition, all LDAP transactions that flow
over the SSL connection with the server are encrypted. (This includes the LDAP
credentials that are supplied on the ldap_bind.

For example, if the LDAP server uses a high-assurance Verisign certificate, you
should obtain a CA certificate from Verisign, import it into your key ring file, and
mark it as trusted. If the LDAP server is using a self-signed mkkf server certificate,

Chapter 3. Express C/C++ APIs 637


the administrator of the LDAP server can supply you with a copy of the server’s
certificate request file. Import the certificate request file into your key ring file and
mark it as trusted.
v Verisign is a registered trademark of Verisign, Inc.
v RSA is a trademark of RSA Data Security, Inc.
v Telstra is a registered trademarks of Telstra, Inc.
v View500 is a registered trademarks of Telstra, Inc.

ldapsearch diagnostics: Exit status is 0 if no errors occur. Errors result in a


non-zero exit status and a diagnostic message that is written to standard error.

LDAP controls
Certain LDAP Version 3 operations can be extended with the use of controls. The
possibility exists to send controls to a server, or return them to the client with any
LDAP message. This type of control is called server control.

The LDAP API also supports a client-side extension mechanism usage which
defines client controls. The client-side controls affect the behavior of the LDAP
client library, and never are sent to the server. Note that no client-side controls
definition exists for this client library.
Example: Using LDAPControl:
IBM uses a common data structure to represent both server-side and
client-side controls:
typedef struct ldapcontrol {
char *ldctl_oid;
struct berval ldctl_value;
char ldctl_iscritical;
} LDAPControl, *PLDAPControl;
LDAPControl fields definitions:
The LDAPControl fields have the following definitions:
ldctl_oid
Specifies the control type, represented as a string.
ldctl_value
Specifies the data that is associated with the control. Note that the
control may not include data.
ldctl_iscritical
Specifies whether the control is critical. If the field is non-zero, the
operation carries out only if recognized and supported by the
server (or the client for client-side controls).

LDAP APIs listing


The following LDAP APIs (and their related APIs) are listed in alphabetical order:

LDAP API Related LDAP APIs


ldap_abandon ldap_abandon
ldap_abandon_ext
ldap_add ldap_add
ldap_add_s
ldap_add_ext
ldap_add_ext_s

638 Client Access Express Programming


LDAP API Related LDAP APIs
ldap_bind ldap_bind
ldap_bind_s
ldap_simple_bind
ldap_simple_bind_s
ldap_sasl_bind
ldap_sasl_bind_s
ldap_unbind
ldap_unbind_s
ldap_set_rebind_proc
ldap_compare ldap_compare
ldap_compare_s
ldap_compare_ext
ldap_compare_ext_s
ldap_delete ldap_delete
ldap_delete_s
ldap_delete_ext
ldap_delete_ext_s
ldap_error ldap_get_errno
ldap_perror
ldap_result2error
ldap_first_attribute ldap_first_attribute
ldap_next_attribute
ldap_count_attributes
ldap_first_entry ldap_first_entry
ldap_next_entry
ldap_count_entries
ldap_first_reference ldap_first_reference
ldap_next_reference
ldap_count_references
ldap_get_dn ldap_get_dn
ldap_explode_dn
ldap_get_values ldap_get_values
ldap_get_values_len
ldap_count_values
ldap_count_values_len
ldap_value_free
ldap_value_free_len
ldap_init ldap_init
ldap_open
ldap_get_option
ldap_set_option
ldap_version
ldap_memfree ldap_memfree
ldap_control_free
ldap_controls_free
ldap_message ldap_first_message
ldap_next_message
ldap_count_message
ldap_modify ldap_modify
ldap_modify_s
ldap_modify_ext
ldap_modify_ext_s
ldap_mods_free

Chapter 3. Express C/C++ APIs 639


LDAP API Related LDAP APIs
ldap_parse_results ldap_parse_result
ldap_parse_sasl_bind_result
ldap_err2string
ldap_rename ldap_rename
ldap_rename_s
ldap_modrdn
ldap_modrdn_s
ldap_result ldap_result
ldap_msgfree
ldap_msgtype
ldap_msgid
ldap_search ldap_search
ldap_search_s
ldap_search_ext
ldap_search_ext_s
ldap_search_st
ldap_ssl ldap_ssl_init
ldap_ssl_client
ldap_ssl_start
ldap_url ldap_is_ldap_url
ldap_url_parse
ldap_free_urldesc
ldap_url_search
ldap_url_search_s
ldap_url_search_st

640 Client Access Express Programming


ldap_abandon
Purpose: Abandon an LDAP operation in progress.

Syntax:
#include <ldap.h>

int ldap_abandon(
LDAP *ld,
int msgid)

int ldap_abandon_ext(
LDAP *ld,
int msgid,
LDAPControl **serverctrls,
LDAPControl **clientctrls)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
msgid
The message ID of an outstanding LDAP operation, as returned by a call to an
asynchronous LDAP operation such as ldap_search and ldap_modify, and so
forth.
serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.
clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.

Return Codes:
ldap_abandon
This error returns 0 if the operation is successful, -1 otherwise, setting
ld_errno appropriately. ldap_abandon_ext returns LDAP_SUCCESS if
successful, and returns an LDAP error code if unsuccessful. See
“ldap_error” on page 653 for details.

Usage: Use the ldap_abandon and ldap_abandon_ext APIs to abandon or cancel


an LDAP operation in progress. The msgid that is passed should be the message ID
of an outstanding LDAP operation, as returned by a call to an asynchronous LDAP
operation such as ldap_search, ldap_modify, and so forth.

Both APIs check to see if the server previously returned the result of the operation.
If it has, it deletes it from the queue of pending messages. If not, it sends an LDAP
abandon operation to the LDAP server.

The caller can expect that the result of an abandoned operation will not return
from a future call to ldap_result.

The ldap_abandon_ext API returns the constant LDAP_SUCCESS if the abandon


was successful, or an LDAP error code if unsuccessful. The ldap_abandon API
returns zero if the abandon is successful, -1 otherwise, and does not support LDAP
V3 server controls or client controls. The ldap_abandon_ent API returns the
constant LDAP_SUCCESS if the abandon is successful, or an LDAP error code if

Chapter 3. Express C/C++ APIs 641


unsuccessful.

642 Client Access Express Programming


ldap_add
Purpose: Perform an LDAP operation to add an entry.

Syntax:
#include <ldap.h>

int ldap_add(
LDAP *ld,
char *dn,
LDAPMod *attrs[])

int ldap_add_s(
LDAP *ld,
char *dn,
LDAPMod *attrs[])

int ldap_add_ext(
LDAP *ld,
char *dn,
LDAPMod *attrs[]
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_add_ext_s(
LDAP *ld,
char *dn,
LDAPMod *attrs[]
LDAPControl **serverctrls,
LDAPControl **clientctrls)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn The DN of an entry to add.
attrs
The entry’s attributes, specified using the LAPMod structure, as defined for
ldap_modify. Fill in the mod_type and mod_vals fields, if not already done. The
mod_op field remains ignored unless the use of ORed with the constant
LDAP_MOD_BVALUES. In this case, the mod_op field is used to select the
mod_bvalues case of the mod_vals union.
serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.
clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: ldap_add returns -1 in case of error initiating the request.


ldap_add_s and ldap_add_ext_s will return an LDAP error code directly
(LDAP_SUCCESS if the call was successful. Otherwise an LDAP error is returned).

Chapter 3. Express C/C++ APIs 643


Usage: Use the ldap_add and associated APIs to perform an LDAP add operation.
They take dn, the DN of the entry to add, and attrs, a NULL-terminated array of
the entry’s attributes. The LDAPMod structure (for ldap_modify) is used to
represent attributes, with the mod_type and mod_values fields being filled in and
used as described for ldap_modify. The system ignores the mod_op field unless
ORed with the constant LDAP_MOD_BVALUES. In this instance, the mod_op field
is used to select the mod_bvalues case of the mod_vals union.

Note that all entries except those that are specified by the last component in the
given DN must already exist.

The ldap_add_ext API initiates an asynchronous add operation and returns the
constant LDAP_SUCCESS if the request was successfully sent, or another LDAP
error code if not. If successful, ldap_add_ext places the message ID of the request
in *msgidp. A subsequent call to ldap_result can be used to obtain the result of the
operation. Once the operation has completed, ldap_result returns a result that
contains the status of the operation (in the form of an error code). The error code
indicates if the operation completed successfully. The ldap_parse_result API is
used to check the error code in the result.

Similarly, the ldap_add API initiates an asynchronous add operation and returns
the message ID of the operation initiated. A subsequent call to ldap_result, can be
used to obtain the result of the add. In case of error, ldap_add will return -1. This
sets the session error parameters in the LDAP structure appropriately, use
ldap_get_errno to obtain it.

See “ldap_error” on page 653 for more details.

The ldap_add_ext and ldap_add_ext_s APIs both support LDAP V3 server


controls and client controls.

644 Client Access Express Programming


ldap_bind
Purpose: LDAP routines for binding and unbinding.

Syntax:
#include <ldap.h>

int ldap_sasl_bind(
LDAP *ld,
char *dn,
char *mechanism,
struct berval *cred,
LDAPControl **servctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_sasl_bind_s(
LDAP *ld,
char *dn,
char *mechanism,
struct berval *cred,
LDAPControl **servctrls,
LDAPControl **clientctrls,
struct berval **servercredp)

int ldap_simple_bind(
LDAP *ld,
char *dn,
char *passwd)

int ldap_simple_bind_s(
LDAP *ld,
char *dn,
char *passwd)

int ldap_unbind(
LDAP *ld)

int ldap_unbind_s(
LDAP *ld)

void ldap_set_rebind_proc(
LDAP *ld;
LDAPRebindProc rebindproc)

int ldap_bind(
LDAP *ld,
char *dn,
char *cred,
int method)

int ldap_bind_s(
LDAP *ld,
char *dn,
char *cred,
int method)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn Specifies the Distinguish Name of an entry to bind as.

Chapter 3. Express C/C++ APIs 645


cred
Specifies the credentials with which to authenticate. The possibility exists to
pass arbitrary credentials by using this parameter. In most cases, this is the
user’s password. When using a SASL bind, the format and content of the
credentials depends on the setting of the mechanism parameter.
mechanism
Although a variety of mechanisms has been IANA registered, the only
mechanism supported by the library at this time is the
LDAP_MECHANISM_EXTERNAL mechanism. The string ″EXTERNAL″
represents this mechanism.

The LDAP_MECHANISM_EXTERNAL mechanism indicates to the server that


information external to SASL should be used to determine whether the client is
authorized to authenticate. For this implementation, the system that provides
the external information is SSL. For the client to request that the server use the
strongly authenticated identity from the client’s X.509 certificate, the complete
following steps.
v Supply a null dn.
v Supply a null credential with mechanism that is set to
LDAP_MECHANISM_EXTERNAL.
This was the certificate that is used to authenticate the client to the server
during the SSL handshake. The server can then use the strongly authenticated
identity to access the directory.
method
Selects which authentication method to use. Specify LDAP_AUTH_SIMPLE
for simple authentication. Simple authentication is the only supported method.
Note that use of the ldap_bind and ldap_bind_s APIs is deprecated. See
“Obsolete Client Access APIs” on page 13 for more information.
passwd
Specifies the password that is used in association with DN of the entry in
which to bind.
serverctrls
Specifies a list of LDAP server controls. See “LDAP controls” on page 638 for
more information about server controls.
clientctrls
Specifies a list of LDAP client controls. See “LDAP controls” on page 638 for
more information about client controls.
rebindproc
This parameter specifies the entry-point of a routine that is called to obtain
bind credentials. Use these credentials when contacting a new server during a
LDAP referral.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.
servercredp
Set this result parameter to the credentials that are returned by the server. If no
credentials return, set the parameter to NULL.

Return Codes: Asynchronous routines will return -1 in case of errors. To obtain


the LDAP error, use the ldap_get_errno API.

646 Client Access Express Programming


Usage: These routines provide various interfaces to the LDAP bind operation.
After using ldap_init, ldap_ssl_init, or ldap_open to create an LDAP handle, the
possibility exists to perform a bind before attempting other operations over the
connection. Both synchronous and asynchronous versions of each variant of the
bind call are provided.

When communicating with an LDAP server that supports the LDAP V3 protocol, a
bind is optional. The LDAP V3 server interprets the absence of a bind as a request
for unauthenticated access. A bind is required by LDAP servers that support only
the LDAP V2 protocol.

The ldap_simple_bind and ldap_simple_bind_s APIs provide simple


authentication, using a user ID (or dn) and a password that is passed in clear-text
to the LDAP API.

The ldap_bind and ldap_bind_s provide general authentication routines, where in


principle an authentication method can be chosen. In this toolkit, set method to
LDAP_AUTH_SIMPLE. Since use of these two APIs is deprecated, use
ldap_simple_bind and ldap_simple_bind_s instead.

Use the ldap_sasl_bind and ldap_sasl_bind_s APIs to do general and extensible


authentication over LDAP through the use of the Simple Authentication Security
Layer.

All bind routines take ld as their first parameter, as returned from ldap_init,
ldap_ssl_init, or ldap_open.

SIMPLE AUTHENTICATION

The simplest form of the bind call is ldap_simple_bind_s. It takes the DN to bind
as, as well as the user’s password (supplied in passwd). It returns an LDAP error
indication (see “ldap_error” on page 653). The ldap_simple_bind call is
asynchronous, taking the same parameters but only initiating the bind operation
and returning the message ID of the request it sent. A subsequent call to
ldap_result obtains the result of the operation.

GENERAL AUTHENTICATION

The ldap_bind and ldap_bind_s routines are deprecated.

Use them when the authentication method to use needs to become selected at
runtime. They both take an extra method parameter that selects which
authentication method to use. Set method to LDAP_AUTH_SIMPLE when using
this toolkit to select simple authentication. ldap_bind and ldap_simple_bind
return the message ID of the initiated request. ldap_bind_s and
ldap_simple_bind_s return an LDAP error indication, or LDAP_SUCCESS on
successful completion.

SASL AUTHENTICATION

The primary reason for using the SASL bind facility is to use the client
authentication mechanism that is provided by SSL to strongly authenticate the
directory server. Do this by using the client’s X.509 certificate. For example, the
client application can use the following logic:
v ldap_ssl_client_init (initialize the SSL library).

Chapter 3. Express C/C++ APIs 647


v ldap_ssl_init (host, port, name), where name refers to a public/private key pair
in the client’s key database file.
v ldap_sasl_bind_s(ld, dn=null, mechanism=LDAP_MECHANISM_EXTERNAL,
cred=null, and so forth).

A server that supports this mechanism (such as V4R4 or later AS/400 Directory
Server) can then access the directory by using the strongly authenticated client
identity (as extracted from the client’s X.509 certificate).

By setting mechanism to a NULL pointer, the SASL bind request will be


interpreted as a request for simple authentication (the equivalent of using
ldap_simple_bind or ldap_simple_bind_s).

UNBINDING

The ldap_unbind call is used to unbind from the directory, end the current
association, and free the resources contained in the ld structure. Once called, any
open connection to the LDAP server closes, and the ld structure is not valid. The
ldap_unbind_s and ldap_unbind; are both synchronous. Use either.

RE-BINDING WHILE FOLLOWING REFERRALS

The ldap_set_rebind_proc call is used to set the entry-point of a routine that will
be called to obtain bind credentials. These credentials are for use when contacting
a new server during the following of an LDAP referral. Note that this function is
only available when LDAP_OPT_REFERRALS is set (this is the default). Never
calling ldap_set_rebind_proc, or calling it with a NULL rebindproc parameter,
generates an unauthenticated simple LDAP bind when chasing referrals.

rebindproc should be a function that is declared like this:


int rebindproc( LDAP *ld, char **whop, char **credp,

int *methodp, int freeit );

The LDAP library first will call the rebindproc to obtain the referral bind
credentials, and the freeit parameter will be zero. Set the whop, credp, and methodp
parameters as appropriate. If the rebindproc returns LDAP_SUCCESS, referral
processing continues. The rebindproc is called a second time with freeit non-zero.
This will give your application a chance to free any memory that was allocated in
the previous call.

If the first call to the rebindproc returns anything but LDAP_SUCCESS, then
referral processing stops. Additionally, that error code returns for the original
LDAP operation.

648 Client Access Express Programming


ldap_compare
Purpose: Perform an LDAP compare operation.

Syntax:
#include <ldap.h>

int ldap_compare(
LDAP *ld,
char *dn,
char *attr,
char *value)

int ldap_compare_s(
LDAP *ld,
char *dn,
char *attr,
char *value)

int ldap_compare_ext(
LDAP *ld,
char *dn,
char *attr,
struct berval *bvalue,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_compare_ext_s(
LDAP *ld,
char *dn,
char *attr,
struct berval *bvalue,
LDAPControl **serverctrls,
LDAPControl **clientctrls)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn Specifies the DN of an entry on which to perform the compare.
attr
Specifies the attribute type to use in the comparison.
bvalue
Specifies the attribute value to compare against the value in the entry. Use this
parameter in the ldap_compare_ext and ldap_compare_ext_s routines. They
serve as a pointer to a struct berval, making it possible to compare binary
values. See “ldap_get_values” on page 663 for more information.
value
Specifies the string attribute value to compare against the value in the entry.
Use this parameter in the ldap_compare and ldap_compare_s routines, because
they are suitable only for string attributes.Use ldap_compare_ext or
ldap_compare_ext_s if you need to compare binary values.
serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.

Chapter 3. Express C/C++ APIs 649


clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: ldap_compare_s returns an LDAP error code which can be


interpreted by calling one of ldap_perror and friends. ldap_compare returns -1 if
initiating the request fails. It returns the non-negative message ID of the request if
the request is successful.

Usage: The various LDAP compare routines are used to perform LDAP compare
operations. They take the following parameters:
v dn (the DN of the entry on which to perform the compare).
v attr (the attribute type to compare to those that are found in the entry).
v value (the value to compare to those that are found in the entry).

The ldap_compare_ext API initiates an asynchronous compare operation and


returns the constant LDAP_SUCCESS if the request was successfully sent, or
another LDAP error code if not. If successful, ldap_compare_ext places the
message ID of the request in *msgidp. A subsequent call to ldap_result can be used
to obtain the result of the operation. Once the operation has completed,
ldap_result returns a result that contains the status of the operation in the form of
an error code. The error code indicates if the operation completed successfully
(LDAP_COMPARE_TRUE) or unsuccessfully (LDAP_COMPARE_FALSE).

Similarly, the ldap_compare API initiates an asynchronous compare operation and


returns the message ID of the operation initiated. A subsequent call to ldap_result,
can be used to obtain the result of the compare. In case of error, ldap_compare will
return -1. This sets the session error parameters in the LDAP structure
appropriately. Obtain this by using ldap_get_errno.

See “ldap_error” on page 653 for more details.

The synchronous ldap_compare_s and ldap_compare_ext_s APIs are used to


perform LDAP compare operations. They return an LDAP error code, which will
be LDAP_COMPARE_TRUE if the entry contains the attribute value, and
LDAP_COMPARE_FALSE if it does not. Otherwise, another error code is returned.

The ldap_compare_ext and ldap_compare_ext_s APIs both support LDAP V3


server controls and client controls.

650 Client Access Express Programming


ldap_delete
Purpose: Perform an LDAP operation to delete a leaf entry.

Syntax:
#include <ldap.h>

int ldap_delete_s(
LDAP *ld,
char *dn

int ldap_delete(
LDAP *ld,
char *dn)

int ldap_delete_ext_s(
LDAP *ld,
char *dn,
LDAPMod *attrs,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_delete_ext(
LDAP *ld,
char *dn,
LDAPMod *attrs,
LDAPControl **serverctrls,
LDAPControl **clientctrls)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn This parameter specifies the DN of the entry to delete.
serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.
clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: ldap_delete_s returns an LDAP error code that can be interpreted
by calling one of the ldap_error routines. ldap_delete returns -1 if initiating the
request fails. It returns the non-negative message ID of the request if successful.

Usage: Note that the entry to delete must be a leaf entry (that is, it must have no
children). LDAP does not support the deletion of entire subtrees in a single
operation.

The ldap_delete_ext API initiates an asynchronous delete operation and returns


the constant LDAP_SUCCESS if the request was successfully sent, or another
LDAP error code if not. If successful, ldap_delete_ext places the message ID of the
request in *msgidp. A subsequent call to ldap_result can be used to obtain the
result of the operation. Once the operation has completed, ldap_result returns a

Chapter 3. Express C/C++ APIs 651


result that contains the status of the operation (in the form of an error code). The
error code indicates if the operation completed successfully. The ldap_parse_result
API is used to check the error code in the result.

Similarly, the ldap_delete API initiates an asynchronous delete operation and


returns the message ID of the operation initiated. A subsequent call to ldap_result,
can be used to obtain the result of the delete. In case of error, ldap_delete will
return -1. This sets the session error parameters in the LDAP structure
appropriately. Use ldap_get_errno to obtain this.

See “ldap_error” on page 653 for more details.

The synchronous ldap_delete_s and ldap_delete_ext_s APIs perform LDAP delete


operations. Both return the result of the operation, either the constant
LDAP_SUCCESS if the operation was successful, or another LDAP error code if it
was not successful.

The ldap_delete_ext and ldap_delete_ext_s APIs both support LDAP V3 server


controls and client controls.

652 Client Access Express Programming


ldap_error
Purpose: LDAP protocol error handling routines.

Syntax:
#include <ldap.h>

int ldap_get_errno(
LDAP *ld)

void ldap_perror(
LDAP *ld,
char *s)

int ldap_result2error(
LDAP *ld,
LDAPMessage *res,
int freeit)

char *ldap_err2string(
int error)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
s Specifies the message prefix, which is added to the beginning of the string
form of the error code that is held stored under the LDAP structure. The string
form of the error is the same string that would be returned by a call to
ldap_err2string.
res
Specifies the result, as produced by ldap_result or ldap_search_s, to be
converted to the error code with which it is associated.
freeit
Specifies whether the result, res, becomes freed as a result of calling
ldap_result2error. If non-zero, the result res will be feed by the call. If zero, res
will not be freed by the call.

Return Codes: The possible values for an LDAP error code are:
#define LDAP_SUCCESS 0x00
#define LDAP_OPERATIONS_ERROR 0x01
#define LDAP_PROTOCOL_ERROR 0x02
#define LDAP_TIMELIMIT_EXCEEDED 0x03
#define LDAP_SIZELIMIT_EXCEEDED 0x04
#define LDAP_COMPARE_FALSE 0x05
#define LDAP_COMPARE_TRUE 0x06
#define LDAP_STRONG_AUTH_NOT_SUPPORTED 0x07
#define LDAP_STRONG_AUTH_REQUIRED 0x08
#define LDAP_PARTIAL_RESULTS 0x09

#define LDAP_REFERRAL 0X0a


#define LDAP_ADMIN_LIMIT_EXCEEDED 0X0b
#define LDAP_UNAVAILABLE_CRITICAL_EXTENSION 0X0c

#define LDAP_NO_SUCH_ATTRIBUTE 0x10


#define LDAP_UNDEFINED_TYPE 0x11
#define LDAP_INAPPROPRIATE_MATCHING 0x12
#define LDAP_CONSTRAINT_VIOLATION 0x13
#define LDAP_TYPE_OR_VALUE_EXISTS 0x14
#define LDAP_INVALID_SYNTAX 0x15

Chapter 3. Express C/C++ APIs 653


#define LDAP_NO_SUCH_OBJECT 0x20
#define LDAP_ALIAS_PROBLEM 0x21
#define LDAP_INVALID_DN_SYNTAX 0x22
#define LDAP_IS_LEAF 0x23
#define LDAP_ALIAS_DEREF_PROBLEM 0x24

#define LDAP_INAPPROPRIATE_AUTH 0x30


#define LDAP_INVALID_CREDENTIALS 0x31
#define LDAP_INSUFFICIENT_ACCESS 0x32
#define LDAP_BUSY 0x33
#define LDAP_UNAVAILABLE 0x34
#define LDAP_UNWILLING_TO_PERFORM 0x35
#define LDAP_LOOP_DETECT 0x36

#define LDAP_NAMING_VIOLATION 0x40


#define LDAP_OBJECT_CLASS_VIOLATION 0x41
#define LDAP_NOT_ALLOWED_ON_NONLEAF 0x42
#define LDAP_NOT_ALLOWED_ON_RDN 0x43
#define LDAP_ALREADY_EXISTS 0x44
#define LDAP_NO_OBJECT_CLASS_MODS 0x45
#define LDAP_RESULTS_TOO_LARGE 0x46

#define LDAP_AFFECTS_MULTIPLE_DSAS 0X47

#define LDAP_OTHER 0x50


#define LDAP_SERVER_DOWN 0x51
#define LDAP_LOCAL_ERROR 0x52
#define LDAP_ENCODING_ERROR 0x53
#define LDAP_DECODING_ERROR 0x54
#define LDAP_TIMEOUT 0x55
#define LDAP_AUTH_UNKNOWN 0x56
#define LDAP_FILTER_ERROR 0x57
#define LDAP_USER_CANCELLED 0x58
#define LDAP_PARAM_ERROR 0x59
#define LDAP_NO_MEMORY 0x5a

#define LDAP_URL_ERR_NOTLDAP 0x60


#define LDAP_URL_ERR_NODN 0x61
#define LDAP_URL_ERR_BADSCOPE 0x62
#define LDAP_URL_ERR_MEM 0x63

#define LDAP_SSL_ALREADY_INITIALIZED 0x70


#define LDAP_SSL_INITIALIZE_FAILED 0x71
#define LDAP_SSL_INITIALIZE_NOT_CALLED 0x72
#define LDAP_SSL_PARAM_ERROR 0x73
#define LDAP_SSL_HANDSHAKE_FAILED 0x74

Usage: These routines provide interpretation of the various error codes that are
returned by the LDAP protocol and LDAP library routines.

The ldap_get_errno API obtains information about the most recent error that
occurred for an LDAP operation. Call this function for any LDAP API that does
not return an error.

The ldap_result2error routine takes res, a result as produced by ldap_result or


ldap_search_s, and returns the corresponding error code. See below for possible
error codes. A non-zero freeit parameter indicates that the res parameter frees by a
call to ldap_msgfree after extracting the error code. The ld_errno field in ld is set
and returned.

The returned value can be passed to ldap_err2string, which returns a pointer to a


character string that is a textual description of the LDAP error code. The character
string should not be freed when use of the string is complete.

654 Client Access Express Programming


The ldap_perror routine can be called to print an indication of the error on
standard error.

Chapter 3. Express C/C++ APIs 655


ldap_first_attribute
Purpose: Step through LDAP entry attributes.

Syntax:
#include <ldap.h>

int ldap_count_attributes(
LDAP *ld,
LDAPMessage *entry)

char *ldap_first_attribute(
LDAP *ld,
LDAPMessage *entry,
BerElement **berptr)

char *ldap_next_attribute(
LDAP *ld,
LDAPMessage *entry,
BerElement *berptr)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
entry
The attribute information as returned by ldap_first_entry or ldap_next_entry.
berptr
This is an output parameter that is returned from ldap_first_attribute, which
returns a pointer to a BerElement that is allocated to keep track of current
position. It is an input parameter and an output parameter for subsequent calls
to ldap_next_attribute. This is where it specifies a pointer to a BerElement that
was allocated by the previous call to ldap_first_attribute or
ldap_next_attribute. The BerElement structure is opaque to the application.

Return Codes: If the ldap_first_attribute call results in an error, NULL is


returned, the error code is set, and the memory to which berptr points
automatically is freed and set to NULL.

If the ldap_next_attribute call results in an error, NULL is returned, the error code
is set, and the memory to which berptr points also must be freed by calling
ldap_ber_free.

The ldap_get_errno API can be used to obtain the error code.

Usage: The ldap_count_attributes routine returns a count of the number of


attributes in an LDAP entry. If a null entry is returned from ldap_first_entry or
ldap_next_entry, and is passed as input to ldap_count_attributes, a -1 is returned.

The ldap_first_attribute and ldap_next_attribute routines are used to step through


the attributes in an LDAP entry.

ldap_first_attribute takes an entry as returned by ldap_first_entry or


ldap_next_entry and returns a pointer to a buffer containing the first attribute type
in the entry.

The pointer returned by ldap_first_attribute in berptr should be passed to


subsequent calls to ldap_next_attribute, and is used to step through the entry’s

656 Client Access Express Programming


attributes. When there are no attributes left to be retrieved, ldap_next_attribute
returns NULL, sets the error code to LDAP_SUCCESS, and releases the memory
allocated for the BerElement buffer. If an error occurs, NULL is returned and an
error code is set.

Therefore, when NULL is returned, the ldap_get_errno API should be used to


determine whether an error has occurred.

If the caller fails to call ldap_next_attribute a sufficient number of times to exhaust


the list of attributes, the caller is responsible for freeing the BerElement to which
berptr points, when it no longer is needed, by calling ldap_ber_free.

The attribute names that are returned by ldap_first_attribute are suitable for
inclusion in a call to ldap_get_values.

ldap_next_attribute returns a string that contains the name of the next type in the
entry. Free this string by using ldap_memfree when its use completes.

The attribute names that are returned by ldap_next_attribute are suitable for
inclusion in a call to ldap_get_values to retrieve the attribute’s values.

Note: The ldap_first_attribute and ldap_next_attribute routines allocate memory


(by using malloc) that caller may need to free by using ldap_memfree.

Chapter 3. Express C/C++ APIs 657


ldap_first_entry/reference
Purpose: LDAP result entry and continuation reference parsing and counting
routines.

Note: APIs with the ″_np″ suffix are preliminary implementations, and are not
documented in the Internet Draft, C LDAP Application Program Interface.

Syntax:
#include <ldap.h>

LDAPMessage *ldap_first_entry(
LDAP *ld,
LDAPMessage *result)

LDAPMessage *ldap_next_entry(
LDAP *ld,
LDAPMessage *entry)

int ldap_count_entries(
LDAP *ld,
LDAPMessage *result)

int ldap_get_entry_controls_np(
LDAP *ld,
LDAPMessage *entry
LDAPControl ***serverctrlsp)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
entry
Specifies a pointer to an entry that is returned on a previous call to
ldap_first_entry, ldap_next_entry, ldap_first_reference, or
ldap_next_reference.
result
Specifies the result that is returned by a call to ldap_result or one of the
synchronous search routines (ldap_search_s, ldap_search_st, or
ldap_search_ext_s).
serverctrlsp
Specifies a pointer to a result parameter that is filled in with an allocated array
of controls copied out of the LDAPMessage message. Free the control array by
calling ldap_controls_free.

Return Codes: If an error occurs in ldap_first_entry or ldap_next_entry, NULL is


returned, and the ldap_get_errno API can be used to obtain the error code.

If an error occurs in ldap_count_entries, -1 is returned, and ldap_get_errno can be


used to obtain the error code. See “ldap_error” on page 653 for a description of
possible error codes.

ldap_get_entry_controls_np and ldap_parse_reference_np return an LDAP error


code directly (LDAP_SUCCESS if the call was successful; otherwise, an LDAP
error).

658 Client Access Express Programming


Usage: These routines parse results that are received from ldap_result or the
synchronous LDAP search operation routines ldap_search_s, ldap_search_st, and
ldap_search_ext_s.

PROCESSING ENTRIES

The ldap_first_entry and ldap_next_entry APIs are used to step through and
retrieve the list of entries from a search result chain. When an LDAP operation
completes and the result is obtained as described, a list of LDAPMessage
structures is returned. This is referred to as the search result chain. A pointer to
the first of these structures is returned by ldap_result and ldap_search_s.

The ldap_first_entry routine is used to retrieve the first entry in a chain of search
results. It takes the result as returned by a API call, (from those that are listed
below), and returns a pointer to the first entry in the result.
v ldap_result.
v ldap_search_s.
v ldap_search_st.
v ldap_search_ext_s.

This pointer should be supplied on a subsequent call to ldap_next_entry to get the


next entry. The result of which should be supplied to the next call to
ldap_next_entry, and so forth. ldap_next_entry will return NULL when there are
no more entries. The entries that are returned from these calls are used in calls to
the routines that are described in ldap_get_dn, ldap_first_attribute,
ldap_get_values, and so forth.

COUNTING ENTRIES

The ldap_count_entries API returns the number of entries that are contained in a
chain of entries. It also counts the number of entries that remain in a chain. This is
true provided the API was called with a message, entry, or continuation reference
returned by ldap_first_message, ldap_next_message, ldap_first_entry,
ldap_next_entry, ldap_first_reference, or ldap_next_reference, respectively.

Chapter 3. Express C/C++ APIs 659


ldap_first_reference
Purpose: LDAP continuation reference parsing and counting routines.

Note: APIs with the ″_np″ suffix are preliminary implementations, and are not
documented in the Internet Draft, C LDAP Application Program Interface.

Syntax:
#include <ldap.h>

LDAPMessage *ldap_first_reference(
LDAP *ld,
LDAPMessage *result)

LDAPMessage *ldap_next_reference(
LDAP *ld,
LDAPMessage *entry)

int ldap_count_references(
LDAP *ld,
LDAPMessage *result)

int ldap_parse_reference_np(
LDAP *ld,
LDAPMessage *ref
char ***referralsp,
LDAPControl ***serverctrlsp,
int freeit )

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
entry
Specifies a pointer to an entry that are returned on a previous call to
ldap_first_entry, ldap_next_entry, ldap_first_reference, or
ldap_next_reference.
result
Specifies the result that is returned by a call to ldap_result or one of the
synchronous search routines (ldap_search_s, ldap_search_st, or
ldap_search_ext_s).
referralsp
Specifies a pointer to a result parameter that is filled in with the contents of
the referrals field from the LDAPMessage message, indicating zero or more
alternate LDAP servers where the request should be retried. The referrals array
should be freed by calling ldap_value_free. NULL may be supplied for this
parameter to ignore the referrals field.
serverctrlsp
Specifies a pointer to a reslt parameter that is filled in with an allocated array
of controls copied out of the LDAPMessage message. The control array should
be freed by calling ldap_controls_freed.
freeit
Specifies a boolean value that determines if the LDAP result chain (as specified
by ref) is to be freed. Any non-zero value will result in the LDAP result chain
being freed after the requested information is extracted. Alternatively, the
ldap_msgfree API can be used to free the LDAP result chain at a later time.

660 Client Access Express Programming


Return Codes: If an error occurs in ldap_first_reference or ldap_next_reference
NULL is returned, and the ldap_get_errno API can be used to obtain the error
code.

If an error occurs in ldap_count_references, -1 is returned, and ldap_get_errno can


be used to obtain the error code. See “ldap_error” on page 653 for a description of
possible error codes.

Usage: These routines parse results that are received from ldap_result or the
synchronous LDAP search operation routines ldap_search_s, ldap_search_st, and
ldap_search_ext_s.

PROCESSING CONTINUATION REFERENCES

The ldap_first_reference and ldap_next_reference APIs step through and retrieve


the list of continuation references from a search result chain. They will return
NULL when no more continuation references exist in the result set.

The ldap_first_reference routine is used to retrieve the first continuation reference


in a chain of search results. It takes the result as returned by an API call, (from
those are listed below), and returns a pointer to the first continuation reference in
the result.
v ldap_result.
v ldap_search_s.
v ldap_search_st.
v ldap_search_ext_s.

This pointer should be supplied on a subsequent call to ldap_next_reference to get


the next continuation reference.

The ldap_parse_reference_np routine is used to retrieve the list of alternate servers


returned in an individual continuation reference in a chain of search results. This
routine also is used to obtain an array of server controls returned in the
continuation reference.

COUNTING REFERENCES

Use the ldap_count_references API to count the number of continuation references


returned. Additionally, use it to count the number of continuation references that
remain in a chain.

Chapter 3. Express C/C++ APIs 661


ldap_get_dn
Purpose: LDAP DN handling routines.

Syntax:
#include <ldap.h>

char *ldap_get_dn(
LDAP *ld,
LDAPMessage *entry)

char **ldap_explode_dn(
char *dn,
int notypes)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn Specifies the DN to be exploded (as returned fromldap_get_dn).
entry
The entry whose dn is retrieved, as returned by ldap_first_entry or
ldap_next_entry.
notypes
Specifies if type information is to return with each RDN. Any returned
non-zero information strips the type information. Any returned zero
information keeps the type information. For example, notypes=1 results in
″cn=Fido″ that returns as ″Fido″.

Return Codes: Null returns if an error occurs in ldap_get_dn or


ldap_explode_dn. Use the ldap_get_errno API to obtain the error code. See
“ldap_error” on page 653 for a description of possible error codes.

Usage: The ldap_get_dn routine takes an entry as returned by ldap_first_entry or


ldap_next_entry and returns a copy of the entry’s DN. Space for the DN will have
been allocated by the LDAP API, and should be freed by the caller by a call to
ldap_memfree.

The ldap_explode_dn routine takes a DN as returned by ldap_get_dn and breaks


it up into its component parts. Each part is known as a Relative Distinguished
Name, or RDN. ldap_explode_dn returns a NULL-terminated array, each
component of which contains an RDN from the DN. Use the notypes parameter to
request that only the RDN values return, not their types. For example, the DN
″cn=Bob,c=US″ would return as either ″cn=Bob″, ″c=US″,NULL, or ″Bob″,″US″,
NULL, depending on whether notypes was 0 or 1, respectively. Free the result by
calling ldap_value_free.

Note: These routines malloc memory that the caller must free.

662 Client Access Express Programming


ldap_get_values
Purpose: LDAP attribute value handling routines.

Syntax:
#include <ldap.h>

typedef struct berval {


unsigned long bv_len;
char *bv_val;
};

char **ldap_get_values(
LDAP *ld,
LDAPMessage *entry,
char *attr)

struct berval **ldap_get_values_len(


LDAP *ld,
LDAPMessage *entry,
char *attr)

int ldap_count_values(
char **vals)

int ldap_count_values_len(
struct berval **bvals)

void ldap_value_free(
char **vals)

void ldap_value_free_len(
struct berval **bvals)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
attr
Specifies the attribute whose values are desired.
entry
Specifies an LDAP entry as returned by ldap_first_entry or ldap_next_entry.
vals
Specifies a pointer to a NULL-terminated array of attribute values, as returned
by ldap_get_values.
bvals
Specifies a pointer to a NULL-terminated array of pointers to berval structures,
as returned by ldap_get_values_len.

Return Codes: If an error occurs in ldap_get_values or ldap_get_values_len,


NULL is returned and the ldap_get_errno API can be used to obtain the error
code. See “ldap_error” on page 653 for a description of possible error codes.

Usage: Use these routines to retrieve and manipulate attribute values from an
LDAP entry as returned by ldap_first_entry or ldap_next_entry. The
ldap_get_values API takes the entry and the attribute attr whose values are desired
and returns a NULL-terminated array of pointers to NULL-terminated character

Chapter 3. Express C/C++ APIs 663


strings that represent the attribute’s values. attr may be an attribute type as
returned from ldap_first_attribute or ldap_next_attribute, or simply give the
attribute type if known.

Call ldap_count_values to count the number of values in the array. Call


ldap_value_free to free the array of returned values.

If the attribute values are binary in nature, and therefore not suitable to be
returned as an array of char *s, use the ldap_get_values_len routine instead. It
takes the same parameters as ldap_get_values, but returns a NULL-terminated
array of pointers to berval structures. These structures each contain the length of
and a pointer to a value.

Call ldap_count_values_len to count the number of values in the array. Call


ldap_value_free_len to free the array of returned values.

664 Client Access Express Programming


ldap_init
Purpose: To initialize the LDAP library, open a connection to an LDAP server, and
set or get options for an LDAP connection.

Syntax:
#include <ldap.h>

LDAP *ldap_init(
char *host,
int port)

LDAP *ldap_open(
char *host,
int port)

int ldap_set_option(
LDAP *ld,
int optionToSet,
void *optionValue)

int ldap_get_option(
LDAP *ld,
int optionToGet,
void *optionValue)

int ldap_version(
LDAPVersion *version)

Parameters:
host
Specifies the name of the host on which the LDAP server is running. The host
parameter may contain a blank-separated list of possible connection hosts.
Additionally, each host may optionally be of the form host:port. If present, the
:port overrides the port parameter to supplied on ldap_init, ldap_ssl_init, or
ldap_open. If the host parameter is null, the LDAP server is assumed to be
running on the local host.
port
Specifies the port number to which to connect. Specify LDAP_PORT if you
desire the default IANA-assigned port of 389. To use the default SSL port 636
for SSL connections, use LDAPS_PORT.
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
optionToSet
Identifies the option value that is to be set on the ldap_set_option call. See
USAGE below for the list of supported options.
optionToGet
Identifies the option value that is to be queried on the ldap_get_option call.
See USAGE below for the list of supported options.
optionValue
This parameter specifies one of the following addresses.
v The address of the value to set by using ldap_set_option.
v The address of the storage in which to return the queried value by
ldap_get_option.

Chapter 3. Express C/C++ APIs 665


version
Specifies the address of an LDAPVersion structure that contains the following
returned values:
sdk_version
Toolkit version, multiplied by 100
protocol_version
Highest LDAP protocol supported, multiplied by 100
SSL_version
SSL version supported, multiplied by 100
security_level
Level of encryption supported, in bits. Set to
LDAP_SECURITY_NONE if SSL not enabled.
ssl_max_cipher
A string containing the default ordered set of ciphers supported by this
installation. See ldap_set_option below for more information about
changing the set of ciphers that are used to negotiate the secure
connection with the server.
sdk_vendor
A pointer to a static string that identifies the supplier of the LDAP
library. This string should not be freed by the application.
sdk_build_level
A pointer to a static string that identifies the build level, including the
date when the library was built. This string should not be freed by the
application.

Return Codes: If an error occurs, a non-zero return code returns from


ldap_set_option and ldap_get_option.

Usage: ldap_init initializes a session with an LDAP server. The server is not
actually contacted until an operation is performed that requires it. This allows the
setting of various options that are after initialization, but before actually contacting
the host. It allocates an LDAP structure, which is used to identify the connection
and maintain per-connection information.

Although deprecated, IBM still supports the use of ldap_open. The ldap_open API
allocates an LDAP structure and opens a connection to the LDAP server. IBM
recommends using ldap_init instead of ldap_open.

The ldap_init and ldap_open APIs return a pointer to an LDAP structure, which
should be passed to subsequent calls to ldap_set_option, ldap_simple_bind,
ldap_search, and so forth.

IBM does not recommend direct manipulation of the LDAP structure.

Note: You should not make any assumptions about the order or location of
elements in the opaque LDAP structure.

The ldap_version API returns the toolkit version (multiplied by 100). It also sets
information in the LDAPVersion structure.

SETTING AND GETTING SESSION SETTINGS

666 Client Access Express Programming


The ldap_set_option API is provided to set options for the specified LDAP
connection. The ldap_get_option API is provided to query settings associated with
the specified LDAP connection.

Set or get the following session settings by using the ldap_set_option and
ldap_get_option API:
LDAP_OPT_SIZELIMIT
Get or Set maximum number of entries that return on a search operation
LDAP_OPT_TIMELIMIT
Get or Set maximum number of seconds to wait for search results
LDAP_OPT_REFHOPLIMIT
Get or Set maximum number of referrals in a sequence that the client can
follow
LDAP_OPT_DEREF
Get or Set rules for following aliases at the server
LDAP_OPT_REFERRALS
Get or Set whether the client should follow referrals
LDAP_OPT_DEBUG
Get or Set debug options
LDAP_OPT_SSL_CIPHER
Get or Set SSL ciphers to use
LDAP_OPT_SSL_TIMEOUT
Get or Set SSL timeout for refreshing session keys
LDAP_OPT_REBIND_FN
Get or Set address of application’s setrebindproc procedure
LDAP_OPT_PROTOCOL_VERSION
Get or Set LDAP protocol version to use (V2 or V3)
LDAP_OPT_SERVER_CONTROLS
Get or Set default server controls
LDAP_OPT_CLIENT_CONTROLS
Get or Set default client library controls
LDAP_OPT_HOST_NAME
Get current host name (cannot be set)
LDAP_OPT_ERROR_NUMBER
Get error number (cannot be set)
LDAP_OPT_ERROR_STRING
Get error string (cannot be set)

See for important information if any of the following listed conditions exist on
your system.
v Your LDAP application is based on the LDAP V2 APIs (that is, you are using
ldap_open).
v Your application uses ldap_init and ldap_set_option to transition from LDAP
V3 to LDAP V2.

The following sections provide additional details.

LDAP_OPT_SIZELIMIT

Chapter 3. Express C/C++ APIs 667


This parameter specifies the maximum number of entries that return on a search
operation. This is bounded by the maximum number of entries that the server is
configured to return. The default sizelimit is unlimited, and is specified with a
value of zero, which thereby defers to the sizelimit setting of the LDAP server.
Examples:

sizevalue=50;
ldap_set_option( ld, LDAP_OPT_SIZELIMIT, &sizevalue);
ldap_get_option( ld, LDAP_OPT_SIZELIMIT, &sizevalue );

LDAP_OPT_TIMELIMIT

This API specifies the number of seconds to wait for search results.

Note: The actual time limit for operations also is bounded by the maximum time
that the server is configured to allow. The actual time limit is the lesser of
the value specified with this option and the value configured in the LDAP
server. The default is unlimited (specified with a value of zero).
Examples:

timevalue=50;
ldap_set_option( ld, LDAP_OPT_TIMELIMIT, &timevalue);
ldap_get_option( ld, LDAP_OPT_TIMELIMIT, &timevalue );

LDAP_OPT_REFHOPLIMIT

This option specifies the maximum number of hops that the client library will take
when chasing referrals. The default is 5.
Examples:

hoplimit=7;
ldap_set_option( ld, LDAP_OPT_REFHOPLIMIT, &hoplimit);
ldap_get_option( ld, LDAP_OPT_REFHOPLIMIT, &hoplimit);

LDAP_OPT_DEREF

This option specifies alternative rules for following aliases at the server.
Supported values:

LDAP_DEREF_NEVER 0
LDAP_DEREF_SEARCHING 1
LDAP_DEREF_FINDING 2
LDAP_DEREF_ALWAYS 3

Note: The default value is LDAP_DEREF_NEVER


Examples:

int deref = LDAP_DEREF_NEVER;


ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref);
ldap_get_option( ld, LDAP_OPT_DEREF, &value );

LDAP_OPT_REFERRALS

This option specifies whether the LDAP library will automatically follow referrals
that are returned by LDAP servers. Supported values are:

668 Client Access Express Programming


LDAP_OPT_ON
Follow referrals
LDAP_OPT_OFF
Do not follow referrals

By default, the LDAP client will follow referrals.


Examples:

ldap_set_option( ld, LDAP_OPT_REFFERALS, LDAP_OPT_ON);


ldap_get_option( ld, LDAP_OPT_REFFERALS, &value);

LDAP_OPT_DEBUG

Specifies a bit-map that indicates the level of debug trace for the LDAP library.
Supported values:

/* Debug levels */
LDAP_DEBUG_OFF 0x000
LDAP_DEBUG_TRACE 0x001
LDAP_DEBUG_PACKETS 0x002
LDAP_DEBUG_ARGS 0x004
LDAP_DEBUG_CONNS 0x008
LDAP_DEBUG_BER 0x010
LDAP_DEBUG_FILTER 0x020
LDAP_DEBUG_CONFIG 0x040
LDAP_DEBUG_ACL 0x080
LDAP_DEBUG_STATS 0x100
LDAP_DEBUG_STATS2 0x200
LDAP_DEBUG_SHELL 0x400
LDAP_DEBUG_PARSE 0x800
LDAP_DEBUG_ANY 0xffff
Examples:

int value;
int debugvalue= LDAP_DEBUG_TRACE | LDAP_DEBUG_PACKETS;
ldap_set_option( ld, LDAP_OPT_DEBUG, &debugvalue);
ldap_get_option( ld, LDAP_OPT_DEBUG, &value );

LDAP_OPT_SSL_CIPHER

This option specifies a set of one or more ciphers to use when negotiating the
cipher algorithm with the LDAP server. The first cipher in the list that is common
with the list of ciphers that are supported by the server is chosen. For the export
version of the SSL library, the value used is ″0306″. For the domestic version of the
SSL library, the default value is ″05040A090306″. Note that the cipher string that is
supported by the export version of the SSL library is fixed, and cannot be
modified.
Supported ciphers:

LDAP_SSL_RC4_MD5_EX "03"
LDAP_SSL_RC2_MD5_EX "06"
LDAP_SSL_RC4_SHA_US "05" (Non-export only)
LDAP_SSL_RC4_MD5_US "04" (Non-export only)
LDAP_SSL_DES_SHA_US "09" (Non-export only)
LDAP_SSL_3DES_SHA_US "0A" (Non-export only)

Chapter 3. Express C/C++ APIs 669


Examples:

char *cipher = "090A";


ldap_set_option( ld, LDAP_OPT_SSL_CIPHER, &cipher);
ldap_get_option( ld, LDAP_OPT_SSL_CIPHER, &cipher );

LDAP_OPT_SSL_TIMEOUT

This option specifies the SSL inactivity timer in seconds. After the specified
seconds, in which no SSL activity has occurred, the SSL connection refreshes with
new session keys. A smaller value may marginally increase security, but will have
a small impact on performance. The default SSL timeout value is 43200 seconds (12
hours).
Examples:

value = 100;
ldap_set_option( ld, LDAP_OPT_SSL_TIMEOUT, &value );
ldap_get_option( ld, LDAP_OPT_SSL_TIMEOUT, &value)

LDAP_OPT_REBIND_FN

This option specifies the address of a routine that is called by the LDAP library
when the need arises to authenticate a connection with another LDAP server. This
can occur, for example, when the LDAP library is chasing a referral. If a routine is
not defined, referrals always will be chased using the anonymous identity. A
default routine is not defined..
Examples:

extern LDAPRebindProc proc_address;


LDAPrebindProc value;
ldap_set_option( ld, LDAP_OPT_REBIND_FN, &proc_address);
ldap_get_option( ld, LDAP_OPT_REBIND_FN, &value);

LDAP_OPT_PROTOCOL_VERSION

This option specifies the LDAP protocol for the LDAP client library to use when
connecting to an LDAP server. This option also is used to determine which LDAP
protocol to use for the connection. In general, an application that uses ldap_init to
create the LDAP connection is assumed to be using LDAP V3 to communicate with
the LDAP server. An application that uses the deprecated ldap_open API is
assumed to be using LDAP V2 to communicate with the LDAP server. In either
case, use the LDAP_OPT_PROTOCOL_VERSION option with ldap_set_option to
change the default. Reset the LDAP protocol version prior to issuing the bind (or
any operation that causes an implicit bind).
Examples:

version2 = LDAP_VERSION2;
version3 = LDAP_VERSION3;
/* Example for Version 3 application setting version to version 2 */
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version2);
/* Example of Version 2 application setting version to version 3 */
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version3);
ldap_get_option( ld, LDAP_OPT_PROTOCOL_VERSION, &value);

LDAP_OPT_SERVER_CONTROLS

670 Client Access Express Programming


This option specifies a default list of server controls that are sent with each request.
Override the default list by specifying a server control, or list of server controls, on
specific APIs. By default, there are no settings for Server Controls.
Example:

ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, );

LDAP_OPT_CLIENT_CONTROLS

Specifies a default list of client controls to be processed by the client library with
each request. Since client controls are not defined for this version of the library, the
ldap_set_option API can be used to define a set of default, non-critical client
controls. If one ore more client controls in the set is critical, the entire list is
rejected with a return code of LDAP_UNAVAILABLE_CRITICAL_EXTENSION.

LDAP_OPT_HOST_NAME

This is a read-only option that returns a pointer to the hostname for the original
connection (as specified on the ldap_init or ldap_ssl_init).
Example:

char *hostname;
ldap_get_option( ld, LDAP_OPT_HOST_NAME, &hostname);

Use ldap_memfree to free the memory returned by ldap_get_opt.

LDAP_OPT_ERROR_NUMBER

This is a read-only option that returns the error code that is associated with the
most recent LDAP error that occurred for the specified LDAP connection.
Example:

int error;
ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &error);

LDAP_OPT_ERROR_STRING

This is a read-only option that returns the text message that is associated with the
most recent LDAP error that occurred for the specified LDAP connection.
Example:

char *error_string;
ldap_get_option( ld, LDAP_OPT_ERROR_STRING, &error_string);

LDAP_OPT_EXTERROR

This is a read-only option that returns the extended error code. For example, if an
SSL error occurred when attempting to call aldap_search_s API, you can obtain the
actual SSL error by using LDAP_OPT_EXTERROR.
Example:

int error;
ldap_get_option( ld, LDAP_OPT_ERROR_EXTERROR, &error);
Returns errors reported by the SSL library.

LDAP_SET_OPTION Syntax for LDAP V2 Applications

Chapter 3. Express C/C++ APIs 671


To maintain compatibility with older versions of the LDAP client library
(pre-LDAP V3), the ldap_set_option API expects the value of the following option
values to be supplied. This is expected instead of the address of the value, when
the application is running as an LDAP V2 application:
v LDAP_OPT_SIZELIMIT
v LDAP_OPT_TIMELIMIT
v LDAP_OPT_SSL_TIMEOUT
v LDAP_OPT_DEREF
v LDAP_OPT_DEBUG

The value returned by ldap_get_option when


LDAP_OPT_PROTOCOL_VERSION is specified can be used to determine how
parameters should be passed to the ldap_set_option call. The easiest way to work
with this compatibility feature is to guarantee that calls to ldap_set_option are
performed while the LDAP_OPT_PROTOCOL_VERSION is set to the same
value. If this cannot be guaranteed by the application, then follow the format of
the example below when coding the call to ldap_set_option:
int sizeLimit=100

int protocolVersion;

ldap_get_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocolVersion );

if ( protocolVersion == LDAP_VERSION2 ) {
ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *)sizeLimit );
} else { /* the protocol version is LDAP_VERSION3 */
ldap_set_option( ld, LDAP_OPT_SIZELIMIT, $sizeLimit );
}

As a general rule, the LDAP application typically is running as LDAP V2 when it


uses ldap_open to create the LDAP connection. The LDAP application typically is
running LDAP V3 when it sues ldap_init to create the LDAP connection. However,
it was possible with the LDAP V2 API to call ldap_init, so that there may be
instances in which this general rule is not valid. Note that
LDAP_OPT_PROTOCOL_VERSION can be used to toggle the protocol, in which
case the behavior of ldap_set_option changes.

MULTITHREADED APPLICATIONS

The LDAP client libraries generally are thread safe. While a multithreaded
application safely can use the LDAP library on multiple threads within the
application, be aware of the following considerations:
1. Use the LDAP connection (the ld) on the thread that is created. This avoids the
possibility of possible conflicts if multiple threads concurrently are processing
the results of an operation submitted on a different thread.
2. Design an application to submit requests on one or more threads, with the
results returned on different threads. This avoids the possibility of two threads
attempting to process the results associated with a single LDAP connection.
3. The ldap_get_errno API obtains information with respect to the most recent
error that occurred for the specified LDAP connection. It does not return the
most recent LDAP error that occurred on the thread on which it is issued.
4. A key consideration is that only a single thread should be performing
operations on a particular LDAP connection at a particular instance.

672 Client Access Express Programming


ldap_memfree
Purpose: Free storage that is allocated by the LDAP library.

Syntax:
#include <ldap.h>

void ldap_memfree(
char *mem)

void ldap_ber_free(
BerElement *berptr)

void ldap_control_free(
LDAPControl *ctrl)

void ldap_controls_free(
LDAPControl **ctrls)

void ldap_msg_free(
LDAPMessage *msg)

Parameters:
mem
Specifies the address of storage that was allocated by the LDAP library.
berptr
Specifies the address of the BerElement returned from ldap_first_attribute and
ldap_next_attribute.
ctrl
Specifies the address of an LDAPControl structure.
ctrls
Specifies the address of an LDAPControl list, represented as a NULL-stopped
array of pointers to LDAPControl structures.

Return Codes: None.

Usage: ldap_memfree is used to free storage that has been allocated by the LDAP
library (libldap). Use this routine as directed when using ldap_error,
ldap_get_option, and ldap_first_attribute.

For those LDAP APIs that allocate an LDAPControl structure, use the
ldap_control_free API.

For those LDAP APIs that allocate a list of LDAPControl structures, use the
ldap_controls_free API.

The ldap_msgfree routine is used to free the memory allocated for an LDAP
message by ldap_result, ldap_search_s, ldap_search_ext_s, or ldap_search_st. It
takes a pointer to the result to be freed, and returns the type of the message it
freed.

The ldap_ber_free routine is used to free the BerElement pointed to by berptr. The
LDAP library automatically frees the BerElement when ldap_next_attribute returns
NULL. The application is responsible for freeing the BerElement if for any reason it
does not invoke the ldap_next_attribute until it returns NULL.

Chapter 3. Express C/C++ APIs 673


ldap_message
Purpose: Step through the list of messages of a result chain, as returned by
ldap_result.

Syntax:
#include <ldap.h>

LDAPMessage *ldap_first_message(
LDAP *ld,
LDAPMessage *result)

LDAPMessage *ldap_next_message(
LDAP *ld,
LDAPMessage *msg)

int ldap_count_messages(
LDAP *ld,
LDAPMessage *result)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
result
Specifies the result that is returned by a call to ldap_result or one of the
synchronous search routines (ldap_search_s, ldap_search_st, or
ldap_search_ext_s).
msg
Specifies the message that is returned by a previous call to ldap_first_message
or ldap_next_message.

Return Codes: If an error occurs in ldap_first_message or ldap_next_message,


use the ldap_get_errno API to obtain the error code.

If an error occurs in ldap_count_entries or ldap_count_references, -1 is returned,


and ldap_get_errno can be used to obtain the error code. See “ldap_error” on
page 653 for a description of possible error codes.

Usage: Use these routines to step through the list of messages in a result chain, as
returned by ldap_result.

For search operations, the result chain may include:


v Referral messages
v Entry messages
v Result messages

Use the ldap_count_messages API to count the number of messages returned. Use
the ldap_msgtype API to distinguish between the different message types.

Unlike the ldap_first_entry API, ldap_first_message returns any of three types of


messages (referral, entry and result messages). The other routines return the
specific type of message, skipping the others.

674 Client Access Express Programming


The ldap_first_message and ldap_next_message APIs will return NULL when no
more messages exist in the result that is set to return. NULL also returns if an
error occurs while stepping through the entries. When such an error occurs, use
ldap_get_errno to obtain the error code.

ldap_count_messages API returns the number of messages that are contained in a


chain of results. Additionally, it counts the number of messages that remain in a
chain. This is valid, provided the API was called with a message, entry, or
reference returned by ldap_first_message, ldap_next_message, ldap_first_entry,
ldap_next_entry, ldap_first_reference, and ldap_next_reference.

Chapter 3. Express C/C++ APIs 675


ldap_modify
Purpose: Perform various LDAP modification operations.

Syntax:
#include <ldap.h>

typedef struct ldapmod {


int mod_op;
char *mod_type;
union {
char **modv_strvals;
struct berval **modv_bvals;
} mod_vals;
} LDAPMod;
#define mod_values mod_vals.modv_strvals
#define mod_bvalues mod_vals.modv_bvals

int ldap_modify(
LDAP *ld,
char *dn,
LDAPMod *mods[])

int ldap_modify_ext(
LDAP *ld,
char *dn,
LDAPMod *mods[],
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_modify_s(
LDAP *ld,
char *dn,;
LDAPMod *mods[])

int ldap_modify_ext_s(
LDAP *ld,
char *dn,
LDAPMod *mods[],
LDAPControl **serverctrls,
LDAPControl **clientctrls)

void ldap_mods_free(
LDAPMod **mods,
int freemods)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn Specifies the DN of an entry to change.
mods
Specifies a NULL-terminated array of modifications to make to the entry. Each
element of the mods array is a pointer to an LDAPMod structure (see USAGE
below).
freemods
Specifies whether the mods pointer frees in addition to the NULL-terminated
array of mod structures.

676 Client Access Express Programming


serverctrls
Specifies a list of LDAP server controls. See “LDAP controls” on page 638 for
more information about server controls.
clientctrls
Specifies a list of LDAP client controls. See “LDAP controls” on page 638 for
more information about client controls.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: ldap_modify_s and ldap_modify_ext_s will return the LDAP error
code that result from the modification operation.

ldap_modify and ldap_modify_ext will return -1 instead of a valid msgid if an


error occurs. This sets the session error in the LD structure, which can be obtained
by using ldap_get_errno.

See “ldap_error” on page 653 for more details.

Usage: The use of various modification APIs to perform an LDAP modification


operation exists. dn is the DN of the entry to change, and mods is a
NULL-terminated array of modifications to make to the entry. Each element of the
mods array is a pointer to an LDAPMod structure.

Use the mod_op field to specify the type of modification to perform. The field
should be one of the following:
v LDAP_MOD_ADD (0x00)
v LDAP_MOD_DELETE (0x01)
v LDAP_MOD_REPLACE (0x02)

This field also indicates the type of values that are included in the mod_vals union.
For binary data, you also must logically OR the operation type with
LDAP_MOD_BVALUES (0x80). This indicates that the values are specified in a
NULL-terminated array of struct_berval structures.

The mod_type field specifies the type of attribute to add, change, or delete.

The mod_vals field specifies a pointer to a NULL-terminated array of values to add,


change, or delete, respectively. Only one of the mod_values or mod_bvalues variants
should be used, with the mod_bvalues selected by ORing, and the mod_op field
selected with the constant LDAP_MOD_BVALUES.

mod_values is a NULL-terminated array of NULL-terminated strings. mod_bvalues is


a NULL-terminated array of berval structures that are used to pass binary values
such as images.

For LDAP_MOD_ADD modifications, the given values are added to the entry,
creating the attribute if necessary.

For LDAP_MOD_DELETE modifications, the given values are deleted from the
entry, and remove the attribute if no values remain. To delete the entire attribute,
set the mod_values field to NULL.

Chapter 3. Express C/C++ APIs 677


For LDAP_MOD_REPLACE modifications, the attribute will have created the listed
values after the modification, if necessary, or removed if the mod_vals field is
NULL.

All modifications are performed in the order in which they are listed.

The ldap_modify_ext API initiates an asynchronous change operation and returns


the constant LDAP_SUCCESS if the request was successfully sent, or another
LDAP error code if not. If successful, ldap_modify_ext places the message ID of
the request in *msgidp. A subsequent call to ldap_result can be used to obtain the
result of the operation. Once the operation has completed, ldap_result returns a
result that contains the status of the operation (in the form of an error code). The
error code indicates if the operation completed successfully. The ldap_parse_result
API is used to check the error code in the result.

Similarly, the ldap_modify API initiates an asynchronous change operation and


returns the message ID of the operation initiated. A subsequent call to ldap_result,
can be used to obtain the result of the change. In case of error, ldap_modify will
return -1, using using ldap_get_errno to get the error code.

See “ldap_error” on page 653 for more details.

The synchronous ldap_modify_ext_s and ldap_modify_s APIs both return the


result of the operation. Either the constant LDAP_SUCCESS if the operation was
successful, or another LDAP error code if it was not.

The ldap_modify_ext and ldap_modify_ext_s APIs support LDAP V3 server


controls and client controls.

ldap_modify_s returns the LDAP error code resulting from the change operation.
This error code can be interpreted by ldap_perror and ldap_err2string.

The ldap_modify operation works the same way as ldap_modify_s, except for the
following conditions.
v It is asynchronous.
v It returns the message ID of the request it initiates.
v It returns a -1 on error.
Obtain the result of the operation by calling ldap_result.

The use of ldap_mods_free is not recommended. It is used internally by the LDAP


library. The use of ldap_mods_free by an application may corrupt the application’s
memory management.

678 Client Access Express Programming


ldap_parse_results
Purpose: LDAP routines for extracting information from results and handle errors
that are returned by other LDAP API routines.

Syntax:
#include <ldap.h>

int ldap_parse_result(
LDAP *ld;
LDAPMessage *res,
int *errcodep,
char **matcheddnp,
char **errmsgp,
char ***referralsp,
LDAPControl ***servctrlsp,
int freeit)

int ldap_parse_sasl_bind_result(
LDAP *ld;
LDAPMessage *res,
struct berval **servercredp,
int freeit)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
res
Specifies the result of an LDAP operation as returned by ldap_result or one of
the synchronous LDAP API operation calls.
errcodep
Specifies a pointer to the result parameter that the LDAP error code field fills
in from the LDAPResult message. The LDAP server produces the LDAPResult
message, and indicates the outcome of the operation. Specify NULL for
errcodep to ignore the LDAPResult message.
matcheddnp
Specifies a pointer to a result parameter. When LDAP_NO_SUCH_OBJECT
returns as the LDAP error code, this result parameter fills in with a
Distinguished Name that indicates how much of the name in the request the
server recognized. Specify NULL for matcheddnp to ignore the matched DN.
Call ldap_memfree to free the matched DN string.
errmsgp
Specifies a pointer to a result parameter that is filled in with the contents of
the error message from the LDAPMessage message. Call ldap_memfree to free
the error message string.
referralsp
This parameter specifies a pointer to a result parameter that is filled in with
the contents of the referrals field from the LDAPMessage message. This
message indicates zero or more alternate LDAP servers where the request
retries. Call ldap_value_free to free the referrals array. Supply a NULL for this
parameter to ignore the referrals field.
serverctrlsp
Specifies a pointer to a result parameter that is filled in with an allocated array
of controls that are copied out of the LDAPMessage message. Call
ldap_controls_free to free the control array.

Chapter 3. Express C/C++ APIs 679


freeit
Specifies a boolean value that determines if the LDAP result (as specified by
res) is to become freed. Any non-zero value will result in freeing res after the
requested information extracts. Alternatively, the ldap_msgfree API can be
used to free the result at a later time.
servercredp
Specifies a pointer to a result parameter. For SASL bind results, this result
parameter fills in with the credentials that are returned by the server for
mutual authentication (if returned). The credentials, if returned, return in a
berval structure. Supply a NULL to ignore this field.

Return Codes: The parse routines return an LDAP error code if they encounter an
error by parsing the result.

See “ldap_error” on page 653 for a list of the LDAP error codes.

Usage: The ldap_parse_result API is used to:


v Obtain the LDAP error code field that is associated with an LDAPResult
message.
v Obtain the portion of the DN that the server recognizes for a failed operation.
v Obtain the text error message that is associated with the error code that is
returned in an LDAPMessage message.
v Obtain the list of alternate servers from the referrals field.
v Obtain the array of controls that are potentially returned by the server.

The ldap_parse_sasl_bind_results API is used to obtain server credentials, as a


result of an attempt to perform mutual authentication.

Both of the ldap_parse_*_result APIs ignore messages of type


LDAP_RES_SEARCH_ENTRY and LDAP_RES_SEARCH_REFERENCE when
looking for a result message to parse. They both return LDAP_SUCCESS if the
result successfully parsed, and an LDAP error code if not successfully located and
parsed.

The ldap_err2string API is used to convert the numeric LDAP error code.
(Provided it was returned by one of the ldap_parse_*_result APIs, or one of the
synchronous APIs, into a NULL-terminated character string that describes the
error.) The string returns as static data and must not be freed by the application.

680 Client Access Express Programming


ldap_rename
Purpose: Perform an LDAP rename operation.

Syntax:
#include <ldap.h>

int ldap_rename(
LDAP *ld,
char *dn,
char *newrdn,
char *newparent,
int deleteoldrdn,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp)

int ldap_rename_s(
LDAP *ld,
char *dn,
char *newrdn,
char *newparent,
int deleteoldrdn,
LDAPControl **serverctrls,
LDAPControl **clientctrls)

int ldap_modrdn(
LDAP *ld,
char *dn,
char *newrdn,
int deleteoldrdn)

int ldap_modrdn_s(
LDAP *ld,
char *dn,
char *newrdn,
int deleteoldrdn)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
dn Specifies the DN of an entry whose DN is to change. When specified with the
deprecated ladp_modrdn API and deprecated ldap_modrdn_s API, dn
specifies the DN of the entry whose RDN is to change.
newrdn
Specifies the new RDN that is given to the entry.
newparent
Specifies the new parent, or superior entry. If this parameter is NULL, only the
RDN of the entry changes. Specify the root DN by passing a zero length string,
″″. The newparent parameter always should be NULL when using version 2 of
the LDAP protocol; otherwise the server’s behavior is undefined.
deleteoldrdn
Specifies a boolean value. When set to 1, the old RDN value deletes from the
entry. When set to 0, the old RDN value remains as a non-distinguished value.
With regard to the ldap_rename and ldap_rename_s APIs, this parameter only
has meaning if newrdn is different from the old RDN.

Chapter 3. Express C/C++ APIs 681


serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.
clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: The synchronous version of this routine returns an LDAP error
code, either LDAP_SUCCESS or an error code if there was an error. The
asynchronous version returns -1 in case of trouble. If the asynchronous API is
successful, use ldap_result to obtain the results of the operation. See “ldap_error”
on page 653 for more details.

Usage: In LDAP V2, the ldap_modrdn and ldap_modrdn_s APIs were used to
change the name of an LDAP entry. They could only be used to change the least
significant component of a name (the RDN or relative distinguished name). LDAP
V3 provides the Change DN protocol operation that allows more general name
change access. The ldap_rename and ldap_rename_s routines are used to change
the name of an entry, and the use of the ldap_modrdn and routines is deprecated.

The ldap_rename API initiates an asynchronous change DN operation and returns


the constant LDAP_SUCCESS if the request was successfully sent, or another
LDAP error code if not. If successful, ldap_rename places the DN message ID of
the request in *msgidp. A subsequent call to ldap_result can be used to obtain the
result of the operation. Once the operation has completed, ldap_result returns a
result that contains the status of the operation (in the form of an error code). The
error code indicates if the operation completed successfully. The ldap_parse_result
API is used to check the error code in the result.

Similarly, the ldap_modrdn API initiates an asynchronous change RDN operation


and returns the message ID of the operation initiated. A subsequent call to
ldap_result, can be used to obtain the result of the change. In case of error,
ldap_modrdn will return -1. This sets the session error parameters in the LDAP
structure appropriately. Obtain the parameter by using ldap_get_errno.

The synchronous ldap_rename_s API returns the result of the operation. Either the
constant LDAP_SUCCESS if the operation was successful, or another LDAP error
code if it was not.

The ldap_rename and ldap_rename_s APIs both support LDAP V3 server controls
and client controls.

The ldap_modrdn and ldap_modrdn_s routines perform an LDAP change RDN


operation. They both take dn, the DN of the entry whose RDN is to change, and
newrdn, the new RDN to give the entry. ldap_modrdn_s is synchronous, returning
the LDAP error code indicating the success or failure of the operation. In addition,
they both take the deleteoldrdn parameter. Use this parameter as a boolean value to
indicate whether to delete the old RDN values from the entry.

682 Client Access Express Programming


ldap_result
Purpose:
v Wait for the result of an asynchronous LDAP operation.
v Obtain LDAP message types.
v Obtain the message ID of an LDAP message.

Syntax:
#include <ldap.h>

int ldap_result(
LDAP *ld,
int msgid,
int all,
struct timeval *timeout,
LDAPMessage **result)

int ldap_msgtype(
LDAPMessage *msg)

int ldap_msgid(
LDAPMessage *msg)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
msgid
Specifies the message ID of the operation whose results are to be returned. Set
the parameter to LDAP_RES_ANY if you require any result.
all This parameter only has meaning for search results. For search results, use all
to specify how many search result messages return in a single call to
ldap_result. Specify LDAP_MSG_ONE to retrieve one search result message at
a time. Specify LDAP_MSG_ALL to request receival of all results of a search
before returning all results in a single chain. Specify LDAP_MSG_RECEIVED
to indicate that all results retrieved so far should return in the result chain.
timeout
Specifies how long in seconds to wait for results (as identified by the supplied
msgid) to return from ldap_result. A NULL value causes ldap_result to wait
until results for the operation identified by msgid are available. To poll, the
timeout parameter should be non-NULL, pointing to a zero-valued timeval
structure.
msg
Specifies a pointer to a result, as returned from ldap_result, ldap_search_s,
ldap_search_st, or ldap_search_ext_s.
result
Contains the result of the asynchronous operation that is identified by msgid.
Pass this result to the LDAP through parsing routines such as ldap_first_entry.

If ldap_result is unsuccessful, it returns -1 and sets the appropriate LDAP error


(which can be obtained with ldap_get_errno). If ldap_result times out, it
returns 0. If successful, it returns one of the following result types:
#define LDAP_RES_BIND 0x61L
#define LDAP_RES_SEARCH_ENTRY 0x64L
#define LDAP_RES_SEARCH_RESULT 0x65L

Chapter 3. Express C/C++ APIs 683


#define LDAP_RES_MODIFY 0x67L
#define LDAP_RES_ADD 0x69L
#define LDAP_RES_DELETE 0x6bL
#define LDAP_RES_MODRDN 0x6dL
#define LDAP_RES_COMPARE 0x6fL
#define LDAP_RES_SEARCH_REFERENCE 0X73L
#define LDAP_RES_EXTENDED 0X78L
#define LDAP_RES_ANY (-1L)

Return Codes: ldap_result returns 0 if the timeout expires, and -1 if an error


occurs. Use the ldap_get_errno routine to get the error code.

Usage: The ldap_result routine is used to wait for and return the result of an
operation previously initiated by one of the LDAP asynchronous operation
routines. (For example, ldap_search, ldap_modify, and so forth.) These routines
return a msgid that uniquely identifies the request. Use the msgid to request the
result of a specific operation from ldap_result.

The ldap_msgtype API returns the type of LDAP message, based on the LDAP
message that is passed as input (by using the msg parameter).

The ldap_msgid API returns the message ID associated with the LDAP message
that is passed as input (by using the msg parameter).

Note: This routine allocates memory for results that it receives. Free the memory
by calling ldap_msgfree.

684 Client Access Express Programming


ldap_search
Purpose: Perform various LDAP search operations.

Syntax:
#include <sys/time.h> /* for struct timeval definition */
#include <ldap.h>

int ldap_search(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly)

int ldap_search_ext(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeout,
int sizelimit,
int *msgidp)

int ldap_search_s(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly,
LDAPMessage **res)

int ldap_search_ext_s(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeout,
int sizelimit,
LDAPMessage **res)

int ldap_search_st(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly,
struct timeval *timeout,
LDAPMessage **res)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.

Chapter 3. Express C/C++ APIs 685


base
Specifies the DN of the entry at which to start the search.
scope
Specifies the scope of the search. It can be any of the following parameters.
v LDAP_SCOPE_BASE to search the object itself.
v LDAP_SCOPE_ONELEVEL to search the object’s immediate children.
v LDAP_SCOPE_SUBTREE to search the object and all its descendents.
filter
Specifies a string representation of the filter to apply in the search. Specify
simple filters as attributetype=attributevalue. Specify the more complex filters by
using a prefix notation according to the following BNF:
<filter> ::= '(' <filtercomp> ')'
<filtercomp> ::= <and> | <or> | <not> | <simple>
<and> ::= '&' <filterlist>
<or> ::= '|' <filterlist>
<not> ::= '!' <filter>
<filterlist> ::= <filter> | <filter> <filterlist>
<simple> ::= <attributetype> <filtertype>
<attributevalue>
<filtertype> ::= '=' | 'x=' | '<=' | '>='

Use the ’x=’ construct to specify approximate matching of the filters. The
representation for <attributetype> and <attributevalue> are as described in The

String Representation of Standard Attribute Syntaxes (RFC 1778) . The


<attributevalue> can be a single * to achieve an attribute existence test, or can
contain text and *’s that are interspersed to matching achieve substrings.

For example, the filter ″mail=*″ will find any entries that have a mail attribute.
The filter ″mail=*@terminator.rs.itd.umich.edu″ will find any entries that have a
mail attribute that end in the specified string. To put parentheses in a filter,
escape them with a backslash ’\\’ character. See A String Representation of

LDAP Search Filters (RFC 1558) for a more complete description of


allowable filters.
attrs
Specifies a NULL-terminated array of character string attribute types to return
from entries that match filter. Specifying NULL returns all attributes.
attrsonly
Specifies attribute information. Set attrsonly to 1 to request attribute types only.
Set it to 0 to request both attributes types and attribute values.
timeout
For the ldap_search_st API, this specifies the local search timeout value. For
the ldap_search_ext and ldap_search_ext_s APIs, this function specifies both
the local search timeout value and the operation time limit that is sent to the
server within the search request.
serverctrls
Specifies a list of LDAP server controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about server controls.
clientctrls
Specifies a list of LDAP client controls. This parameter may be set to NULL.
See “LDAP controls” on page 638 for more information about client controls.

686 Client Access Express Programming


res
Contains the result of the asynchronous operation that is identified by msgid,
as returned from ldap_search_s or ldap_search_st. Pass this result to the
parsing routines that are used by LDAP (see “ldap_result” on page 683).
msgidp
This result parameter is set to the message ID of the request if the
ldap_add_ext call succeeds.

Return Codes: ldap_search_s, ldap_search_ext_s, and ldap_search_st will return


the LDAP error code resulting from the search operation.

ldap_search and ldap_search_ext returns -1 instead of a valid msgid if an error


occurs. This sets the session error in the LD structure. Obtain this by using
ldap_get_errno.

See “ldap_error” on page 653 for more details.

Usage: Use these routines to perform LDAP search operations.

The ldap_search_ext API initiates an asynchronous search operation and returns


the constant LDAP_SUCCESS if the request was successfully sent, or another
LDAP error code if not.

If successful, ldap_search_ext places the message ID of the request in *msgidp. A


subsequent call to ldap_result can be used to obtain the results from the search.

Once the operation has completed, ldap_result returns a result that contains the
status of the operation (in the form of an error code). The error code indicates if
the operation completed successfully. The ldap_parse_result API is used to check
the error code in the result.

Similar to ldap_search_ext, the ldap_search API initiates an asynchronous search


operation and returns the message ID of the operation initiated. If an error occurs,
ldap_search will return -1, setting the session error in the LD structure, which can
be obtained by using ldap_get_errno. If successful, a subsequent call to ldap_result
can be used to obtain the results from the search.

The synchronous ldap_search_ext_s, ldap_search_s, and ldap_search_st functions


all return the result of the operation. Either the constant LDAP_SUCCESS if the
operation was successful, or another LDAP error code if it was not. See LDAP
Errors for more information about possible errors and how to interpret them. The
res parameter contains any entries that are returned from the search. This
parameter is opaque to the caller. Extract entries, attributes, values, and so forth,
by calling the result parsing routines. Free the results that are contained in res
when no longer in use by calling ldap_msgfree.

The ldap_search_ext and ldap_search_ext_s APIs support LDAP V3 server


controls, client controls, and allow varying size and time limits to be easily
specified for each search operation. The ldap_search_stAPI is identical to
ldap_search_s except that it takes an additional parameter specifying a local
timeout for the search.

There are three options in the session handle ld which potentially affects the
performance of the search. They are:

Chapter 3. Express C/C++ APIs 687


LDAP_OPT_SIZELIMIT
A limit on the number of entries to return from the search.
A value of zero means no limit. Note that the value from
the session handle is ignored when using the
ldap_search_ext() or ldap_search_ext_s() functions.

LDAP_OPT_TIMELIMIT
A limit on the number of seconds to spend on the search. A
value of zero means no limit. Note that the value from the
session handle is ignored when using the ldap_search_ext()
or ldap_search_ext_s() functions.

LDAP_OPT_DEREF
One of LDAP_DEREF_NEVER (0x00), LDAP_DEREF_SEARCHING
(0x01), LDAP_DEREF_FINDING (0x02), or LDAP_DEREF_ALWAYS
(0x03), specifying how aliases should be handled during the
search. The LDAP_DEREF_SEARCHING value means aliases should
be dereferenced during the search but not when locating the
base object of the search. The LDAP_DEREF_FINDING value
means aliases should be dereferenced when locating the base
object but not during the search.

READING AN ENTRY

LDAP does not support a read operation directly. Instead, this operation is
emulated by a search with base set to the DN of the entry to read, scope set to
LDAP_SCOPE_BASE, and filter set to ″(objectclass=*)″. attrs contains the list of
attributes to return.

LISTING THE CHILDREN OF AN ENTRY

LDAP does not support a list operation directly. Instead, this operation is emulated
by a search with base set to the DN of the entry to list, scope set to
LDAP_SCOPE_ONELEVEL, and filter set to ″(objectclass=*)″. attrs contains the list
of attributes to return for each child entry.

If only the distinguished names of child entries is required, the attrs parameter
should specify a NULL-terminated array of one character string, which has the
value ″dn″.

Note: These routines use malloc to allocate storage that is returned by the res
parameter. Use ldap_msgfree to free this storage.

688 Client Access Express Programming


ldap_ssl
Purpose: Routines for initializing the Secure Socket Layer (SSL) function for an
LDAP application, and creating a secure (SSL) connection to an LDAP server.

Syntax:
#include <ldap.h>
#include <ldapssl.h>

int ldap_ssl_client_init(
char *keyring,
char *keyring_pw,
int ssl_timeout)
int *pSSLReasonCode)

LDAP *ldap_ssl_init(
char *host,
int port,
char *name)

int ldap_ssl_start(
LDAP *ld,
char *keyring,
char *keyring_pw,
char *name)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
host
Specifies the name of the host on which the LDAP server is running. The host
parameter may contain a blank-separated list of connection hosts. Additionally,
each host may optionally be of the form host:port. If present, the :port overrides
the ldap_ssl_init port parameter to supplied on ldap_init or ldap_open. If the
host parameter is null, the LDAP server is assumed to be running on the local
host.
port
Specifies the port number to which to connect. If you want the default
IANA-assigned SSL port of 636, specify LDAPS_PORT.
keyring
Specifies the key database file (with ″kdb″ extension). The key database file
typically contains one or more certificates of certification authorities (CAs) that
are trusted by the client. These types of X.509 certificates also are known as
trusted roots. Use of a key database file extends to storing the client’s private
keys and associated client certificates. Requirement for a private key and
associated client certificate exists only if the LDAP server configuration
requires client and server authentication. If the LDAP server configuration
provides only server authentication, a private key and a client certificate are
not used.

Note: Although still supported, use of ldap_ssl_start is discouraged (it is


obsolete). Any application that uses the ldap_ssl_start API should use
only a single key-database file (per application process).

IBM recommends a fully-qualified path and filename. If a filename is


specified without a fully-qualified path, the LDAP library looks in the

Chapter 3. Express C/C++ APIs 689


current directory for the file. Create the key database file that is
specified here using the ikmgui utility. If a key database file name is not
provided, the default roots for trusted Certification Authorities (CAs) are
used.
keyring_pw
Specifies the password that is used to protect the contents of the key ring file.
This password is important since it protects the private key that is stored in
the key ring file. The password was specified when the key ring file initially
created. A null password is accepted.
name
Specifies the name, or label, associated with the client private key/certificate
pair in the key ring file. With respect to mkkf, call the dn the key name. It is
used to uniquely identify a private key/certificate pair, as stored in the key
ring file, and may be something like: ″Digital ID for Fred Smith″.

If the LDAP server configuration performs Server Authentication, it does not


require a client certificate, (so set name to null). If the LDAP server
configuration performs Client and Server Authentication, it does require a client
certificate. name can be set to null if a default certificate/private key pair has
been designated as the default (using mkkf). Similarly, name can be set to null
if there is a single certificate/private key pair in the designated key ring file.
ssl_timeout
Specifies the SSL timeout value in seconds. The timeout value controls the
frequency with which the SSL protocol stack regenerates session keys. Setting
ssl_timeout to 0 uses the default value of SSLV3_CLIENT_TIMEOUT.
Otherwise, the value supplied will be used, provided it is less than or equal to
86,400 (number of seconds in a day). If ssl_timeout is greater than 86,400,
LDAP_PARAM_ERROR returns.
pSSLReasonCode
Specifies a pointer to the SSL Reason Code, which provides additional
information in the event that an error occurs during intialization of SSL stack
(when ldap_ssl_client_init is invoked). See ldapssl.h for reason codes that can
be returned.

Return Codes: None.

Usage: ldap_ssl_client_init is used to start the SSL protocol stack for an


application process. Start it once prior to making any other LDAP calls. Once
ldap_ssl_client_init has been successfully started, any subsequent calls will return
a return code of LDAP_SSL_ALREADY_INITIALIZED.

ldap_ssl_init is the SSL equivalent of ldap_init. Use it to initialize a secure SSL


session with a server. Note that the server is not actually contacted until
performing an operation requires it. This allows the setting of various options after
initialization. Once the secure connection is established for the ld, all subsequent
LDAP messages that flow over the secure connection are encrypted. This includes
the ldap_simple_bind parameters, until ldap_unbind is invoked.

ldap_ssl_init returns a ″session handle,″ which is a pointer to an opaque data


structure that should be passed to subsequent calls that pertain to the session.
These subsequent calls will return NULL if the session cannot actually be
established with the server. Use ldap_get_option to determine why the call failed.

690 Client Access Express Programming


The LDAP session handle returned by ldap_ssl_init (and ldap_init) is a pointer to
an opaque data type that represents an LDAP session. The ldap_get_option and
ldap_set_option APIs are used to access and set a variety of session-wide
parameters. See ldap_get_option and ldap_set_option for more information.

When connecting to an LDAP V2 server, one of the ldap_simple_bind or


ldap_bind calls must be completed before other operations can be performed on
the session. (ldap_set/get_options is the only exception to this set-up.) The LDAP
V3 protocol does not require a bind operation before performing other operations.

Although still supported, the use of the ldap_ssl_start API is now deprecated. The
ldap_ssl_client_init and ldap_ssl_init APIs should be used instead. The
ldap_ssl_start API starts a secure connection (using SSL) to an LDAP server.
ldap_ssl_start accepts the ld from a ldap_open and performs an SSL handshake to
a server. ldap_ssl_start must be called after ldap_open and prior to ldap_bind.
Once the secure connection is established for the ld, all subsequent LDAP
messages that flow over the secure connection are encrypted. This includes the
ldap_bind parameters, until ldap_unbind is invoked.

The following scenario depicts the recommended calling sequence where the entire
set of LDAP transactions are ″protected″ by using a secure SSL connection. This
includes the dn and password that flow on the ldap_simple_bind:
rc = ldap_ssl_client_init (keyfile, keyfile_pw, timeout, reasoncode);
ld = ldap_ssl_init(ldaphost, ldapport, label );
rc = ldap_set_option( ld, LDAP_OPT_SSL_CIPHER, &ciphers);
rc = ldap_simple_bind_s(ld, binddn, passwd);

...additional LDAP API calls

rc = ldap_unbind( ld );

The sequence of calls for the deprecated APIs is ldap_open/init, ldap_ssl_start,


followed by ldap_bind.

The SSL handshake attempts the following ciphers by default, in the order that is
shown.
(Export Version)

RC4_MD5_EXPORT
RC2_MD5_EXPORT

(Non-export Version)

RC4_SHA_US
RC4_MD5_US
DES_SHA_US
3DES_SHA_US
RC4_MD5_EXPORT
RC2_MD5_EXPORT

ldap_ssl options

Support exists for options that control the nature of the secure connection. Set
these options by using the ldap_set_option API.

To specify the number of seconds for the SSL session-level timer, use:
ldap_set_option(ld,LDAP_OPT_SSL_TIMEOUT, &timeout)

Chapter 3. Express C/C++ APIs 691


Where timeout specifies timeout in seconds. When timeout occurs, SSL
re-establishes the session keys for the session, for increased security.

To specify a specific cipher, or set of ciphers, to be used when negotiating with the
server, use ldap_set_option to define a sequence of ciphers. For example, the
following defines a sequence of three ciphers to use when negotiating with the
server. The first cipher that is found to be in common with the server’s list of
ciphers is used.
ldap_set_option( ld, LDAP_OPT_SSL_CIPHER, (void *)
LDAP_SSL_3DES_SHA_US
LDAP_SSL_RC4_MD5_US);

Refer to ldap.h for the following ciphers definitions.


(Export Version)

#define LDAP_SSL_RC4_MD5_EX

#define LDAP_SSL_RC2_MD5_EX

(Non-export Version)

#define LDAP_SSL_RC4_SHA_US
#define LDAP_SSL_RC4_MD5_US
#define LDAP_SSL_DES_SHA_US
#define LDAP_SSL_3DES_SHA_US
#define LDAP_SSL_RC4_MD5_EX
#define LDAP_SSL_RC2_MD5_EX

For more information on ldap_set_option, see LDAP Options.

Note: ldapssl.h contains return codes that are specific for ldap_ssl_client_init,
ldap_ssl_init, and ldap_ssl_start.

The SSL versions of these utilities include RSA(1) software.

The ldap_ssl_client_init, ldap_ssl_init, and ldap_ssl_start APIs are only


supported when the SSL library is installed.

(1) RSA is a trademark of RSA Data Security, Inc.

692 Client Access Express Programming


ldap_url
Purpose: LDAP Uniform Resource Locator routines.

Syntax:
#include <sys/time.h> /* for struct timeval definition */

#include <ldap.h>

int ldap_is_ldap_url(
char *url)

int ldap_url_parse(
char *url,
LDAPURLDesc **ludpp)

typedef struct ldap_url_desc {


char *lud_host; /* LDAP host to contact */
int lud_port; /* port on host */
char *lud_dn; /* base for search */
char **lud_attrs; /* NULL-terminate list of attributes */
int lud_scope; /* a valid LDAP_SCOPE_... value */
char *lud_filter; /* LDAP search filter */
char *lud_string; /* for internal use only */
} LDAPURLDesc;

ldap_free_urldesc(
LDAPURLDesc *ludp)

int ldap_url_search(
LDAP *ld,
char *url,
int attrsonly)

int ldap_url_search_s(
LDAP *ld,
char *url,
int attrsonly,
LDAPMessage **res)

int ldap_url_search_st(
LDAP *ld,
char *url,
int attrsonly,
struct timeval *timeout,
LDAPMessage **res)

Parameters:
ld Specifies the LDAP pointer that is returned by a previous call to ldap_init,
ldap_ssl_init, or ldap_open.
url
Specifies a pointer to the URL string.
attrsonly
Specifies attribute information. Set to 1 to request attribute types only. Set to 0
to request both attribute types and attribute values.
timeout
Specifies a timeout value for a synchronous search that is issued by the
ldap_url_search_st routine.

Chapter 3. Express C/C++ APIs 693


ludpp
Points to the LDAP URL description, as returned by ldap_url_parse.
res
Contains the result of the asynchronous operation that is identified by msgid,
as returned from ldap_url_search_s or ldap_url_search_st. Pass this result to
the parsing routines of LDAP.

Return Codes: None.

Usage: These routines support the use of LDAP URLs (uniform resource locators).
LDAP URLs look like this:
ldap://[hostport]/dn[?attributes[?scope[?filter]]]

where:
hostport is a host name with an optional ":portnumber"
dn\f is the base DN to be used for an LDAP search operation
attributes is a comma separated list of attributes to be retrieved
scope is one of these three strings: base one sub (default=base)
filter\f is LDAP search filter as used in a call to ldap_search

for example, ldap://ldap.itd.umich.edu/c=US?o,description?one?o=umich

Tolerated URLs include those that are wrapped in angle-brackets or preceded by


″URL:″. This includes the following forms:
URL:ldapurl

for example
URL:ldap://ldap.itd.umich.edu/c=US?o,description?one?o=umich
<URL:ldapurl>

for example
<URL:ldap://ldap.itd.umich.edu/c=US?o,description?one?o=umich>

ldap_is_ldap_url returns a non-zero value if url begins with ″ldap://″. It can be


used as a quick check for an LDAP URL; the ldap_url_parse routine is used to
extract the various components of the URL.

ldap_url_parse breaks down an LDAP URL passed in url into its component
pieces. If successful, zero returns, an LDAP URL description allocates, fills in, and
setsludpp to point to it. If an error occurs, one of these values returns:
LDAP_URL_ERR_NOTLDAP - URL does not begin with "ldap://"
LDAP_URL_ERR_NODN - URL has no DN (required)
LDAP_URL_ERR_BADSCOPE - URL scope string is invalid
LDAP_URL_ERR_MEM - cannot allocate memory space

ldap_free_urldesc should be called to free an LDAP URL description that was


obtained from a call to ldap_url_parse.

ldap_url_search initiates an asynchronous LDAP search based on the contents of


the url string. This routine acts just like ldap_search except that the search
parameters are pulled out of the URL.

ldap_url_search_s performs a synchronous LDAP search based on the contents of


the url string. This routine acts just like ldap_search_s except that the search
parameters are pulled out of the URL.

694 Client Access Express Programming


ldap_url_search_st performs a synchronous LDAP URL search with a specified
timeout. This routine acts just like ldap_search_st except that the search parameters
are pulled out of the URL.

Note: For search operations, omitting hostport causes the system to use the host
and port for the current connection. Specifying hostport different from host
and port combination that are used for the current connection, directs the
search to hostport instead of the current connection. In this case, use the
underlying referral mechanism to bind to hostport.

If the LDAP URL does not contain a search filter, the filter defaults to
objectClass=*.

Chapter 3. Express C/C++ APIs 695


Distinguished names format
Use distinguished names to uniquely identify entries in an LDAP or X.500
directory. Distinguished names are user-adjusted strings. They typically are used:
v To add, change, or delete an entry in directories that use the LDAP
programming interface
v When you are using the LDAP utilities such as “ldapmodify” on page 626,
“ldapsearch” on page 633, “ldapmodrdn” on page 630, and “ldapdelete” on
page 623

A distinguished name typically is composed of an ordered set of attribute


type/attribute value pairs. The following are the most commonly used pairs:
v common name (cn)
v organization (o) or organizational unit (ou)
v country (c)

The following string-type attributes represent the set of standardized attribute


types for accessing an LDAP directory. Note however that almost any attributes
can compose a distinguished name, provided that the directory is not configured to
perform schema checking.
v CN - CommonName
v L - LocalityName
v ST - StateOrProvinceName
v O - OrganizationName
v OU - OrganizationalUnitName
v C - CountryName
v STREET - StreetAddress
Related topics:
v “Distinguished names format: informal definition”
v “Distinguished names format: formal definition” on page 697

Distinguished names format: informal definition


This notation is designed to be convenient for common forms of name. Most
distinguished names begin with CommonName (CN), and progress up the naming
tree of the directory. Typically, as you read from left to right, each component of
the name represents increasingly larger groupings of entries, ending with
CountryName (C). Remember that sequence is important. For example, the
following two distinguished names do not identify the same entry in the directory:

CN=wiley coyote, O=acme, O=anvils, C=US

CN=wiley coyote, O=anvils, O=acme, C=US

Some examples appear below. The author of A String Representation of Distinguished

Names (RFC 1779) is specified as:


CN=Steve Kille, O=ISODE Consortium, C=GB

Another name might be:


CN=Christian Huitema, O=INRIA, C=FR

Semicolon (″;″) may be used as an alternate separator. The possibility exists to mix
separators, but this usage is discouraged.

696 Client Access Express Programming


CN=Christian Huitema; O=INRIA; C=FR

Here is an example of a multi-valued relative distinguished name. The namespace


is flat within an organization, and use of the department name disambiguates
certain names:
OU=Sales + CN=J. Smith, O=Widget Inc., C=US

The final examples show both methods for the quoting of a comma in an
Organization name:
CN=L. Eagle, O="Sue, Grabbit and Runn", C=GB

CN=L. Eagle, O=Sue\, Grabbit and Runn, C=GB

Distinguished names format: formal definition


For a formal and comprehensive definition of distinguished names to use with the
LDAP interfaces, see Lightweight Directory Access Protocol (V3):UTF-8 String
Representation of Distinguished Names (RFC 2253). To view the document:
How to view the document:
1. Follow this link to the Internet Engineering Task Force (IETF) Web site’s

Directory List of Requests for Comments .


2. Scroll down and select rfc2253.txt.

LDAP Data Interchange Format (LDIF)


This topic provides a description of the LDAP Data Interchange Format (LDIF),
especially as used by the ldapmodify, ldapadd, and ldapsearch command-line
utilities that are provided with this toolkit. Other utilities that are referred to in
this documentation are not supplied with the toolkit. LDAP entries in text form
use LDIF for representation.

The basic form of an LDIF entry is:


dn: <distinguished name>
<attrtype>: <attrvalue>
<attrtype>: <attrvalue>
...

A line may be continued by starting the next line with a single space or tab
character, for example,
dn: cn=Barbara J Jensen, o=University of Michi
gan, c=US

Multiple attribute values are specified on separate lines, for example,


cn: Barbara J Jensen
cn: Barb Jensen

If an <attrvalue> contains a non-printing character, or begins with a space or a


colon ’:’, follow the <attrvalue> by a double colon, and the value encodes in base
64 notation. For example, the value ″ begins with a space″ would be encoded like
this:
cn:: IGJlZ2lucyB3aXRoIGEgc3BhY2U=

Blank lines separate multiple entries within the same LDIF file.
View an example of LDIF:
“Example: LDIF” on page 698

Chapter 3. Express C/C++ APIs 697


Example: LDIF
The following example of an LDIF file contains three entries.
dn: cn=Barbara J Jensen, o=University of Michi
gan, c=US
cn: Barbara J Jensen
cn: Barb Jensen
objectclass: person
sn: Jensen

dn: cn=Bjorn J Jensen, o=University of Michi


gan, c=US
cn: Bjorn J Jensen
cn: Bjorn Jensen
objectclass: person
sn: Jensen

dn: cn=Jennifer J Jensen, o=University of Michi


gan, c=US
cn: Jennifer J Jensen
cn: Jennifer Jensen
objectclass: person
sn: Jensen
jpegPhoto:: /9j/4AAQSkZJRgABAAAAAQABAAD/2wBDABALD
A4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQ
ERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVG
...

Notice that the jpegPhoto that is encoded in Jennifer Jensen’s entry now uses base
64.

Express Multimedia APIs


Ultimedia System Facilities (USF) is an object-based multimedia management
system, and an integrated function of OS/400. It provides a series of functions that
are available to applications through application program interfaces (APIs). USF
APIs are available to both AS/400 and client PC applications. These APIs use
standard interfaces that are callable from high-level languages (COBOL, RPG, and
C). The client APIs are callable from programs that support C-style APIs. The API
requests are routed to either the AS/400 or a client PC, depending on which
platform is best suited to perform the function.

Support for Ultimedia System Facilities APIs resides in the application layer above
the operating system. It uses standard operating system interfaces, including:
v Client Access/400 for communications between the AS/400 system and the
client
v Network drives to store both byte-stream multimedia data and attribute data
v Multimedia extensions that are supplied by Microsoft Windows environments
v Standard graphical user interface-support of the Windows environment
v AS/400 security for the protection of objects that are stored in the Ultimedia
System Facilities Multimedia Repository
Express Toolkit:
The Client Access Express Toolkit provides USF APIs documentation,
access to the USF interface definition (header) files, and links to sample
programs. To access this information, open the Express Toolkit and select
Multimedia —> C/C++ APIs.
Using USF in Windows:

See the IBM Ultimedia System Facilities Web site

698 Client Access Express Programming


Express Multimedia topics:
v “Ultimedia System Facilities API capabilities overview”
v “Ultimedia System Facilities API types overview”
Related IBM publications:
v Ultimedia System Facilities User Guide: SC41-4541
v OS/400 Ultimedia System Facilities Programming: SC41-4652

Ultimedia System Facilities API capabilities overview


Ultimedia System Facilities APIs allow you to do the following:
v Add multimedia functions to existing AS/400 applications
v Add multimedia interfaces to existing AS/400 applications with little
modification to the existing application
v Create new AS/400 applications that use multimedia
v Create new client applications that use multimedia
v Create cooperative (AS/400 and client) applications that use multimedia
v Use the AS/400 system as a Multimedia Repository and server for either
AS/400-based or client-based tools or applications
v Use diverse multimedia devices such as digital video adapters, compact disc
(CD) players, videodisc players, videocassette recorders (VCRs), and audio
boards through the Multimedia Extensions Media Control Interface
v Share video media without physically handling the video devices or having
players attached to dedicated viewing stations
v Sequence the delivery and presentation of multiple multimedia objects to the
client
v Import and track multimedia objects that were created by industry-standard
authoring tools
v Use multimedia input and output such as touch screens, audio output,
full-motion video, and images

Ultimedia System Facilities API types overview


The following types of APIs comprise the Ultimedia System Facilities APIs:
Object Management APIs
These APIs query, create, change, and delete Ultimedia System Facilities
objects and their attributes.
Multimedia APIs
These APIs support various ways of capturing, editing, and presenting
multimedia objects. They also allow the integration of multimedia into an
AS/400 or client application.
Shared Analog Device Control (SADC) APIs
These APIs control the shared multimedia analog devices that are attached
to the AS/400 system.
Cooperative Process Management (CPM) APIs
Every client Ultimedia System Facilities application must use the two CPM
APIs that start and stop CPM processing (fzzmInitializeUSFComm and
fzzmStopUSFComm). Additional CPM APIs provide optional functions
such as:
v Sending a request for processing from one platform to the other
v Returning request data
v Retrieving data sent from another process

Chapter 3. Express C/C++ APIs 699


Express AS/400 Objects APIs
Client Access Express AS/400 Objects application programming interfaces (APIs)
allow you to work with AS/400 print-related objects. These APIs make it possible
to work with AS/400 spooled files, writer jobs, output queues, printers, and more.

By using AS/400 Objects APIs, you can write workstation applications that are
customized for the user’s environment. For example, you can write an application
to manage spooled files for a single user, or for all users across a network of
AS/400s. This includes holding, releasing, changing attributes of, deleting, sending,
retrieving and answering messages for the spooled files.
Express AS/400 Objects APIs required files:

Header file Import library Dynamic Link Library


cwbobj.h cwbapi.lib cwbobj.dll

Express Toolkit:
The Client Access Express Toolkit provides AS/400 Objects documentation,
access to the cwbobj.h header file, and links to sample programs. To access
this information, open the Express Toolkit and select AS/400 Operations
—> C/C++ APIs.
Express AS/400 Objects APIs topics:
v “AS/400 objects attributes”
v Express AS/400 Objects API listing
v “Example: Using Express AS/400 Objects APIs” on page 815
v “Express AS/400 Object APIs return codes” on page 26
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

AS/400 objects attributes


Network Print Server objects have attributes. The Network Print Server supports
the following attributes. Refer to the data stream description for each object/action
to determine the attributes that are supported for that combination.

700 Client Access Express Programming


AS/400 objects attributes listing
“Advanced Function Printing” “Front Overlay Offset Across” on “Replace
page 710Unprintable Characters” on page 719
“Align Page” on page 702 “Front Overlay Offset Down” on page 710
“Replacement Character” on page 719
“Graphic Character Set” on page
“Allow Direct Print” on page 702 710
“Resource library name” on page 720
“Authority” on page 702 “Hardware Justification” on page 710
“Resource name” on page 720
“Hold Spool File” on page 711 “Resource object type” on page 720
“Authority to Check” on page 702
“Automatically End Writer” on “Initialize
page 702 the writer” on page 711“Restart Printing” on page 720
“Back Margin Offset Across” on“Internet
page 703Address” on page 711“Save Spooled File” on page 720
“Back Margin Offset Down” on“JobpageName”
703 on page 711 “Seek Offset” on page 720
“Backside Overlay Library Name”“JobonNumber”
page 703on page 711 “Seek Origin” on page 721
“Backside Overlay Name” on page“Job703
Separators” on page 711 “Send Priority” on page 721
“Back Overlay offset across” on“Job
pageUser”
703 on page 712 “Separator page” on page 721
“Back Overlay Offset Down” on“Last
pagePage
703 Printed” on page 712 “Source Drawer” on page 721
“Length of Page” on page 712 “Spool SCS” on page 721
“Characters per Inch” on page 704
“Code Page” on page 704 “Library Name” on page 712 “Spool the Data” on page 721
“Coded Font Name” on page 704 “Lines Per Inch” on page 712 “Spooled File Name” on page 722
“Coded Font Library Name” on“Manufacturer
page 704 Type and Model” on pageFile
“Spooled 712Number” on page 722
“Copies” on page 704 “Maximum Spooled Output Records” “Spooledon File
pageStatus”
713 on page 722
“Measurement
“Copies left to Produce” on page 704 Method” on page 713
“Spooled Output Schedule” on page 722
“Current Page” on page 705 “Message Help” on page 713 “Starting Page” on page 722
“Data Format” on page 705 “Message ID” on page 713 “Text Description” on page 723
“Data Queue Library Name” on“Message
page 705 Queue Library Name” on page
“Time File 713
Opened” on page 723
“Data Queue Name” on page 705 “Message Queue” on page 713 “Total Pages” on page 723
“Date File Opened” on page 705“Message Reply” on page 714 “Transform SCS to ASCII” on page 723
“User Specified DBCS Data” on“Message
page 705 Text” on page 714 “Unit of Measure” on page 723
“DBCS Extension Characters” on “Message
page 706Type” on page 714 “User Comment” on page 723
“DBCS Character Rotation” on “Message
page 706 Severity” on page 714“User Data” on page 724
“DBCS Characters per Inch” on“Number
page 706 of Bytes to Read/Write” on defined
“User page 714data” on page 724
“DBCS SO/SI Spacing” on page“Number
706 of Files” on page 715 “User defined object library” on page 724
“Defer Write” on page 706 “Number of Writers Started to “User
Queue” on page
defined 715 name” on page 724
object
“Object
“Degree of Page Rotation” on page 706 Extended Attribute” on“User
page 715
defined object type” on page 724
“Delete File After Sending” on “Open
page 707time commands” on page 715 defined option(s)” on page 724
“User
“Operator Controlled” on page “User
“Destination Option” on page 707 715 driver program” on page 725
“Destination Type” on page 707“Order of Files On Queue” on page “User716
driver program library” on page 725
“Device Class” on page 707 “Output Priority” on page 716 “User driver program name” on page 725
“Device Model” on page 707 “Output Queue Library Name”“User on page
ID”716
on page 725
“Device Type” on page 707 “Output Queue Name” on page“User 716 ID Address” on page 725
“Display any File” on page 708 “Output Queue Status” on page“User716 transform program library” on page 725
“Drawer for Separators” on page“Overflow
708 Line Number” on page 716transform program name” on page 726
“User
“Ending Page” on page 708 “Pages Per Side” on page 717 “VM/MVS Class” on page 726
“File Separators” on page 708 “Pel Density” on page 717 “When to Automatically End Writer” on page
“Fold Records” on page 708 “Point Size” on page 717 “When to End Writer” on page 726
“Font Identifier” on page 709 “Print Fidelity” on page 717 “When to Hold File” on page 726
“Form Feed” on page 709 “Print on Both Sides” on page 717“Width of Page” on page 726
“Form Type” on page 709 “Print Quality” on page 718 “Workstation Customizing Object Name” on p
“Form Type Message Option” on “Print
pageSequence”
709 on page 718 “Workstation Customizing Object Library” on
“Front Margin Offset Across” on“Print
pageText”
709 on page 718 “Writer Job Name” on page 727
“Front Margin Offset Down” on“Printer”
page 709on page 718 “Writer Job Number” on page 727
“Front Overlay Library Name” “Printer
on page Device
710 Type” on page 718
“Writer Job Status” on page 727
“Front Overlay Name” on page“Printer
710 File Library Name” on“Writer
page 718Job User Name” on page 727
“Printer File Name” on page 719 “Writer Starting Page” on page 728
“Printer Queue” on page 719 “Network Print Server Object Attributes” on p
“Record Length” on page 719
“Remote System” on page 719

Advanced Function Printing


Key CWBOBJ_KEY_AFP
ID 0x000A

Chapter 3. Express C/C++ APIs 701


Type char[11]
Description
Indicates whether this spooled file uses AFP resources external to the
spooled file. Valid values are *YES and *NO.

Align Page
Key CWBOBJ_KEY_ALIGN
ID 0x000B
Type char[11]
Description
Indicates whether a forms alignment message is sent prior to printing this
spooled file. Valid values are *YES, *NO.

Allow Direct Print


Key CWBOBJ_KEY_ALWDRTPRT
ID 0x000C
Type char[11]
Description
Indicates whether the printer writer allows the printer to be allocated to a
job that prints directly to a printer. Valid values are *YES, *NO.

Authority
Key CWBOBJ_KEY_AUT
ID 0x000D
Type char[11]
Description
Specifies the authority that is given to users who do not have specific
authority to the output queue. Valid values are *USE, *ALL, *CHANGE,
*EXCLUDE, *LIBCRTAUT.

Authority to Check
Key CWBOBJ_KEY_AUTCHK
ID 0x000E
Type char[11]
Description
Indicates what type of authorities to the output queue allow the user to
control all the files on the output queue. Valid values are *OWNER,
*DTAAUT.

Automatically End Writer


Key CWBOBJ_KEY_AUTOEND
ID 0x0010
Type char[11]
Description
Specifies if the writer should be automatically ended. Valid values are
*NO, *YES.

702 Client Access Express Programming


Back Margin Offset Across
Key CWBOBJ_KEY_BACKMGN_ACR
ID 0x0011
Type float
Description
For the back side of a piece of paper, it specifies, how far in from the left
side of the page printing starts. The special value *FRONTMGN will be
encoded as -1.

Back Margin Offset Down


Key CWBOBJ_KEY_BACKMGN_DWN
ID 0x0012
Type float
Description
For the back side of a piece of paper, it specifies, how far down from the
top of the page printing starts. The special value *FRONTMGN will be
encoded as -1.

Backside Overlay Library Name


Key CWBOBJ_KEY_BKOVRLLIB
ID 0x0013
Type char[11]
Description
The name of the library that contains the back overlay. If the back overlay
name field has a special value, this library field will be blank.

Backside Overlay Name


Key CWBOBJ_KEY_BKOVRLAY
ID 0x0014
Type char[11]
Description
The name of the back overlay. Valid special values include *FRONTMGN.

Back Overlay offset across


Key CWBOBJ_KEY_BKOVL_ACR
ID 0x0016
Type float
Description
The offset across from the point of origin where the overlay is printed.

Back Overlay Offset Down


Key CWBOBJ_KEY_BKOVL_DWN
ID 0x0015
Type float

Chapter 3. Express C/C++ APIs 703


Description
The offset down from the point of origin where the overlay is printed.

Characters per Inch


Key CWBOBJ_KEY_CPI
ID 0x0017
Type float
Description
The number of characters per horizontal inch.

Code Page
Key CWBOBJ_KEY_CODEPAGE
ID 0x0019
Type char[11]
Description
The mapping of graphic characters to code points for this spooled file. If
the graphic character set field contains a special value, this field may
contain a zero (0).

Coded Font Name


Key CWBOBJ_KEY_CODEDFNT
ID 0x001A
Type char[11]
Description
The name of the coded font. A coded font is an AFP resource that is
composed of a character set and a code page. Special values include
*FNTCHRSET.

Coded Font Library Name


Key CWBOBJ_KEY_CODEDFNTLIB
ID 0x0018
Type char[11]
Description
The name of the library that contains the coded font. This field may
contain blanks if the coded font name field has a special value.

Copies
Key CWBOBJ_KEY_COPIES
ID 0x001C
Type long
Description
The total number of copies to be produced for this spooled file.

Copies left to Produce


Key CWBOBJ_KEY_COPIESLEFT
ID 0x001D

704 Client Access Express Programming


Type long
Description
The remaining number of copies to be produced for this spooled file.

Current Page
Key CWBOBJ_KEY_CURPAGE
ID 0x001E
Type long
Description
Current page that is being written by the writer job.

Data Format
Key CWBOBJ_KEY_DATAFORMAT
ID 0x001F
Type char[11]
Description
Data format. Valid values are *RCDDATA, *ALLDATA.

Data Queue Library Name


Key CWBOBJ_KEY_DATAQUELIB
ID 0x0020
Type char[11]
Description
The name of the library that contains the data queue.

Data Queue Name


Key CWBOBJ_KEY_DATAQUE
ID 0x0021
Type char[11]
Description
Specifies the name of the data queue that is associated with the output
queue.

Date File Opened


Key CWBOBJ_KEY_DATE
ID 0x0022
Type char[8]
Description
The date the spooled file was opened. The date is encoded in a character
string with the following format, C YY MM DD.

User Specified DBCS Data


Key CWBOBJ_KEY_DBCSDATA
ID 0x0099
Type char[11]

Chapter 3. Express C/C++ APIs 705


Description
Whether the spooled file contains double-byte character set (DBCS) data.
Valid values are *NO and *YES.

DBCS Extension Characters


Key CWBOBJ_KEY_DBCSEXTENSN
ID 0x009A
Type char[11]
Description
Whether the system is to process the DBCS extension characters. Valid
values are *NO and *YES.

DBCS Character Rotation


Key CWBOBJ_KEY_DBCAROTATE
ID 0x009B
Type char[11]
Description
Whether the DBCS characters are rotated 90 degrees counterclockwise
before printing. Valid values are *NO and *YES.

DBCS Characters per Inch


Key CWBOBJ_KEY_DBCSCPI
ID 0x009C
Type long
Description
The number of double-byte characters to be printed per inch. Valid values
are -1, -2, 5, 6, and 10. The value *CPI is encoded as -1. The value
*CONDENSED is encoded as -2.

DBCS SO/SI Spacing


Key CWBOBJ_KEY_DBCSSISO
ID 0x009D
Type char[11]
Description
Determines the presentation of shift-out and shift-in characters when
printed. Valid values are *NO, *YES, and *RIGHT.

Defer Write
Key CWBOBJ_KEY_DFR_WRITE
ID 0x0023
Type char[11]
Description
Whether print data is held in system buffers before

Degree of Page Rotation


Key CWBOBJ_KEY_PAGRTT

706 Client Access Express Programming


ID 0x0024
Type long
Description
The degree of rotation of the text on the page, with respect to the way the
form is loaded into the printer. Valid values are -1, -2, -3, 0, 90, 180, 270.
The value *AUTO is encoded as -1, the value *DEVD is encoded as -2, and
the value *COR is encoded as -3.

Delete File After Sending


Key CWBOBJ_KEY_DELETESPLF
ID 0x0097
Type char[11]
Description
Delete the spooled file after sending? Valid values are *NO and *YES.

Destination Option
Key CWBOBJ_KEY_DESTOPTION
ID 0x0098
Type char[129]
Description
Destination option. A text string that allows the user to pass options to the
receiving system.

Destination Type
Key CWBOBJ_KEY_DESTINATION
ID 0x0025
Type char[11]
Description
Destination type. Valid values are *OTHER, *AS400, *PSF2.

Device Class
Key CWBOBJ_KEY_DEVCLASS
ID 0x0026
Type char[11]
Description
The device class.

Device Model
Key CWBOBJ_KEY_DEVMODEL
ID 0x0027
Type char[11]
Description
The model number of the device.

Device Type
Key CWBOBJ_KEY_DEVTYPE

Chapter 3. Express C/C++ APIs 707


ID 0x0028
Type char[11]
Description
The device type.

Display any File


Key CWBOBJ_KEY_DISPLAYANY
ID 0x0029
Type char[11]
Description
Whether users who have authority to read this output queue can display
the output data of any output file on this queue, or only the data in their
own files. Valid values are *YES, *NO, *OWNER.

Drawer for Separators


Key CWBOBJ_KEY_DRWRSEP
ID 0x002A
Type long
Description
Identifies the drawer from which the job and file separator pages are to be
taken. Valid values are -1, -2, 1, 2, 3. The value *FILE is encoded as -1, and
the value *DEVD is encoded as -2.

Ending Page
Key CWBOBJ_KEY_ENDPAGE
ID 0x002B
Type long
Description
The page number at which to end printing the spooled file. Valid values
are 0 or the ending page number. The value *END is encoded as 0.

File Separators
Key CWBOBJ_KEY_FILESEP
ID 0x002C
Type long
Description
The number of file separator pages that are placed at the beginning of each
copy of the spooled file. Valid values are -1, or the number of separators.
The value *FILE is encoded as -1.

Fold Records
Key CWBOBJ_KEY_FOLDREC
ID 0x002D
Type char[11]

708 Client Access Express Programming


Description
Whether records that exceed the printer forms width are folded (wrapped)
to the next line. Valid values are *YES, *NO.

Font Identifier
Key CWBOBJ_KEY_FONTID
ID 0x002E
Type char[11]
Description
The printer font that is used. Valid special values include *CPI and *DEVD.

Form Feed
Key CWBOBJ_KEY_FORMFEED
ID 0x002F
Type char[11]
Description
The manner in which forms feed to the printer. Valid values are *CONT,
*CUT, *AUTOCUT, *DEVD.

Form Type
Key CWBOBJ_KEY_FORMTYPE
ID 0x0030
Type char[11]
Description
The type of form to be loaded in the printer to print this spooled file.

Form Type Message Option


Key CWBOBJ_KEY_FORMTYPEMSG
ID 0x0043
Type char[11]
Description
Message option for sending a message to the writer’s message queue when
the current form type is finished. Valid values are *MSG, *NOMSG,
*INFOMSG, *INQMSG.

Front Margin Offset Across


Key CWBOBJ_KEY_FTMGN_ACR
ID 0x0031
Type float
Description
For the front side of a piece of paper, it specifies, how far in from the left
side of the page printing starts. The special value *DEVD is encoded as -2.

Front Margin Offset Down


Key CWBOBJ_KEY_FTMGN_DWN
ID 0x0032

Chapter 3. Express C/C++ APIs 709


Type float
Description
For the front side of a piece of paper, it specifies, how far down from the
top of the page printing starts. The special value *DEVD is encoded as -2.

Front Overlay Library Name


Key CWBOBJ_KEY_FTOVRLLIB
ID 0x0033
Type char[11]
Description
The name of the library that contains the front overlay. This field may be
blank if the front overlay name field contains a special value.

Front Overlay Name


Key CWBOBJ_KEY_FTOVRLAY
ID 0x0034
Type char[11]
Description
The name of the front overlay. Valid special values include *NONE.

Front Overlay Offset Across


Key CWBOBJ_KEY_FTOVL_ACR
ID 0x0036
Type float
Description
The offset across from the point of origin where the overlay is printed.

Front Overlay Offset Down


Key CWBOBJ_KEY_FTOVL_DWN
ID 0x0035
Type float
Description
The offset down from the point of origin where the overlay is printed.

Graphic Character Set


Key CWBOBJ_KEY_CHAR_ID
ID 0x0037
Type char[11]
Description
The set of graphic characters to be used when printing this file. Valid
special values include *DEVD, *SYSVAL, and *JOBCCSID.

Hardware Justification
Key CWBOBJ_KEY_JUSTIFY
ID 0x0038

710 Client Access Express Programming


Type long
Description
The percentage that the output is right justified. Valid values are 0, 50, 100.

Hold Spool File


Key CWBOBJ_KEY_HOLD
ID 0x0039
Type char[11]
Description
Whether the spooled file is held. Valid values are *YES, *NO.

Initialize the writer


Key CWBOBJ_KEY_WTRINIT
ID 0x00AC
Type char[11]
Description
The user can specify when to initialize the printer device. Valid values are
*WTR, *FIRST, *ALL.

Internet Address
Key CWBOBJ_KEY_INTERNETADDR
ID 0x0094
Type char[16]
Description
The internet address of the receiving system.

Job Name
Key CWBOBJ_KEY_JOBNAME
ID 0x003B
Type char[11]
Description
The name of the job that created the spooled file.

Job Number
Key CWBOBJ_KEY_JOBNUMBER
ID 0x003C
Type char[7]
Description
The number of the job that created the spooled file.

Job Separators
Key CWBOBJ_KEY_JOBSEPRATR
ID 0x003D
Type long

Chapter 3. Express C/C++ APIs 711


Description
The number of job separators to be placed at the beginning of the output
for each job having spooled files on this output queue. Valid values are -2,
0-9. The value *MSG is encoded as -2. Job separators are specified when
the output queue is created.

Job User
Key CWBOBJ_KEY_USER
ID 0x003E
Type char[11]
Description
The name of the user that created the spooled file.

Last Page Printed


Key CWBOBJ_KEY_LASTPAGE
ID 0x003F
Type long
Description
The number of the last printed page is the file if printing ended before the
job completed processing.

Length of Page
Key CWBOBJ_KEY_PAGELEN
ID 0x004E
Type float
Description
The length of a page. Units of measurement are specified in the
measurement method attribute.

Library Name
Key CWBOBJ_KEY_LIBRARY
ID 0x000F
Type char[11]
Description
The name of the library.

Lines Per Inch


Key CWBOBJ_KEY_LPI
ID 0x0040
Type float
Description
The number of lines per vertical inch in the spooled file.

Manufacturer Type and Model


Key CWBOBJ_KEY_MFGTYPE
ID 0x0041

712 Client Access Express Programming


Type char[21]
Description
Specifies the manufacturer, type, and model when transforming print data
from SCS to ASCII.

Maximum Spooled Output Records


Key CWBOBJ_KEY_MAXRECORDS
ID 0x0042
Type long
Description
The maximum number of records allowed in this file at the time this file
was opened. The value *NOMAX is encoded as 0.

Measurement Method
Key CWBOBJ_KEY_MEASMETHOD
ID 0x004F
Type char[11]
Description
The measurement method that is used for the length of page and width of
page attributes. Valid values are *ROWCOL, *UOM.

Message Help
Key CWBOBJ_KEY_MSGHELP
ID 0x0081
Type char(*)
Description
The message help, which is sometimes known as second-level text, can be
returned by a ″retrieve message″ request. The system limits the length to
3000 characters (English version must be 30 % less to allow for translation).

Message ID
Key CWBOBJ_KEY_MESSAGEID
ID 0x0093
Type char[8]
Description
The message ID.

Message Queue Library Name


Key CWBOBJ_KEY_MSGQUELIB
ID 0x0044
Type char[11]
Description
The name of the library that contains the message queue.

Message Queue
Key CWBOBJ_KEY_MSGQUE

Chapter 3. Express C/C++ APIs 713


ID 0x005E
Type char[11]
Description
The name of the message queue that the writer uses for operational
messages.

Message Reply
Key CWBOBJ_KEY_MSGREPLY
ID 0x0082
Type char[133]
Description
The message reply. Text string to be provided by the client which answers
a message of type ″inquiry″. In the case of message retrieved, the attribute
value is returned by the server and contains the default reply which the
client can use. The system limits the length to 132 characters. Should be
null-terminated due to variable length.

Message Text
Key CWBOBJ_KEY_MSGTEXT
ID 0x0080
Type char[133]
Description
The message text, that is sometimes known as first-level text, can be
returned by a ″retrieve message″ request. The system limits the length to
132 characters.

Message Type
Key CWBOBJ_KEY_MSGTYPE
ID 0x008E
Type char[3]
Description
The message type, a 2-digit, EBCDIC encoding. Two types of messages
indicate whether one can ″answer″ a ″retrieved″ message: ’04’
Informational messages convey information without asking for a reply
(may require a corrective action instead), ’05’ Inquiry messages convey
information and ask for a reply.

Message Severity
Key CWBOBJ_KEY_MSGSEV
ID 0x009F
Type long
Description
Message severity. Values range from 00 to 99. The higher the value, the
more severe or important the condition.

Number of Bytes to Read/Write


Key CWBOBJ_KEY_NUMBYTES

714 Client Access Express Programming


ID 0x007D
Type long
Description
The number of bytes to read for a read operation, or the number of bytes
to write for a write operation. The object action determines how to
interpret this attribute.

Number of Files
Key CWBOBJ_KEY_NUMFILES
ID 0x0045
Type long
Description
The number of spooled files that exist on the output queue.

Number of Writers Started to Queue


Key CWBOBJ_KEY_NUMWRITERS
ID 0x0091
Type long
Description
The number of writer jobs started to the output queue.

Object Extended Attribute


Key CWBOBJ_KEY_OBJEXTATTR
ID 0x000B1
Type char[11]
Description
An ″extended″ attribute used by some objects like font resources. This
value shows up via WRKOBJ and DSPOBJD commands on the AS/400.
The title on an AS/400 screen may just indicate ″Attribute″. In the case of
object types of font resources, for example, common values are CDEPAG,
CDEFNT, and FNTCHRSET.

Open time commands


Key CWBOBJ_KEY_OPENCMDS
ID 0x00A0
Type char[11]
Description
Specifies whether the user wants SCS open time commands to be inserted
into datastream prior to spool file data. Valid values are *YES, *NO.

Operator Controlled
Key CWBOBJ_KEY_OPCNTRL
ID 0x0046
Type char[11]

Chapter 3. Express C/C++ APIs 715


Description
Whether users with job control authority are allowed to manage or control
the spooled files on this queue. Valid values are *YES, *NO.

Order of Files On Queue


Key CWBOBJ_KEY_ORDER
ID 0x0047
Type char[11]
Description
The order of spooled files on this output queue. Valid values are *FIFO,
*JOBNBR.

Output Priority
Key CWBOBJ_KEY_OUTPTY
ID 0x0048
Type char[11]
Description
The priority of the spooled file. The priority ranges from 1 (highest) to 9
(lowest). Valid values are 0-9, where 0 represents *JOB.

Output Queue Library Name


Key CWBOBJ_KEY_OUTQUELIB
ID 0x0049
Type char[11]
Description
The name of the library that contains the output queue.

Output Queue Name


Key CWBOBJ_KEY_OUTQUE
ID 0x004A
Type char[11]
Description
The name of the output queue.

Output Queue Status


Key CWBOBJ_KEY_OUTQUESTS
ID 0x004B
Type char[11]
Description
The status of the output queue. Valid values are RELEASED, HELD.

Overflow Line Number


Key CWBOBJ_KEY_OVERFLOW
ID 0x004C
Type long

716 Client Access Express Programming


Description
The last line to be printed before the data that is being printed overflows
to the next page.

Pages Per Side


Key CWBOBJ_KEY_MULTIUP
ID 0x0052
Type long
Description
The number of logical pages that print on each side of each physical page
when the file is printed. Valid values are 1, 2, 4.

Pel Density
Key CWBOBJ_KEY_PELDENSITY
ID 0x00B2
Type char[2]
Description
For font resources only, this value is an encoding of the number of pels
(″1″ represents a pel size of 240, ″2″ represents a pel size of 320).
Additional values may become meaningful as the AS/400 system defines
them.

Point Size
Key CWBOBJ_KEY_POINTSIZE
ID 0x0053
Type float
Description
The point size in which this spooled file’s text is printed. The special value
*NONE will be encoded as 0.

Print Fidelity
Key CWBOBJ_KEY_FIDELITY
ID 0x0054
Type char[11]
Description
The kind of error handling that is performed when printing. Valid values
are *ABSOLUTE, *CONTENT.

Print on Both Sides


Key CWBOBJ_KEY_DUPLEX
ID 0x0055
Type char[11]
Description
How the information prints. Valid values are *FORMDF, *NO, *YES,
*TUMBLE.

Chapter 3. Express C/C++ APIs 717


Print Quality
Key CWBOBJ_KEY_PRTQUALITY
ID 0x0056
Type char[11]
Description
The print quality that is used when printing this spooled file. Valid values
are *STD, *DRAFT, *NLQ, *FASTDRAFT.

Print Sequence
Key CWBOBJ_KEY_PRTSEQUENCE
ID 0x0057
Type char[11]
Description
Print sequence. Valid values are *NEXT.

Print Text
Key CWBOBJ_KEY_PRTTEXT
ID 0x0058
Type char[31]
Description
The text that is printed at the bottom of each page of printed output and
on separator pages. Valid special values include *BLANK and *JOB.

Printer
Key CWBOBJ_KEY_PRINTER
ID 0x0059
Type char[11]
Description
The name of the printer device.

Printer Device Type


Key CWBOBJ_KEY_PRTDEVTYPE
ID 0x005A
Type char[11]
Description
The printer data stream type. Valid values are *SCS, *IPDS(*), *USERASCII,
*AFPDS.

Printer File Library Name


Key CWBOBJ_KEY_PRTRFILELIB
ID 0x005B
Type char[11]
Description
The name of the library that contains the printer file.

718 Client Access Express Programming


Printer File Name
Key CWBOBJ_KEY_PRTRFILE
ID 0x005C
Type char[11]
Description
The name of the printer file.

Printer Queue
Key CWBOBJ_KEY_RMTPRTQ
ID 0x005D
Type char[129]
Description
The name of the destination printer queue when sending spooled files via
SNDTCPSPLF (LPR).

Record Length
Key CWBOBJ_KEY_RECLENGTH
ID 0x005F
Type long
Description
Record length.

Remote System
Key CWBOBJ_KEY_RMTSYSTEM
ID 0x0060
Type char[256]
Description
Remote system name. Valid special values include *INTNETADR.

Replace Unprintable Characters


Key CWBOBJ_KEY_RPLUNPRT
ID 0x0061
Type char[11]
Description
Whether characters that cannot be printed are to be replaced with another
character. Valid values are *YES or *NO.

Replacement Character
Key CWBOBJ_KEY_RPLCHAR
ID 0x0062
Type char[2]
Description
The character that replaces any unprintable characters.

Chapter 3. Express C/C++ APIs 719


Resource library name
Key CWBOBJ_KEY_RSCLIB
ID 0x00AE
Type char[11]
Description
The name of the library that contains the external AFP (Advanced Function
Print) resource.

Resource name
Key CWBOBJ_KEY_RSCNAME
ID 0x00AF
Type char[11]
Description
The name of the external AFP resource.

Resource object type


Key CWBOBJ_KEY_RSCTYPE
ID 0x00B0
Type Long
Description
A numerical, bit encoding of external AFP resource object type. Values are
0x0001, 0x0002, 0x0004, 0x0008, 0x0010 corresponding to *FNTRSC,
*FORMDF, *OVL, *PAGSEG, *PAGDFN, respectively.

Restart Printing
Key CWBOBJ_KEY_RESTART
ID 0x0063
Type long
Description
Restart printing. Valid values are -1, -2, -3, or the page number to restart at.
The value *STRPAGE is encoded as -1, the value *ENDPAGE is encoded as
-2, and the value *NEXT is encoded as -3.

Save Spooled File


Key CWBOBJ_KEY_SAVESPLF
ID 0x0064
Type char[11]
Description
Whether the spooled file is to be saved after it is written. Valid values are
*YES, *NO.

Seek Offset
Key CWBOBJ_KEY_SEEKOFF
ID 0x007E
Type long

720 Client Access Express Programming


Description
Seek offset. Allows both positive and negative values relative to the seek
origin.

Seek Origin
Key CWBOBJ_KEY_SEEKORG
ID 0x007F
Type long
Description
Valid values include 1 (beginning or top), 2 (current), and 3 (end or
bottom).

Send Priority
Key CWBOBJ_KEY_SENDPTY
ID 0x0065
Type char[11]
Description
Send priority. Valid values are *NORMAL, *HIGH.

Separator page
Key CWBOBJ_KEY_SEPPAGE
ID 0x00A1
Type char[11]
Description
Allows a user the option of printing a banner page. Valid values are *YES
or *NO.

Source Drawer
Key CWBOBJ_KEY_SRCDRWR
ID 0x0066
Type long
Description
The drawer to be used when the automatic cut sheet feed option is
selected. Valid values are -1, -2, 1-255. The value *E1 is encode as -1, and
the value *FORMDF is encoded as -2.

Spool SCS
Key CWBOBJ_KEY_SPLSCS
ID 0x00AD
Type Long
Description
Determines how SCS data is used during create spool file. Valid values are
-1, 0, 1, or the page number. The value *ENDPAGE is encoded as -1. For
the value 0, printing starts on page 1. For the value 1, the entire file prints.

Spool the Data


Key CWBOBJ_KEY_SPOOL

Chapter 3. Express C/C++ APIs 721


ID 0x0067
Type char[11]
Description
Whether the output data for the printer device is spooled. Valid values are
*YES, *NO.

Spooled File Name


Key CWBOBJ_KEY_SPOOLFILE
ID 0x0068
Type char[11]
Description
The name of the spooled file.

Spooled File Number


Key CWBOBJ_KEY_SPLFNUM
ID 0x0069
Type long
Description
The spooled file number.

Spooled File Status


Key CWBOBJ_KEY_SPLFSTATUS
ID 0x006A
Type char[11]
Description
The status of the spooled file. Valid values are *CLOSED, *HELD,
*MESSAGE, *OPEN, *PENDING, *PRINTER, *READY, *SAVED,
*WRITING.

Spooled Output Schedule


Key CWBOBJ_KEY_SCHEDULE
ID 0x006B
Type char[11]
Description
Specifies, for spooled files only, when the spooled file is available to the
writer. Valid values are *IMMED, *FILEEND, *JOBEND.

Starting Page
Key CWBOBJ_KEY_STARTPAGE
ID 0x006C
Type long
Description
The page number at which to start printing the spooled file. Valid values
are -1, 0, 1, or the page number. The value *ENDPAGE is encoded as -1.
For the value 0, printing starts on page 1. For the value 1, the entire file
prints.

722 Client Access Express Programming


Text Description
Key CWBOBJ_KEY_DESCRIPTION
ID 0x006D
Type [51]
Description
Text to describe an instance of an AS/400 object.

Time File Opened


Key CWBOBJ_KEY_TIMEOPEN
ID 0x006E
Type char[7]
Description
The time this spooled file was opened. The time is encoded in a character
0x0005 with the following format, HH MM SS.

Total Pages
Key CWBOBJ_KEY_PAGES
ID 0x006F
Type long
Description
The number of pages that are contained in a spooled file.

Transform SCS to ASCII


Key CWBOBJ_KEY_SCS2ASCII
ID 0x0071
Type char[11]
Description
Whether the print data is to be transformed from SCS to ASCII. Valid
values are *YES, *NO.

Unit of Measure
Key CWBOBJ_KEY_UNITOFMEAS
ID 0x0072
Type char[11]
Description
The unit of measure to use for specifying distances. Valid values are *CM,
*INCH.

User Comment
Key CWBOBJ_KEY_USERCMT
ID 0x0073
Type char[101]
Description
The 100 characters of user-specified comment that describe the spooled file.

Chapter 3. Express C/C++ APIs 723


User Data
Key CWBOBJ_KEY_USERDATA
ID 0x0074
Type char[11]
Description
The 10 characters of user-specified data that describe the spooled file. Valid
special values include *SOURCE.

User defined data


Key CWBOBJ_KEY_USRDFNDTA
ID 0x00A2
Type char[]
Description
User defined data to be utilized by user applications or user specified
programs that process spool files. All characters are acceptable. Max size is
255.

User defined object library


Key CWBOBJ_KEY_USRDFNOBJLIB
ID 0x00A4
Type char[11]
Description
User defined object library to search by user applications that process
spool files.

User defined object name


Key CWBOBJ_KEY_USRDFNOBJ
ID 0x00A5
Type char[11]
Description
User defined object name to be utilized by user applications that process
spool files.

User defined object type


Key CWBOBJ_KEY_USRDFNOBJTYP
ID 0x00A6
Type char[11]
Description
User defined object type pertaining to the user defined object.

User defined option(s)


Key CWBOBJ_KEY_USEDFNOPTS
ID 0x00A3
Type char[*]

724 Client Access Express Programming


Description
User defined options to be utilized by user applications that process spool
files. Up to 4 options may be specifies, each value is length char(10). All
characters are acceptable.

User driver program


Key CWBOBJ_KEY_USRDRVPGMDTA
ID 0x00A9
Type char[11]
Description
User data to be used with the user driver program. All characters are
acceptable. Maximum size is 5000 characters.

User driver program library


Key CWBOBJ_KEY_USRDRVPGMLIB
ID 0x00AA
Type char[11]
Description
User defined library to search for driver program that processes spool files.

User driver program name


Key CWBOBJ_KEY_USRDRVPGM
ID 0x00AB
Type char[11]
Description
User defined program name that processes spool files.

User ID
Key CWBOBJ_KEY_TOUSERID
ID 0x0075
Type char[9]
Description
User ID to which the spooled file is sent.

User ID Address
Key CWBOBJ_KEY_TOADDRESS
ID 0x0076
Type char[9]
Description
Address of user to whom the spooled file is sent.

User transform program library


Key CWBOBJ_KEY_USRTFMPGMLIB
ID 0x00A7
Type char[11]

Chapter 3. Express C/C++ APIs 725


Description
User defined library search for transform program.

User transform program name


Key CWBOBJ_KEY_USETFMPGM
ID 0x00A8
Type char[11]
Description
User defined transform program name that transforms spool file data
before it is processed by the driver program.

VM/MVS Class
Key CWBOBJ_KEY_VMMVSCLASS
ID 0x0077
Type char[2]
Description
VM/MVS class. Valid values are A-Z and 0-9.

When to Automatically End Writer


Key CWBOBJ_KEY_WTRAUTOEND
ID 0x0078
Type char[11]
Description
When to end the writer if it is to be ended automatically. Valid values are
*NORDYF, *FILEEND. Attribute Automatically end writer must be set to
*YES.

When to End Writer


Key CWBOBJ_KEY_WTREND
ID 0x0090
Type char[11]
Description
When to end the writer. Valid value are *CNTRLD, *IMMED, and
*PAGEEND. This is different from when to automatically end the writer.

When to Hold File


Key CWBOBJ_KEY_HOLDTYPE
ID 0x009E
Type char[11]
Description
When to hold the spooled file. Valid values are *IMMED, and *PAGEEND.

Width of Page
Key CWBOBJ_KEY_PAGEWIDTH
ID 0x0051
Type float

726 Client Access Express Programming


Description
The width of a page. Units of measurement are specified in the
measurement method attribute.

Workstation Customizing Object Name


Key CWBOBJ_KEY_WSCUSTMOBJ
ID 0x0095
Type char[11]
Description
The name of the workstation customizing object.

Workstation Customizing Object Library


Key CWBOBJ_KEY_WSCUSTMOBJL
ID 0x0096
Type char[11]
Description
the name of the library that contains the workstation customizing object.

Writer Job Name


Key CWBOBJ_KEY_WRITER
ID 0x0079
Type char[11]
Description
The name of the writer job.

Writer Job Number


Key CWBOBJ_KEY_WTRJOBNUM
ID 0x007A
Type char[7]
Description
The writer job number.

Writer Job Status


Key CWBOBJ_KEY_WTRJOBSTS
ID 0x007B
Type char[11]
Description
The status of the writer job. Valid values are STR, END, JOBQ, HLD,
MSGW.

Writer Job User Name


Key CWBOBJ_KEY_WTRJOBUSER
ID 0x007C
Type char[11]

Chapter 3. Express C/C++ APIs 727


Description
The name of the user that started the writer job.

Writer Starting Page


Key CWBOBJ_KEY_WTRSTRPAGE
ID 0x008F
Type long
Description
Specifies the page number of the first page to print from the first spooled
file when the writer job starts. This is only valid if the spooled file name is
also specified when the writer starts.

Network Print Server Object Attributes


v “NPS Attribute Default Value”
v “NPS Attribute High Limit”
v “NPS Attribute ID”
v “NPS Attribute Low Limit” on page 729
v “NPS Attribute Possible Value” on page 729
v “NPS Attribute Text Description” on page 729
v “NPS Attribute Type” on page 729
v “NPS CCSID” on page 729
v “NPS Object” on page 729
v “NPS Object Action” on page 730
v “NPS Level” on page 730

NPS Attribute Default Value:


Key CWBOBJ_KEY_ATTRDEFAULT
ID 0x0083
Type dynamic
Description
Default value for the attribute.

NPS Attribute High Limit:


Key CWBOBJ_KEY_ATTRMAX
ID 0x0084
Type dynamic
Description
High limit of the attribute value.

NPS Attribute ID:


Key CWBOBJ_KEY_ATTRID
ID 0x0085
Type long
Description
ID of the attribute.

728 Client Access Express Programming


NPS Attribute Low Limit:
Key CWBOBJ_KEY_ATTRMIN
ID 0x0086
Type dynamic
Description
Low limit of the attribute value.

NPS Attribute Possible Value:


Key CWBOBJ_KEY_ATTRPOSSIBL
ID 0x0087
Type dynamic
Description
Possible value for the attribute. More than one NPS possible value instance
may be present in a code point.

NPS Attribute Text Description:


Key CWBOBJ_KEY_ATTRDESCRIPT
ID 0x0088
Type char(*)
Description
Text description that provides a name for the attribute.

NPS Attribute Type:


Key CWBOBJ_KEY_ATTRTYPE
ID 0x0089
Type long
Description
The type of the attribute. Valid values are the types that are defined by the
Network Print Server.

NPS CCSID:
Key CWBOBJ_KEY_NPSCCSID
ID 0x008A
Type long
Description
CCSID that the Network Print Server expects that all strings will be
encoded in.

NPS Object:
Key CWBOBJ_KEY_NPSOBJECT
ID 0x008B
Type long

Chapter 3. Express C/C++ APIs 729


Description
Object ID. Valid values are the objects that are defined by the Network
Print Server.

NPS Object Action:


Key CWBOBJ_KEY_NPSACTION
ID 0x008C
Type long
Description
Action ID. Valid values are the actions that are defined by the Network
Print Server.

NPS Level:
Key CWBOBJ_KEY_NPSLEVEL
ID 0x008D
Type char[7]
Description
The version, release, and modification level of the Network Print Server.
This attribute is a character string encoded as VXRYMY (ie. ″V3R1M0″)
where

X is in (0..9)
Y is in (0..9,A..Z)

Express AS/400 Objects API listing


Note: When working with handles in the following APIs, 0 never will be returned
as a valid handle.

Function/type Express AS/400 Objects APIs


List APIs cwbOBJ_CloseList
cwbOBJ_CreateListHandle
cwbOBJ_DeleteListHandle
cwbOBJ_GetListSize
cwbOBJ_OpenList
cwbOBJ_ResetListAttrsToRetrieve
cwbOBJ_ResetListFilter
cwbOBJ_SetListAttrsToRetrieve
cwbOBJ_SetListFilter
cwbOBJ_SetListFilterWithSplF
Object APIs cwbOBJ_CopyObjHandle
cwbOBJ_DeleteObjHandle
cwbOBJ_GetObjAttr
cwbOBJ_GetObjAttrs
cwbOBJ_GetObjHandleFromIDcwbOBJ_GetObjID
cwbOBJ_RefreshObj
cwbOBJ_SetObjAttrs
Parameter object APIs cwbOBJ_CopyParmObjHandle
cwbOBJ_CreateParmObjHandle
cwbOBJ_DeleteParmObjHandle
cwbOBJ_GetParameter
cwbOBJ_SetParameter

730 Client Access Express Programming


Function/type Express AS/400 Objects APIs
Writer job APIs cwbOBJ_EndWriter
cwbOBJ_StartWriter
Output queue APIs cwbOBJ_HoldOutputQueue
cwbOBJ_PurgeOutputQueue
cwbOBJ_ReleaseOutputQueue
AFP resource APIs cwbOBJ_CloseResource
cwbOBJ_CreateResourceHandle
cwbOBJ_DisplayResource
cwbOBJ_OpenResource
cwbOBJ_OpenResourceForSplF
cwbOBJ_ReadResource
cwbOBJ_SeekResource
Spooled file APIs for working cwbOBJ_CloseNewSplF
with new spooled files cwbOBJ_CloseNewSplFAndGetHandle
cwbOBJ_CreateNewSplF
cwbOBJ_GetSplFHandleFromNewSplF
cwbOBJ_WriteNewSplF
Spooled file APIs for reading cwbOBJ_CloseSplF
spooled files cwbOBJ_OpenSplF
cwbOBJ_ReadSplF
cwbOBJ_SeekSplF
Spooled file APIs for cwbOBJ_CallExitPgmForSplF
manipulating AS/400 spooled cwbOBJ_CreateSplFHandle
files cwbOBJ_DeleteSplF
cwbOBJ_DisplaySplF
cwbOBJ_HoldSplF
cwbOBJ_IsViewerAvailable
cwbOBJ_MoveSplF
cwbOBJ_ReleaseSplF
cwbOBJ_SendNetSplF
cwbOBJ_SendTCPSplF
Spooled file APIs for handling cwbOBJ_AnswerSplFMsg
spooled file messages cwbOBJ_GetSplFMsgAttr
Spooled file API for analyzing
data cwbOBJ_AnalyzeSplFData
Server program APIs cwbOBJ_DropConnections
cwbOBJ_GetNPServerAttr
cwbOBJ_SetConnectionsToKeep

Chapter 3. Express C/C++ APIs 731


cwbOBJ_AnalyzeSplFData
Purpose: Analyze data for a spooled file and give a best guess as to what the data
type is.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_AnalyzeSplFData(


const char *data,
unsigned long bufLen,
cwbOBJ_SplFDataType *dataType,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *data - input
pointer to data to be analyzed.
unsigned long bufLen - input
The length of the buffer pointed to by data.
cwbOBJ_SplFDataType *dataType - output
On output this will contain the data type. If the data type can not be
determined, it defaults to CWBOBJ_DT_USERASCII.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_PARAMETER
Invalid parameter specified.

Usage: This uses the same routine that is used during the creation of spooled files
that don’t have a data type specified or have a data type of *AUTO specified. The
result defaults to *USERASCII if it can not be determined.

732 Client Access Express Programming


cwbOBJ_AnswerSplFMsg
Purpose: Answer the message that the spooled file is waiting on.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_AnswerSplFMsg(


cwbOBJ_ObjHandle splFHandle,
char *msgAnswer,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to answer the message for.
const char *msgAnswer - input
Pointer to a ASCIIZ string that contains the answer for the message.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.
CWBOBJ_RC_SPLFNOMESSAGE
The spooled file isn’t waiting on a message.

Usage: None

Chapter 3. Express C/C++ APIs 733


cwbOBJ_CallExitPgmForSplF
Purpose: Instructs the Client Access/400 Netprint server program, QNPSERVR, to
call down its exit program chain passing this spooled file’s ID and some
application specified data as parameters.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CallExitPgmForSplF(


cwbOBJ_ObjHandle splFHandle,
void *data,
unsigned long dataLen,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be passes as a parameter to the exit programs.
void *data - input
Pointer to a block of date that will be passed to the exit programs. The format
of this data is exit program specific.
unsigned long dataLen - input
length of data pointed to by pData.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.
CWBOBJ_RC_NO_EXIT_PGM
No exit program is registered with the Network Print server.

Usage: This is a way for a client program to communicate with its server portion
to do processing of spooled files. All exit programs registered with the QNPSERVR
program on the AS/400 will be called, so it is up to the client program and exit
program to architect the format of the data in *data such that the exit program can
recognize it. See the AS/400 ’Guide to Programming for Print’ for information on
the interface between the QNPSERVR server program and the exit programs.

734 Client Access Express Programming


cwbOBJ_CloseNewSplF
Purpose: Closes a newly created spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CloseNewSplF(


cwbOBJ_ObjHandle newSplFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle newSplFHandle - input
New spooled file handle. This is the handle passed back on the
cwbOBJ_CreateNewSplF() API.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: Once a spooled file is closed, you can no longer write to it.

Chapter 3. Express C/C++ APIs 735


cwbOBJ_CloseNewSplFAndGetHandle
Purpose: Closes a newly created spooled file and returns a handle to it.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CloseNewSplFAndGetHandle(


cwbOBJ_ObjHandle newSplFHandle,
cwbOBJ_ObjHandle *splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle newSplFHandle - input
New spooled file handle. This is the handle passed back on the
cwbOBJ_CreateNewSplF() API.
cwbOBJ_ObjHandle *splFHandle - output
Pointer to an object handle that, upon successful, completion of this call, will
hold the spooled file handle. This handle may be used with other APIs that
take a spooled file handle as input.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The handle returned in splFHandle must be released with the


cwbOBJ_DeleteObjHandle() API in order to free resources.

736 Client Access Express Programming


cwbOBJ_CloseList
Purpose: Closes an opened list.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CloseList(


cwbOBJ_ListHandle listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
Handle of the list to be closed. This list must be opened.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated list handle.
CWBOBJ_RC_LIST_NOT_OPEN
The list isn’t open.

Usage: Closing the list frees the memory used by the list to hold its items. Any
object handles gotten with cwbOBJ_GetObjHandle() API should be released before
closing the list to free resources. These handles are no longer valid.

Chapter 3. Express C/C++ APIs 737


cwbOBJ_CloseResource
Purpose: Closes an AFP Resource object that was previously opened for for
reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CloseResource(


cwbOBJ_ObjHandle resourceHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle resourceHandle - input
Handle of the resource to be closed.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid resource handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_RSCNOTOPEN
Resource not opened.
CWBOBJ_RC_SPLFNOTOPEN
Spooled file not open.

Usage: If the handle for the resource was obtained via a call to the
cwbOBJ_OpenResourceForSplF() API, then this api will delete the handle for you
(the handle was dynamically allocated for you when you opened the resource and
this call deallocates it).

738 Client Access Express Programming


cwbOBJ_CloseSplF
Purpose: Closes an AS/400 spooled file that was previously opened for for
reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CloseSplF(


cwbOBJ_ObjHandle splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be closed.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: None

Chapter 3. Express C/C++ APIs 739


cwbOBJ_CopyObjHandle
Purpose: Creates a duplicate handle to an object. Use this API to get another
handle to the same AS/400 object. This new handle will be valid until the
cwbOBJ_DeleteObjHandle() API has been called to release it.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CopyObjHandle(


cwbOBJ_ObjHandle objectHandle,
cwbOBJ_ObjHandle *newObjectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to copy.
cwbOBJ_ObjHandle *newObjectHandle - output
Upon successful competition of this call, this handle will contain the new
object handle.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.

Usage: If you have a handle to an object in a list and wish to maintain a handle
to that object after the list has been close this API allows you to do that.
cwbOBJ_DeleteObjHandle() must be called to release resources for this handle.

740 Client Access Express Programming


cwbOBJ_CopyParmObjHandle
Purpose: Creates a duplicate parameter list object. All attribute keys and values in
the parameter list object will be copied to the new parameter list object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CopyParmObjHandle(


cwbOBJ_ParmHandle parmListHandle,
cwbOBJ_ParmHandle *newParmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ParmHandle parmListHandle - input
Handle of the parameter list object to copy.
cwbOBJ_ParmHandle *newParmListHandle - output
Upon successful competition of this call, this handle will contain the new
parameter list object handle.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.

Usage: The cwbOBJ_DeleteParmObjectHandle API must be called to free


resources allocated by this call.

Chapter 3. Express C/C++ APIs 741


cwbOBJ_CreateListHandle
Purpose: Allocates a handle for a list of objects. After a list handle has been
allocated, the filter criteria may be set for the list with the cwbOBJ_SetListFilter()
API, the list may be built with the cwbOBJ_OpenList() API, etc.
cwbOBJ_DeleteListHandle() should be called to deallocated this list handle and
free any resources used by it.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CreateListHandle(


const char *systemName,
cwbOBJ_ListType type,
cwbOBJ_ListHandle *listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in ASCIIZ string
cwbOBJ_ListType type - input
Type of list to allocate (eg. spooled file list, output queue list, etc).
cwbOBJ_ListHandle *listHandle - output
Pointer to a list handle that will be passed back on output. This handle is
needed for other calls using the list.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage that is being used.
CWB_API_ERROR
General API failure.

Usage: Caller must call cwbOBJ_DeleteListHandle when done using this list
handle. Typical calling sequence for retrieving a list of objects would be:
1. cwbOBJ_CreateListHandle()
2. cwbOBJ_SetListFilter() { repeated as needed }
3. cwbOBJ_OpenList()
4. cwbOBJ_GetListSize() to get the size of the list.
5. For n=0 to list size - 1 cwbOBJ_GetObjHandle for list item in position n do
something with the object cwbOBJ_DeleteObjHandle()
6. cwbOBJ_CloseList() - You may go back to step 2 here.
7. cwbOBJ_DeleteListHandle()

742 Client Access Express Programming


cwbOBJ_CreateNewSplF
Purpose: Creates a new spooled file on the AS\400.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CreateNewSplF(


const char *systemName,
cwbOBJ_ParmHandle *parmListHandle,
cwbOBJ_ObjHandle *printerFileHandle,
cwbOBJ_ObjHandle *outputQueueHandle,
cwbOBJ_ObjHandle *newSplFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in ASCIIZ string
cwbOBJ_ParmHandle *parmListHandle - input
Optional. A pointer to a valid parameter list object handle that contains
parameters for creating the spooled file. Parameters set in this list override
what is in the printer file and the *outputQueueHandle parameter.
cwbOBJ_ObjHandle *printerFileHandle - input
Optional. A pointer to a valid printer file object handle that references the
printer file to be used when creating this spooled file. The printer file must
exist on the same system that this spooled file is being created on.
cwbOBJ_ObjHandle *outputQueueHandle - input
Optional. A pointer to a valid output queue object handle that references the
output queue that this spooled file should be created on. The output queue
must exist on the same system that this spooled file is being created on. If the
output queue is set in the *parmListHandle parameter (with
CWBOBJ_KEY_OUTQUELIB & CWBOBJ_KEY_OUTQUE) it will override the
output queue specified by this output queue handle.
cwbOBJ_ObjHandle *newSplFHandle - output
A pointer to a object handle that will be filled in upon successful completion of
this call with the newly created spooled file handle. This handle is needed to
write data into and close the new spooled file.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid
CWB_INVALID_PARAMETER
Invalid parameter specified.

Chapter 3. Express C/C++ APIs 743


CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: If the parmListHandle is NULL, or doesn’t specify an attribute, the


attribute is taken from the printer file used. If the output queue is specified with
the *parmListHandle, this will override what is specified in the
*outputQueueHandle parameter. If the output queue is not specified (not in the
*parmListHandle AND outputQueueHandle is NULL), the output queue used is
taken from the printer file. If the printer file is not specified (printerFileHandle is
NULL), the server will use the default network print printer file,
*LIBL/QNPSPRTF. The following parameter keys may be set in the
pParmListHandl object:
CWBOBJ_KEY_ALIGN - Align page
CWBOBJ_KEY_BKOVRLLIB - Back overlay library name
CWBOBJ_KEY_BKOVRLAY - Back overlay
CWBOBJ_KEY_BKOVL_ACR - Back overlay offset across
CWBOBJ_KEY_BKOVL_DWN - Back overlay offset down
CWBOBJ_KEY_CPI - Characters Per Inch
(1)CWBOBJ_KEY_CODEPAGE - Code page
CWBOBJ_KEY_COPIES - Copies
CWBOBJ_KEY_DBCSDATA - Contains DBCS Data
CWBOBJ_KEY_DBCSEXTENSN - Process DBCS Extension
characters
CWBOBJ_KEY_DBCSROTATE - DBCS character rotation
CWBOBJ_KEY_DBCSCPI - DBCS CPI
CWBOBJ_KEY_DBCSSISO - DBCS SO/SI spacing
CWBOBJ_KEY_DFR_WRITE - Defer writing
CWBOBJ_KEY_ENDPAGE - Ending page
(2)CWBOBJ_KEY_FILESEP - File Separators
CWBOBJ_KEY_FOLDREC - Fold records
CWBOBJ_KEY_FONTID - Font identifier
CWBOBJ_KEY_FORMFEED - Form feed
CWBOBJ_KEY_FORMTYPE - Form type
CWBOBJ_KEY_FTOVRLLIB - Front overlay library name
CWBOBJ_KEY_FTOVRLAY - Front overlay
CWBOBJ_KEY_FTOVL_ACR - Front overlay offset across
CWBOBJ_KEY_FTOVL_DWN - Front overlay offset down
(1)CWBOBJ_KEY_CHAR_ID - Graphic character set ID
CWBOBJ_KEY_JUSTIFY - Hardware Justification
CWBOBJ_KEY_HOLD - Hold spooled file
CWBOBJ_KEY_LPI - Lines per inch
CWBOBJ_KEY_MAXRECORDS - Maximum spooled file records
CWBOBJ_KEY_OUTPTY - Output priority
CWBOBJ_KEY_OUTQUELIB - Output queue library name
CWBOBJ_KEY_OUTQUE - Output queue
CWBOBJ_KEY_OVERFLOW - Overflow line number
CWBOBJ_KEY_PAGELEN - Page length
CWBOBJ_KEY_MEASMETHOD - Measurement method
CWBOBJ_KEY_PAGEWIDTH - Page width
CWBOBJ_KEY_MULTIUP - Logical number of pages
per side
CWBOBJ_KEY_POINTSIZE - The default font's point size
CWBOBJ_KEY_FIDELITY - Print fidelity
CWBOBJ_KEY_DUPLEX - Print on both sides
CWBOBJ_KEY_PRTQUALITY - Print quality
CWBOBJ_KEY_PRTTEXT - Print text
CWBOBJ_KEY_PRINTER - Printer device name
CWBOBJ_KEY_PRTDEVTYPE - Printer device type
CWBOBJ_KEY_RPLUNPRT - Replace unprintable characters
CWBOBJ_KEY_RPLCHAR - Replacement character

744 Client Access Express Programming


CWBOBJ_KEY_SAVESPLF - Save spooled file after
printing
CWBOBJ_KEY_SRCDRWR - Source drawer
CWBOBJ_KEY_SPOOL - Spool the data
CWBOBJ_KEY_SPOOLFILE - Spool file name
CWBOBJ_KEY_SCHEDULE - When spooled file available
CWBOBJ_KEY_STARTPAGE - Starting page
CWBOBJ_KEY_UNITOFMEAS - Unit of measure
CWBOBJ_KEY_USERCMT - User comment (100 chars)
CWBOBJ_KEY_USERDATA - User data (10 chars)
CWBOBJ_KEY_SPLSCS - Spool SCS Data
CWBOBJ_KEY_USRDFNDTA - User defined data
(3)CWBOBJ_KEY_USRDFNOPTS - User defined options
CWBOBJ_KEY_USRDFNOBJLIB - User defined object library
CWBOBJ_KEY_USRDFNOBJ - User defined object
CWBOBJ_KEY_USRDFNOBJTYP - User defined object type

Notes:
1. Code page and graphic character set are dependent on each other. If you
specify one of these, you must specify the other.
2. The special value of *FILE is not allowed when using this attribute to create a
new spooled file.
3. Up to 4 user defined options may be specified.

Chapter 3. Express C/C++ APIs 745


cwbOBJ_CreateParmObjHandle
Purpose: Allocate a parameter list object handle. The parameter list object can be
used to hold a list of parameters that can be passed in on other APIs.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CreateParmObjHandle(


cwbOBJ_ParmHandle *parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ParmHandle *parmListHandle - output
Handle of the parameter object.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.

Usage: The cwbOBJ_DeleteParmObjectHandle API must be called to free


resources allocated by this call.

746 Client Access Express Programming


cwbOBJ_CreateResourceHandle
Purpose: Create a resource handle for a particular AFP resource on a specified
system.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CreateResourceHandle(


const char *systemName,
const char *resourceName,
const char *resourceLibrary,
cwbOBJ_AFPResourceType resourceType,
cwbOBJ_ObjHandle *objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in an ASCIIZ string.
const char *resourceName - input
Pointer to the name of the AFP resource.
const char *resourceLibrary - input
Pointer to the name of the AS/400 library that contains the resource.
cwbOBJ_AFPResourceType resourceType - input
Specifies what type of resource this is. Must be one of the following:
v CWBOBJ_AFPRSC_FONT
v CWBOBJ_AFPRSC_FORMDEF
v CWBOBJ_AFPRSC_OVERLAY
v CWBOBJ_AFPRSC_PAGESEG
v CWBOBJ_AFPRSC_PAGEDEF
cwbOBJ_ObjHandle *objectHandle - output
On output this will contain the resource handle.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page being used.
CWB_API_ERROR
General API failure.

Usage: Use this API to get a handle to a resource if you know the name library
and type of resource. If you don’t know either of these or want to choose from a

Chapter 3. Express C/C++ APIs 747


list, use the list APIs to list AFP resources instead. This API does no checking of
the AFP resource on the host. The first time this handle is used to retrieve data for
the resource, a host error will be encountered if the resource file doesn’t exist.

748 Client Access Express Programming


cwbOBJ_CreateSplFHandle
Purpose: Create a spooled file handle for a particular spooled file on a specified
system.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_CreateSplFHandle(


const char *systemName,
const char *jobName,
const char *jobNumber,
const char *jobUser,
const char *splFName,
const unsigned long splFNumber,
cwbOBJ_ObjHandle *objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in an ASCIIZ string.
const char *jobName - input
Pointer to the name of the AS/400 job that created the spooled file in an
ASCIIZ string.
const char *jobNumber - input
Pointer to the number of the AS/400 job that created the spooled file in an
ASCIIZ string.
const char *jobNumber - input
Pointer to the user of the AS/400 job that created the spooled file in an ASCIIZ
string.
const char *splFName - input
Pointer to the name of the spooled file in an ASCIIZ string.
const unsigned long splFNumber - input
The number of the spooled file.
cwbOBJ_ObjHandle *objectHandle - output
On output this will contain the spooled file handle.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.

Chapter 3. Express C/C++ APIs 749


CWB_API_ERROR
General API failure.

Usage: This API does no checking of the spooled file on the host. The first time
this handle is used to retrieve data for the spooled file, a host error will be
encountered if the spooled file doesn’t exist.

750 Client Access Express Programming


cwbOBJ_DeleteListHandle
Purpose: Deallocates a list handle that was previously allocated with the
cwbOBJ_CreateListHandle() API. This will free any resources associated with the
list.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DeleteListHandle(


cwbOBJ_ListHandle listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
List handle that will be deleted.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_INVALID_HANDLE
List handle not found.

Usage: If the list associated with this handle is opened, this call will close it. If
there are opened handles to objects in this list, they will no longer be valid. After
this call returns successfully, the list handle is no longer valid.

Chapter 3. Express C/C++ APIs 751


cwbOBJ_DeleteObjHandle
Purpose: Releases a handle to an object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DeleteObjHandle(


cwbOBJ_ObjHandle objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to release.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.

Usage: None

752 Client Access Express Programming


cwbOBJ_DeleteParmObjHandle
Purpose: Deallocate a parameter list object handle and free the resources used by
it.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DeleteParmObjHandle(


cwbOBJ_ParmHandle parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ParmHandle parmListHandle - input
Handle of the parameter object.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not a parameter object handle.

Usage: After this call returns successfully, the parmListHandle is no longer valid.

Chapter 3. Express C/C++ APIs 753


cwbOBJ_DeleteSplF
Purpose: Delete an AS/400 spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DeleteSplF(


cwbOBJ_ObjHandle splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be deleted.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.

Usage: After this calls returns successfully, cwbOBJ_DeleteObjHandle() should be


called to release the splFHandle.

754 Client Access Express Programming


cwbOBJ_DisplayResource
Purpose: Displays the specified AFP resource to the user.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DisplayResource(


cwbOBJ_ObjHandle resourceHandle,
const char *view,
const unsigned long flags,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle resourceHandle - input
Handle of the AFP Resource object. It must be an overlay or a pagesegment
type of resource.
const char *view - input
Optional, may be NULL. If specified, it is a pointer to an ASCIIZ string that
specifies the view to use when invoking the AFP viewer. There are two
predefined views shipped with the viewer: LETTER (8.5″ x 11″) and SFLVIEW
(132 column). Users may also add their own.
const unsigned long flags - input
Any of following bits may be set: CWBOBJ_DSPSPLF_WAIT - instructs this call
to wait until the viewer process has successfully opened the resource before
returning. If this bit is 0, this API will return after it starts the viewer process.
If it is 1, this API will wait for the viewer to get the resource open before
returning. All other bits must be set to 0.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate a temporary buffer.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_NO_VIEWER
The viewer support for ClientAccess/400 was not installed.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page that is being used.
CWB_API_ERROR
General API failure.
CWBOBJ_RC_INVALID_TYPE
The handle given for resourceHandle is not a handle to an overlay or
pagesegment resource.

Chapter 3. Express C/C++ APIs 755


Usage: Use this API to bring up the AFP viewer on the specified AFP resource.
The type of the resource must be an overlay or a pagesegment. A return code of
CWB_NO_VIEWER means that the viewer component was not installed on the
workstation.

756 Client Access Express Programming


cwbOBJ_DisplaySplF
Purpose: Displays the specified spooled file to the user.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DisplaySplF(


cwbOBJ_ObjHandle splFHandle,
const char *view,
const unsigned long flags,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the parameter object.
const char *view - input
Optional, may be NULL. If specified it is a pointer to an ASCIIZ string that
specifies the view to use when invoking the spooled file viewer. The are two
predefined views shipped with the viewer:
1. LETTER (8.5″ x 11″)
2. SFLVIEW (132 column)
Users may also add their own.
const unsigned long flags - input
Any of following bits may be set: CWBOBJ_DSPSPLF_WAIT - instructs this call
to wait until the viewer process has successfully opened the spooled file before
returning. If this bit is 0, this API will return after it starts the viewer process.
If it is 1, this API will wait for the viewer to get the spooled file open before
returning. All other bits must be set to 0.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_NO_VIEWER
The viewer support for ClientAccess/400 was not installed.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: Use this API to bring up the AFP viewer on the specified spooled file. The
AFP viewer can view AFP data, SCS data and plain ASCII text data. A return code

Chapter 3. Express C/C++ APIs 757


of CWB_NO_VIEWER means that the viewer component was not installed on the
workstation.

758 Client Access Express Programming


cwbOBJ_DropConnections
Purpose: Drops all unused conversations to all systems for the network print
server for this process.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_DropConnections(


cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The CWBOBJ.DLL maintains a pool of available conversations to the


network print server for use on the APIs. These conversations normally time out
after not having been used for 10 to 20 minutes and are then dropped. This API
allows the application to clean up the pool of conversations immediately without
waiting for the timeout. It can also be used at the end of the process to make sure
that any conversations are terminated. This API will drop all connections to all
servers for this process that are not ″in use.″ In use connections include those with
open spooled files on them (for creating or reading from).

Chapter 3. Express C/C++ APIs 759


cwbOBJ_EndWriter
Purpose: Ends an AS/400 writer job.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_EndWriter(


cwbOBJ_ObjHandle writerHandle,
cwbOBJ_ParmHandle *parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle writerHandle - input
Handle of the writer job to be stopped. This handle can be obtained by either
listing writers and getting the writer handle from that list or from starting a
writer and asking for the writer handle to be returned.
cwbOBJ_ParmHandle *parmListHandle - input
Optional. A pointer to a valid parameter list object handle that contains
parameters for ending the writer.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: After this calls returns successfully, cwbOBJ_DeleteObjHandle( should be


called to release the writerHandle. The following parameter key’s may be set in the
pParmListHandl object:
v CWBOBJ_KEY_WTREND - When to end the writer. May be any these special
values:
*CNTRLD - end the writer after the current file is done printing.
*IMMED - end the writer immediately
*PAGEEND - end the writer at the end of the current page.

760 Client Access Express Programming


cwbOBJ_GetListSize
Purpose: Get the size of an opened list.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetListSize(


cwbOBJ_ListHandle listHandle,
unsigned long *size,
cwbOBJ_List_Status *listStatus,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
Handle of the list to get the size of. This list must be opened.
unsigned long *size - output
On output, this will be set to the current size of the list.
cwbOBJ_List_Status *listStatus - output
Optional, may be NULL. This will always be CWBOBJ_LISTSTS_COMPLETED
for lists opened synchronously.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated list handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_LIST_NOT_OPEN
The list isn’t open.

Usage: None

Chapter 3. Express C/C++ APIs 761


cwbOBJ_GetNPServerAttr
Purpose: Get an attribute of the QNPSERVR program on a specified system.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetNPServerAttr(


const char *systemName,
cwbOBJ_KeyID key,
void *buffer,
unsigned long bufLen,
unsigned long *bytesNeeded,
cwbOBJ_DataType *keyType,
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in an ASCIIZ string.
cwbOBJ_KeyID key - input
Identifying key of the attribute to retrieve.
void *buffer - output
The buffer that will hold the attribute value. If this call returns successfully.
The value of the key determines what type of data will be put into pBuffer.
The type is also returned to the *keyType parameter, if provided.
unsigned long bufLen - input
The length of the buffer pointed to by pBuffer.
unsigned long *bytesNeeded - output
On output, this will be the number of bytes needed to hold result.
cwbOBJ_DataType *keyType - output
Optional, may be NULL. On output this will contain the type of data used to
represent this attribute and what is stored at *buffer.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_BUFFER_OVERFLOW
Buffer too small.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_KEY
Key isn’t valid.

762 Client Access Express Programming


CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: The following attributes may be retrieved from the QNPSERVR program:
v CWBOBJ_KEY_NPSCCSID - Server CCSID
v CWBOBJ_KEY_NPSLEVEL - Server code level

Chapter 3. Express C/C++ APIs 763


cwbOBJ_GetObjAttr
Purpose: Get an attribute of an object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetObjAttr(


cwbOBJ_ObjHandle objectHandle,
cwbOBJ_KeyID key,
void *buffer,
unsigned long bufLen,
unsigned long *bytesNeeded,
cwbOBJ_DataType *keyType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to get the attribute for.
cwbOBJ_KeyID key - input
Identifying key of the attribute to retrieve. The CWBOBJ_KEY_XXX constants
define the key ids. The type of object pointed to by objectHandle determine
which keys are valid.
void *buffer - output
The buffer that will hold the attribute value, if this call returns successfully.
The value of the key determines what type of data will be put into pBuffer.
The type is also returned to the *keyType parameter, if provided.
unsigned long bufLen - input
The length of the buffer pointed to by pBuffer.
unsigned long *bytesNeeded - output
On output, this will be the number of bytes needed to hold result.
cwbOBJ_DataType *keyType - output
Optional, may be NULL. On output this will contain the type of data used to
represent this attribute and what is stored at *buffer.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_BUFFER_OVERFLOW
Buffer too small.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

764 Client Access Express Programming


CWBOBJ_RC_INVALID_KEY
Key isn’t valid.
CWB_API_ERROR
General API failure.

Usage: The following attributes may be retrieved for these object types:
v CWBOBJ_LIST_SPLF:
CWBOBJ_KEY_AFP - AFP resources used
CWBOBJ_KEY_ALIGN - Align page
CWBOBJ_KEY_BKMGN_ACR - Back margin across
CWBOBJ_KEY_BKMGN_DWN - Back margin down
CWBOBJ_KEY_BKOVRLLIB - Back overlay library name
CWBOBJ_KEY_BKOVRLAY - Back overlay name
CWBOBJ_KEY_BKOVL_ACR - Back overlay offset across
CWBOBJ_KEY_BKOVL_DWN - Back overlay offset down
CWBOBJ_KEY_CPI - Characters per inch
CWBOBJ_KEY_CODEDFNTLIB - Coded font library name
CWBOBJ_KEY_CODEDFNT - Coded font
CWBOBJ_KEY_COPIES - Copies (total)
CWBOBJ_KEY_COPIESLEFT - Copies left to produce
CWBOBJ_KEY_CURPAGE - Current page
CWBOBJ_KEY_DATE - Date file was opened
CWBOBJ_KEY_PAGRTT - Degree of page rotation
CWBOBJ_KEY_ENDPAGE - Ending page
CWBOBJ_KEY_FILESEP - File separators
CWBOBJ_KEY_FOLDREC - Wrap text to next line
CWBOBJ_KEY_FONTID - Font identifier to use (default)
CWBOBJ_KEY_FORMFEED - Form feed
CWBOBJ_KEY_FORMTYPE - Form type
CWBOBJ_KEY_FTMGN_ACR - Front margin across
CWBOBJ_KEY_FTMGN_DWN - Front margin down
CWBOBJ_KEY_FTOVRLLIB - Front overlay library name
CWBOBJ_KEY_FTOVRLAY - Front overlay
CWBOBJ_KEY_FTOVL_ACR - Front overlay offset across
CWBOBJ_KEY_FTOVL_DWN - Front overlay offset down
CWBOBJ_KEY_CHAR_ID - Graphic character set
CWBOBJ_KEY_JUSTIFY - Hardware justification
CWBOBJ_KEY_HOLD - Hold the spool file
CWBOBJ_KEY_JOBNAME - Name of the job that created file
CWBOBJ_KEY_JOBNUMBER - Number of the job that created file
CWBOBJ_KEY_USER - Name of the user that created file
CWBOBJ_KEY_LASTPAGE - Last page that printed
CWBOBJ_KEY_LPI - Lines per inch
CWBOBJ_KEY_MAXRECORDS - Maximum number of records allowed
CWBOBJ_KEY_OUTPTY - Output priority
CWBOBJ_KEY_OUTQUELIB - Output queue library name
CWBOBJ_KEY_OUTQUE - Output queue
CWBOBJ_KEY_OVERFLOW - Overflow line number
CWBOBJ_KEY_PAGELEN - Page length
CWBOBJ_KEY_MEASMETHOD - Measurement method
CWBOBJ_KEY_PAGEWIDTH - Page width
CWBOBJ_KEY_MULTIUP - Logical pages per physical side
CWBOBJ_KEY_POINTSIZE - The default font's point size
CWBOBJ_KEY_FIDELITY - The error handling when printing
CWBOBJ_KEY_DUPLEX - Print on both sides of paper
CWBOBJ_KEY_PRTQUALITY - Print quality
CWBOBJ_KEY_PRTTEXT - Text printed at bottom of each page
CWBOBJ_KEY_PRTDEVTYPE - Printer dev type (data stream type)
CWBOBJ_KEY_PRTRFILELIB - Printer file library
CWBOBJ_KEY_PRTRFILE - Printer file
CWBOBJ_KEY_RECLENGTH - Record length
CWBOBJ_KEY_RPLUNPRT - Replace unprintable characters
CWBOBJ_KEY_RPLCHAR - Character to replace unprintables
CWBOBJ_KEY_RESTART - Where to restart printing at
CWBOBJ_KEY_SAVESPLF - Save file after printing

Chapter 3. Express C/C++ APIs 765


CWBOBJ_KEY_SRCDRWR - Source drawer
CWBOBJ_KEY_SPOOLFILE - Spool file name
CWBOBJ_KEY_SPLFNUM - Spool file number
CWBOBJ_KEY_SPLFSTATUS - Spool file status
CWBOBJ_KEY_STARTPAGE - Starting page to print
CWBOBJ_KEY_TIME - Time spooled file was opened at
CWBOBJ_KEY_PAGES - Number of pages in spool file
CWBOBJ_KEY_UNITOFMEAS - Unit of measure
CWBOBJ_KEY_USERCMT - User comment
CWBOBJ_KEY_USERDATA - User data
CWBOBJ_KEY_USRDFNDTA - User defined data
CWBOBJ_KEY_USRDFNOPTS - User defined options
CWBOBJ_KEY_USRDFNOBJ - User defined object
CWBOBJ_KEY_USRDFNOBJLIB- User defined object library
CWBOBJ_KEY_USRDFNOBJTYP- User defined object type
v CWBOBJ_LIST_OUTQ:
CWBOBJ_KEY_AUTHCHCK - authority to check
CWBOBJ_KEY_DATAQUELIB - data queue library
CWBOBJ_KEY_DATAQUE - data queue
CWBOBJ_KEY_DESCRIPTION - text description
CWBOBJ_KEY_DISPLAYANY - users can display any file on queue
CWBOBJ_KEY_JOBSEPRATR - number of job separators
CWBOBJ_KEY_NUMFILES - total spooled files on output queue
CWBOBJ_KEY_NUMWRITERS - number of writers started to queue
CWBOBJ_KEY_OPCNTRL - operator controlled
CWBOBJ_KEY_ORDER - order on queue (sequence)
CWBOBJ_KEY_OUTQUELIB - output queue library name
CWBOBJ_KEY_OUTQUE - output queue
CWBOBJ_KEY_OUTQUESTS - output queue status
CWBOBJ_KEY_PRINTER - printer
CWBOBJ_KEY_SEPPAGE - print banner page
CWBOBJ_KEY_USRDFNDTA - user defined data
CWBOBJ_KEY_USRDFNOBJ - user defined object
CWBOBJ_KEY_USRDFNOBJLIB- user defined object library
CWBOBJ_KEY_USRDFNOBJTYP- user defined object type
CWBOBJ_KEY_USRDFNOPTS - user defined options
CWBOBJ_KEY_USRDRVPGM - user driver program
CWBOBJ_KEY_USRDRVPGMLIB- user driver program library
CWBOBJ_KEY_USRDRVPGMDTA- user driver program data
CWBOBJ_KEY_USRTFMPGM - user data transform program
CWBOBJ_KEY_USRTFMPGMLIB- user data transform program library
CWBOBJ_KEY_WRITER - writer job name
CWBOBJ_KEY_WTRJOBNUM - writer job number
CWBOBJ_KEY_WTRJOBSTS - writer job status
CWBOBJ_KEY_WTRJOBUSER - writer job user

v CWBOBJ_LIST_PRTD:
CWBOBJ_KEY_AFP - AFP resources used
CWBOBJ_KEY_CODEPAGE - code page
CWBOBJ_KEY_DEVCLASS - device class
CWBOBJ_KEY_DEVMODEL - device model
CWBOBJ_KEY_DEVTYPE - device type
CWBOBJ_KEY_DRWRSEP - drawer to use for separators
CWBOBJ_KEY_FONTID - font identifier
CWBOBJ_KEY_FORMFEED - form feed
CWBOBJ_KEY_CHAR_ID - graphic character set
CWBOBJ_KEY_MFGTYPE - manufacturer's type & model
CWBOBJ_KEY_MSGQUELIB - message queue library
CWBOBJ_KEY_MSGQUE - message queue
CWBOBJ_KEY_POINTSIZE - default font's point size
CWBOBJ_KEY_PRINTER - printer
CWBOBJ_KEY_PRTQUALITY - print quality
CWBOBJ_KEY_DESCRIPTION - text description
CWBOBJ_KEY_SCS2ASCII - transform SCS to ASCII
CWBOBJ_KEY_USRDFNDTA - user defined data
CWBOBJ_KEY_USRDFNOPTS - user defined options
CWBOBJ_KEY_USRDFNOBJLIB- user defined object library
CWBOBJ_KEY_USRDFNOBJ - user defined object
CWBOBJ_KEY_USRDFNOBJTYP- user defined object type
CWBOBJ_KEY_USRTFMPGMLIB- user data transform
program library
CWBOBJ_KEY_USRTFMPGM - user data transform program
CWBOBJ_KEY_USRDRVPGMDTA- user driver program data
CWBOBJ_KEY_USRDRVPGMLIB- user driver program library
CWBOBJ_KEY_USRDRVPGM - user driver program
v CWBOBJ_LIST_PRTF:

766 Client Access Express Programming


CWBOBJ_KEY_ALIGN - align page
CWBOBJ_KEY_BKMGN_ACR - back margin across
CWBOBJ_KEY_BKMGN_DWN - back margin down
CWBOBJ_KEY_BKOVRLLIB - back side overlay library
CWBOBJ_KEY_BKOVRLAY - back side overlay name
CWBOBJ_KEY_BKOVL_DWN - back overlay offset down
CWBOBJ_KEY_BKOVL_ACR - back overlay offset across
CWBOBJ_KEY_CPI - characters per inch
CWBOBJ_KEY_CODEDFNTLIB - coded font library name
CWBOBJ_KEY_CODEPAGE - code page
CWBOBJ_KEY_CODEDFNT - coded font
CWBOBJ_KEY_COPIES - copies (total)
CWBOBJ_KEY_DBCSDATA - contains DBCS character set data
CWBOBJ_KEY_DBCSEXTENSN - process DBCS extension
characters
CWBOBJ_KEY_DBCSROTATE - rotate DBCS characters
CWBOBJ_KEY_DBCSCPI - DBCS CPI
CWBOBJ_KEY_DBCSSISO - DBCS SI/SO positioning
CWBOBJ_KEY_DFR_WRITE - defer write
CWBOBJ_KEY_PAGRTT - degree of page rotation
CWBOBJ_KEY_ENDPAGE - ending page number to print
CWBOBJ_KEY_FILESEP - number of file separators
CWBOBJ_KEY_FOLDREC - wrap text to next line
CWBOBJ_KEY_FONTID - Font identifier to use (default)
CWBOBJ_KEY_FORMFEED - type of paperfeed to be used
CWBOBJ_KEY_FORMTYPE - name of the form to be used
CWBOBJ_KEY_FTMGN_ACR - front margin across
CWBOBJ_KEY_FTMGN_DWN - front margin down
CWBOBJ_KEY_FTOVRLLIB - front side overlay library
CWBOBJ_KEY_FTOVRLAY - front side overlay name
CWBOBJ_KEY_FTOVL_ACR - front overlay offset across
CWBOBJ_KEY_FTOVL_DWN - front overlay offset down
CWBOBJ_KEY_CHAR_ID - graphic character set for this file
CWBOBJ_KEY_JUSTIFY - hardware justification
CWBOBJ_KEY_HOLD - hold the spool file
CWBOBJ_KEY_LPI - lines per inch
CWBOBJ_KEY_MAXRCDS - maximum number of records allowed
CWBOBJ_KEY_OUTPTY - output priority
CWBOBJ_KEY_OUTQUELIB - output queue library
CWBOBJ_KEY_OUTQUE - output queue
CWBOBJ_KEY_OVERFLOW - overflow line number
CWBOBJ_KEY_LINES_PAGE - page length in lines per page
CWBOBJ_KEY_PAGELEN - page length in Units of Measurement
CWBOBJ_KEY_MEASMETHOD - measurement method
(*ROWCOL or *UOM)
CWBOBJ_KEY_CHAR_LINE - page width in characters per line
CWBOBJ_KEY_PAGEWIDTH - width of page in Units of Measure
CWBOBJ_KEY_MULTIUP - logical pages per physical side
CWBOBJ_KEY_POINTSIZE - the default font's point size
CWBOBJ_KEY_FIDELITY - the error handling when printing
CWBOBJ_KEY_DUPLEX - print on both sides of paper
CWBOBJ_KEY_PRTQUALITY - print quality
CWBOBJ_KEY_PRTTEXT - text printed at bottom of each page
CWBOBJ_KEY_PRINTER - printer device name
CWBOBJ_KEY_PRTDEVTYPE - printer dev type (data stream type)
CWBOBJ_KEY_PRTRFILELIB - printer file library
CWBOBJ_KEY_PRTRFILE - printer file
CWBOBJ_KEY_RPLUNPRT - replace unprintable characters
CWBOBJ_KEY_RPLCHAR - character to replace unprintables
CWBOBJ_KEY_SAVE - save spooled file after printing
CWBOBJ_KEY_SRCDRWR - source drawer
CWBOBJ_KEY_SPOOL - spool the data
CWBOBJ_KEY_SCHEDULE - when available to the writer
CWBOBJ_KEY_STARTPAGE - starting page to print
CWBOBJ_KEY_DESCRIPTION - text description
CWBOBJ_KEY_UNITOFMEAS - unit of measure
CWBOBJ_KEY_USERDATA - user data

Chapter 3. Express C/C++ APIs 767


CWBOBJ_KEY_USRDFNDTA - User defined data
CWBOBJ_KEY_USRDFNOPTS - User defined options
CWBOBJ_KEY_USRDFNOBJLIB- User defined object library
CWBOBJ_KEY_USRDFNOBJ - User defined object
CWBOBJ_KEY_USRDFNOBJTYP- User defined object type
v CWBOBJ_LIST_WTR:
CWBOBJ_KEY_WRITER - writer job name
CWBOBJ_KEY_WTRJOBNUM - writer job number
CWBOBJ_KEY_WTRJOBSTS - writer job status
CWBOBJ_KEY_WTRJOBUSER - writer job user
v CWBOBJ_LIST_LIB:
CWBOBJ_KEY_LIBRARY - the library name
CWBOBJ_KEY_DESCRIPTION - description of the library
v CWBOBJ_LIST_RSC:
CWBOBJ_KEY_RSCNAME - resource name
CWBOBJ_KEY_RSCLIB - resource library
CWBOBJ_KEY_RSCTYPE - resource object type
CWBOBJ_KEY_OBJEXTATTR - object extended attribute
CWBOBJ_KEY_DESCRIPTION - description of the resource
CWBOBJ_KEY_DATE - date object was last modified
CWBOBJ_KEY_TIME - time object was last modified

768 Client Access Express Programming


cwbOBJ_GetObjAttrs
Purpose: Get several attributes of an object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetObjAttrs(


cwbOBJ_ObjHandle objectHandle,
unsigned long numAttrs,
cwbOBJ_GetObjAttrParms *getAttrParms,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to get the attribute for.
unsigned long numAttrs - input
number of attributes to retrieve
cwbOBJ_GetObjAttrParms *getAttrParms - input
an array of numAttrs elements that for each attribute to retrieve gives the
attribute key (id), the buffer where to store the value for that attribute and the
size of the buffer
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_BUFFER_OVERFLOW
Buffer too small.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_KEY
Key isn’t valid.
CWB_API_ERROR
General API failure.

Usage: See the Usage Notes in cwbOBJ_GetObjAttr to see which attribute are
valid for the various types of objects.

Chapter 3. Express C/C++ APIs 769


cwbOBJ_GetObjHandle
Purpose: Get list object. This call gets a handle to an object in an opened list. The
handle returned must be released with the the cwbOBJ_DeleteObjHandle when the
caller is done with it to release resources. The handle returned is only valid while
the list is opened.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetObjHandle(


cwbOBJ_ListHandle listHandle,
unsigned long ulPosition,
cwbOBJ_ObjHandle *objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
Handle of the list to get the object handle from. This list must be opened.
unsigned long ulPosition - input
The position within the list of the object to get a handle for. It is 0 based. Valid
values are 0 to the number of objects in the list - 1. You can use
cwbOBJ_GetListSize() to get the size of the list.
cwbOBJ_ObjHandle *objectHandle - output
On return, this will contain the handle of the object.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated list handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_LIST_NOT_OPEN
The list isn’t open.
CWBOBJ_RC_INVALID_INDEX
The ulPosition is out of range.

Usage: None

770 Client Access Express Programming


cwbOBJ_GetObjHandleFromID
Purpose: Regenerate an object handle from it’s binary ID and type.
cwbOBJ_DeleteObjHandle() must be called to free resources when you are done
using the object handle.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetObjHandleFromID(


void *idBuffer,
unsigned long bufLen,
cwbOBJ_ObjType objectType,
cwbOBJ_ObjHandle *objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
void *idBuffer - input
The buffer that holds the id of this object.
unsigned long bufLen - input
The length of the data pointed to by pIDBuffer.
cwbOBJ_ObjType type - input
Type of object this ID is for. This must match the type of object the ID was
taken from.
cwbOBJ_ObjHandle *objectHandle - output
If this call returns successfully, this will be the handle to the object. This handle
should be released with the cwbOBJ_DeleteObjHandle() API when done using
it.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_INVALID_TYPE
objectType is not correct.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: None

Chapter 3. Express C/C++ APIs 771


cwbOBJ_GetObjID
Purpose: Get the id of an object. This is the data the uniquely identifies this object
on the server. The data gotten is not readable and is binary. It can be passed back
on the cwbOBJ_GetObjHandleFromID() API to get a handle back to that object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetObjID(


cwbOBJ_ObjHandle objectHandle,
void *idBuffer,
unsigned long bufLen,
unsigned long *bytesNeeded,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to get the ID from.
void *idBuffer - output
The buffer that will hold the ID of this object.
unsigned long bufLen - input
The length of the buffer pointed to by pIDBuffer.
unsigned long *bytesNeeded - output
On output, this will be the number of bytes needed to hold the ID.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_BUFFER_OVERFLOW
Buffer too small.

Usage: None

772 Client Access Express Programming


cwbOBJ_GetParameter
Purpose: Gets the value of a parameter in a parameter list object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetParameter(


cwbOBJ_ParmHandle parmListHandle,
cwbOBJ_KeyID key,
void *buffer,
unsigned long bufLen,
unsigned long *bytesNeeded,
cwbOBJ_DataType *keyType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ParmHandle parmListHandle - input
Handle of the parameter object.
cwbOBJ_KeyID key - input
The id of the parameter to set.
void *buffer - output
The buffer that will hold the attribute value. If this call returns successfully.
The value of the key determines what type of data will be put into pBuffer.
The type is also returned to the *keyType parameter, if provided.
unsigned long bufLen - input
The length of the buffer pointed to by buffer.
unsigned long *bytesNeeded - output
On output, this will be the number of bytes needed to hold result.
cwbOBJ_DataType *keyType - output
Optional, may be NULL. On output this will contain the type of data used to
represent this attribute and what is stored at *buffer.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_BUFFER_OVERFLOW
Buffer too small.
CWBOBJ_RC_KEY_NOT_FOUND
Key isn’t specified in parameter list.
CWB_API_ERROR
General API failure.

Chapter 3. Express C/C++ APIs 773


Usage: None

774 Client Access Express Programming


cwbOBJ_GetSplFHandleFromNewSplF
Purpose: Uses a new spooled file handle to generate a spooled file handle. See
notes below about using this API on a new spool file that was created with data
type automatic.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetSplFHandleFromNewSplF(


cwbOBJ_ObjHandle newSplFHandle,
cwbOBJ_ObjHandle *splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle newSplFHandle - input
New spooled file handle. This is the handle passed back on the
cwbOBJ_CreateNewSplF() API.
cwbOBJ_ObjHandle *splFHandle - output
Pointer to an object handle that, upon successful completion of this call, will
hold the spooled file handle. This handle may be used with other APIs that
take a spooled file handle as input.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_SPLFNOTOPEN
Spooled file hasn’t been created on the host yet.

Usage: The handle returned in splFHandle must be released with the


cwbOBJ_DeleteObjHandle() API in order to free resources.

If you are using automatic data typing for the spooled file (the attribute of
CWBOBJ_KEY_PRTDEVTYPE was set to *AUTO or or wasn’t specified on the
cwbOBJ_CreateNewSplF() API) then creation of the spooled file will be delayed
until sufficient data has been written to the spooled file to determine the type of
the data (*SCS, *AFPDS or *USERASCII). If the new spooled file is in this state
when you call this API, the return code will be CWBOBJ_RC_SPLFNOTOPEN.

Chapter 3. Express C/C++ APIs 775


cwbOBJ_GetSplFMsgAttr
Purpose: Retrieves an attribute of a message that’s associated with a spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_GetSplFMsgAttr(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_KeyID key,
void *buffer,
unsigned long bufLen,
unsigned long *bytesNeeded,
cwbOBJ_DataType *keyType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file.
cwbOBJ_KeyID key - input
Identifying key of the attribute to retrieve. The CWBOBJ_KEY_XXX constants
define the key ids.
void *buffer - output
The buffer that will hold the attribute value, if this call returns successfully.
The value of the key determines what type of data will be put into pBuffer.
The type is also returned to the *keyType parameter, if provided.
unsigned long bufLen - input
The length of the buffer pointed to by pBuffer.
unsigned long *bytesNeeded - output
On output, this will be the number of bytes needed to hold result.
cwbOBJ_DataType *keyType - output
Optional, may be NULL. On output this will contain the type of data used to
represent this attribute and what is stored at *buffer.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWB_BUFFER_OVERFLOW
Buffer too small.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_KEY
Key isn’t valid.

776 Client Access Express Programming


CWBOBJ_RC_SPLFNOMESSAGE
The spooled file isn’t waiting on a message.
CWB_API_ERROR
General API failure.

Usage: The following keys are valid:


CWBOBJ_KEY_MSGTEXT - Message text
CWBOBJ_KEY_MSGHELP - Message help text
CWBOBJ_KEY_MSGREPLY - Message reply
CWBOBJ_KEY_MSGTYPE - Message type
CWBOBJ_KEY_MSGID - Message ID
CWBOBJ_KEY_MSGSEV - Message severity
CWBOBJ_KEY_DATE - Message date
CWBOBJ_KEY_TIME - Message time

Message formatting characters will appear in the message text and should be used
as follows:
&N Force the text to a new line indented to column 2. If the text is longer than
1 line, the next lines should be indented to column 4 until the end of text
or another format control character is found.
&P Force the text to a new line indented to column 6. If the text is longer than
1 line, the next lines should be indented to column 4 until the end of text
or another format control character is found.
&B Force the text to a new line indented to column 4. If the text is longer than
1 line, the next lines should be indented to column 6 until the end of text
or another format control character is found.

Chapter 3. Express C/C++ APIs 777


cwbOBJ_HoldOutputQueue
Purpose: Holds an AS/400 output queue.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_HoldOutputQueue(


cwbOBJ_ObjHandle queueHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle queueHandle - input
Handle of the output queue to be held.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not a valid queue handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: None

778 Client Access Express Programming


cwbOBJ_HoldSplF
Purpose: Holds a spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_HoldSplF(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_ParmHandle *parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be held.
cwbOBJ_ParmHandle *parmListHandle - input
Optional. A pointer to a valid parameter list object handle that contains
parameters for holding the spooled file.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.

Usage: The following parameter key may be set in the parmListHandle object:
v CWBOBJ_KEY_HOLDTYPE
- what type of hold to do. May be ″*IMMED″ or ″*PAGEEND″. ″*IMMED″ is
the default.

Chapter 3. Express C/C++ APIs 779


cwbOBJ_IsViewerAvailable
Purpose: Checks if the spooled file viewer is available.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_IsViewerAvailable(


cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion (viewer is installed).
CWB_NO_VIEWER
Viewer not installed.

Usage: Use this function to test for the presence of the viewer on the workstation.
If the viewer is installed this function will return CWB_OK. If the viewer is not
available, the function will return CWB_NO_VIEWER and the errorHandle
parameter (if provided) will contain an appropriate error message. Using this
function, applications can check for viewer support without calling the
cwbOBJ_DisplaySplF() API.

780 Client Access Express Programming


cwbOBJ_MoveSplF
Purpose: Moves an AS/400 spooled file to another output queue or to another
position on the same output queue.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_MoveSplF(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_ObjHandle *targetSplFHandle,
cwbOBJ_ObjHandle *outputQueueHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be moved.
cwbOBJ_ObjHandle *targetSplFHandle - input
Optional. The handle of another spooled file on the same system, that specifies
the spooled file to move this spooled file after. If this is specified,
*outputQueueHandle is not used.
cwbOBJ_ObjHandle *outputQueueHandle - input
Optional. The handle of an output queue on the same system that specifies
which output queue to move the spooled file to. The spooled file will be
moved to the first position on this queue. This parameter is ignored if
targetSplFHandle is specified.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.

Usage: If both targetSplFHandle and outputQueueHandle are NULL, the spooled


file will be moved to the first position on the current output queue.

Chapter 3. Express C/C++ APIs 781


cwbOBJ_OpenList
Purpose: Open the list. This actually builds the list. Caller must call the
cwbOBJ_ClostList() API when done with the list to free resources. After the list is
opened, the caller may use other APIs on the list to do things such as get the list
size and get object handles to items in the list.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_OpenList(


cwbOBJ_ListHandle listHandle,
cwbOBJ_List_OpenType openType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
Handle of the list to open.
cwbOBJ_List_OpenType openHandle - input
Manner in which to open the list. Must be set to
CWBOBJ_LIST_OPEN_SYNCH
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated list handle.
CWBOBJ_RC_LIST_OPEN
The list is already open.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_NOHOSTSUPPORT
Host doesn’t support this type of list.

Usage: None

782 Client Access Express Programming


cwbOBJ_OpenResource
Purpose: Opens an AFP resource object for reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_OpenResource(


cwbOBJ_ObjHandle resourceHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle resourceHandle - input
Handle of the AFP resource file to be opened for reading.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid resource handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_NOHOSTSUPPORT
Host doesn’t support working with resources.

Usage: The resource should be closed with the cwbOBJ_CloseResource() API


when done reading from it.

Chapter 3. Express C/C++ APIs 783


cwbOBJ_OpenResourceForSplF
Purpose: Opens an AFP Resource object for reading for a spooled file that is
already opened for reading. The API is useful if you are reading an AFP Spooled
file and run into an external AFP Resource that you need to read. By using this
API you can open that resource for reading without having to first list the
resource.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_OpenResourceForSplF(


cwbOBJ_ObjHandle splFHandle,
const char *resourceName,
const char *resourceLibrary,
unsigned long resourceType,
const char *reserved,
cwbOBJ_ObjHandle *resourceHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file that is already opened for reading and that the
resource will be opened against. The same conversation (and same instance of
the the network print server program on the AS/400) will be used for reading
the resource and spooled file.
const char *resourceName - input
Pointer to the name of the AFP Resource in an ASCIIZ string.
const char *resourceLibrary - input
Optional, may be NULL. Pointer to the AS/400 library of the AFP Resource in
an ASCIIZ string. If no library is specified, the library list of the spooled file is
used to search for the resource.
unsigned long resourceType - input
An unsigned long integer with one of the following bits on:
CWBOBJ_AFPRSC_FONT
CWBOBJ_AFPRSC_FORMDEF
CWBOBJ_AFPRSC_OVERLAY
CWBOBJ_AFPRSC_PAGESEG
CWBOBJ_AFPRSC_PAGEDEF
Specifies what type of resource to open.
const char *reserved -
Reserved, must be NULL.
cwbOBJ_OBJHandle *resourceHandle - output
Pointer to an OBJHandle that on successful return will contain the dynamically
allocated resource handle that can be used to read, seek and eventually close
the resource.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.

784 Client Access Express Programming


CWB_NO_ERROR
Successful completion.
CWB_FILE_NOT_FOUND
The resource wasn’t found.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_INVALID_HANDLE
Handle is not valid resource handle.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_SPLFNOTOPEN
The spooled file is not opened.
CWBOBJ_RC_NOHOSTSUPPORT
Host doesn’t support working with resources.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the code
page being used.
CWB_API_ERROR
General API failure.

Usage: This call, if successful, will generate a temporary resource handle and
return it in the resourceHandle parameter. This handle will be deleted
automatically when the caller calls the cwbOBJ_CloseResource() API with it.

The resource should be closed with the cwbOBJ_CloseResource()) API when done
reading from it.

Chapter 3. Express C/C++ APIs 785


cwbOBJ_OpenSplF
Purpose: Opens an AS/400 spooled file for reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_OpenSplF(


cwbOBJ_ObjHandle splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be opened for reading.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The spooled file should be closed with the cwbOBJ_CloseSplF() API when
done reading from it.

786 Client Access Express Programming


cwbOBJ_PurgeOutputQueue
Purpose: Purges spooled files on an AS/400 output queue.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_PurgeOutputQueue(


cwbOBJ_ObjHandle queueHandle,
cwbOBJ_ParmHandle *parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle queueHandle - input
Handle of the output queue to be purged.
cwbOBJ_ParmHandle * parmListHandle - input
Optional. A pointer to a valid parameter list object handle that contains
parameters for purging the output queue.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The parameters specified in parmListHandle, if provided, will specify


which spooled files are purged. If parmListHandle is NULL, all spooled files for
the current user are purged. The following parameter key’s may be set in the
parmListHandle object:
v CWBOBJ_KEY_USER
- which user’s spooled files to purge. May be a specific user ID, ″*ALL″ or
″*CURRENT″. ″*CURRENT″ is the default.
v CWBOBJ_KEY_FORMTYPE
- which spooled files to purge base on what formtype they have. May be a
specific formtype, ″*ALL″ or ″*STD″. ″*ALL″ is the default.
v CWBOBJ_KEY_USERDATA
- which spooled files to purge base on what userdata they have. May be a
specific value or ″*ALL″. ″*ALL″ is the default.

Chapter 3. Express C/C++ APIs 787


cwbOBJ_ReadResource
Purpose: Reads bytes from the current read location.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ReadResource(


cwbOBJ_ObjHandle resourceHandle,
char *bBuffer,
unsigned long bytesToRead,
unsigned long *bytesRead,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle resourceHandle - input
Handle of the AFP resource object to be read from.
char *buffer - input
Pointer to buffer to hold the bytes read from the resource.
unsigned long bytesToRead - input
Maximum number of bytes to read. The number read may be less than this.
unsigned long *bytesRead - output
Number of bytes actually read.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_RSCNOTOPEN
Resource file has not been opened yet.
CWBOBJ_RC_ENDOFFILE
The end of file was read.

Usage: The cwbOBJ_OpenResource() API must be called with this resource handle
before this API is called OR the handle must be retrieved with a call to the
cwbOBJ_OpenResourceForSplF() API. If the end of file is reached when reading,
the return code will be CWBOBJ_RC_ENDOFFILE and bytesRead will contain the
actual number of bytes read.

788 Client Access Express Programming


cwbOBJ_ReadSplF
Purpose: Reads bytes from the current read location.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ReadSplF(


cwbOBJ_ObjHandle splFHandle,
char *bBuffer,
unsigned long bytesToRead,
unsigned long *bytesRead,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be read from.
char *buffer - input
Pointer to buffer to hold the bytes read from the spooled file.
unsigned long bytesToRead - input
Maximum number of bytes to read. The number read may be less than this.
unsigned long *bytesRead - output
Number of bytes actually read.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_SPLFNOTOPEN
Spooled file has not been opened yet.
CWBOBJ_RC_SPLFENDOFFILE
The end of file was read.

Usage: The cwbOBJ_OpenSplF() API must be called with this spooled fil handle
before this API is called. If the end of file is reached when reading, the return code
will be CWBOBJ_SPLF_ENDOFFILE and bytesRead will contain the actual number
of bytes read.

Chapter 3. Express C/C++ APIs 789


cwbOBJ_RefreshObj
Purpose: Refreshes the object with the latest information from the AS/400 server.
This will ensure the attributes returned for the object are up to date.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_RefreshObj(


cwbOBJ_ObjHandle objectHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle of the object to be refreshed.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The following object types may be refreshed:


v CWBOBJ_LIST_SPLF (spooled files)
v CWBOBJ_LIST_PRTF (printer files)
v CWBOBJ_LIST_OUTQ (output queues)
v CWBOBJ_LIST_PRTD (printer devices)
v CWBOBJ_LIST_WTR (writers)
Example: Assume listHandle points to a spooled file list with at least one entry in
it.
cwbOBJ_ObjHandle splFileHandle;
ulRC = cwbOBJ_GetObjHandle(listHandle,
0,
&splFileHandle,
NULL);
if (ulRC == CWB_NO_ERROR)
{
ulRC = cwbOBJ_RefreshObj(splFileHandle);
.....
get attributes for object
.....
ulRC = cwbOBJ_DeleteObjHandle(splFileHandle);
}

790 Client Access Express Programming


cwbOBJ_ReleaseOutputQueue
Purpose: Releases an AS/400 output queue.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ReleaseOutputQueue(


cwbOBJ_ObjHandle queueHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle queueHandle - input
Handle of the output queue to be released.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not a valid queue handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: None

Chapter 3. Express C/C++ APIs 791


cwbOBJ_ReleaseSplF
Purpose: Releases a spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ReleaseSplF(


cwbOBJ_ObjHandle splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be released.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.

Usage: None

792 Client Access Express Programming


cwbOBJ_ResetListAttrsToRetrieve
Purpose: Resets the list attributes to retrieve information to its default list.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ResetListAttrsToRetrieve(


cwbOBJ_ListHandle listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
List handle to reset.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion
CWB_INVALID_HANDLE
Handle is not an allocated list handle.

Usage: Use this call to reset the list handle’s list of attributes to retrieve after
calling cwbOBJ_SetListAttrsToRetrieve().

Chapter 3. Express C/C++ APIs 793


cwbOBJ_ResetListFilter
Purpose: Resets the filter on a list to what it was when the list was first allocated
(the default filter).

Syntax:

unsigned int CWB_ENTRY cwbOBJ_ResetListFilter(


cwbOBJ_ListHandle listHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
Handle of the list to have its filter reset.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not allocated list handle.

Usage: The list must be closed and reopened for the change to take affect.

794 Client Access Express Programming


cwbOBJ_SeekResource
Purpose: Moves the current read position on a resource that is open for reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SeekResource(


cwbOBJ_ObjHandle resourceHandle,
cwbOBJ_SeekOrigin seekOrigin,
signed long seekOffset,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle resourceHandle - input
Handle of the AFP resource file to be seeked.
cwbOBJ_SeekOrigin seekOrigin - input
Where to seek from. Valid values are:
CWBOBJ_SEEK_BEGINNING - seek from the beginning of file
CWBOBJ_SEEK_CURRENT - seek from the current read position
CWBOBJ_SEEK_ENDING - seek from the end of the file
signed long seekOffset - input
Offset (negative or positive) from the seek origin in bytes to move the current
read pointer to.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_RSCNOTOPEN
Resource has not been opened yet.
CWBOBJ_RC_SEEKOUTOFRANGE
Seek offset out of range.

Usage: The cwbOBJ_OpenResource() API must be called with this resource handle
before this API is called OR the handle must be retrieved with a call to the
cwbOBJ_OpenResourceForSplF() API.

Chapter 3. Express C/C++ APIs 795


cwbOBJ_SeekSplF
Purpose: Moves the current read position on a spooled file that is open for
reading.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SeekSplF(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_SeekOrigin seekOrigin,
signed long seekOffset,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be closed.
cwbOBJ_SeekOrigin seekOrigin - input
Where to seek from. Valid values are:
v CWBOBJ_SEEK_BEGINNING - seek from the beginning of file
v CWBOBJ_SEEK_CURRENT - seek from the current read position
v CWBOBJ_SEEK_ENDING - seek from the end of the file
signed long seekOffset - input
Offset (negative or positive) from the seek origin in bytes to move the current
read pointer to.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_SPLFNOTOPEN
Spooled file has not been opened yet.
CWBOBJ_RC_SEEKOUTOFRANGE
Seek offset out of range.

Usage: The cwbOBJ_OpenSplF() API must be called with this spooled file handle
before this API is called.

796 Client Access Express Programming


cwbOBJ_SendNetSplF
Purpose: Sends a spooled file to another user on the same system or to a remote
system on the network.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SendNetSplF(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_ParmHandle parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be sent.
cwbOBJ_ParmHandle parmListHandle - input
Required. A handle of a parameter list object that contains the parameters for
sending the spooled file.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.

Usage: The equivalent of an AS/400 send net spooled file (SNDNETSPLF)


command will be issued against the spooled file. The following parameter key’s
MUST be set in the parmListHandl object:
v CWBOBJ_KEY_TOUSERID
Specifies user ID to send the spooled file to.
v CWBOBJ_KEY_TOADDRESS
Specifies the remote system to send the spooled file to. ″*NORMAL″ is the
default.
The following parameter key’s may be set in the parmListHandle object:
v CWBOBJ_KEY_DATAFORMAT
Specifies the data format in which to transmit the spooled file. May be
″*RCDDATA″ or ″*ALLDATA″. ″*RCDDATA″ is the default.

Chapter 3. Express C/C++ APIs 797


v CWBOBJ_KEY_VMMVSCLASS
Specifies the VM/MVS SYSOUT class for distributions sent to a VM host
system or to an MVS host system. May be ″A″ to ″Z″ or ″0″ to ″9″. ″A″ is the
default.
v CWBOBJ_KEY_SENDPTY
Specifies the queueing priority used for this spooled file when it is being
routed through a snad network. May be ″*NORMAL″ or ″*HIGH″.
″*NORMAL″ is the default.

798 Client Access Express Programming


cwbOBJ_SendTCPSplF
Purpose: Sends a spooled file to be printed on a remote system. This i the AS/400
version of the TCP/IP LPR command.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SendTCPSplF(


cwbOBJ_ObjHandle splFHandle,
cwbOBJ_ParmHandle parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to be sent.
cwbOBJ_ParmHandle parmListHandle - input
Required. A handle of a parameter list object that contains the parameters for
sending the spooled file.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.
CWBOBJ_RC_INVALID_TYPE
Handle is not a spooled file handle.
CWBOBJ_KEY_SEPPAGE
Specifies wether or not to print the separator page.
CWBOBJ_KEY_USRDTATFMLIB
Specifies the name of the user data transform library.
CWBOBJ_KEY_USRDTATFM
Specifies the name of the user data transform.

Usage: The equivalent of an AS/400 send TCP/IP spooled file (SNDTCPSPLF)


command will be issued against the spooled file. The following parameter key’s
MUST be set in the parmListHandl object:
v CWBOBJ_KEY_RMTSYSTEM
Specifies the remote system to which the print request is sent. May be a
remote system name or ″*INTNETADR″.

Chapter 3. Express C/C++ APIs 799


v CWBOBJ_KEY_RMTPRTQ
Specifies the name of the destination print queue.
The following parameter key’s may be set in the parmListHandle object:
v CWBOBJ_KEY_DELETESPLF
Specifies whether to delete the spooled file after it has been successfully sent.
May be ″*NO″ or ″*YES″. ″*NO″ is the default.
v CWBOBJ_KEY_DESTOPTION
Specifies a destination-dependant option. These options will be sent to the
remote system with the spooled file.
v CWBOBJ_KEY_DESTINATION
Specifies the type of system to which the spooled file is being sent. When
sending to other AS/400 systems, this value should be ″*AS/400″. May also
be ″*OTHER″, ″*PSF/2″. ″*OTHER″ is the default.
v CWBOBJ_KEY_INTERNETADDR
Specifies the internet address of the receiving system.
v CWBOBJ_KEY_MFGTYPE
Specifies the manufacturer, type and model when transforming print data for
SCS to ASCII.
v CWBOBJ_KEY_SCS2ASCII
Specifies wether the print data is to be transformed for SCS to ASCII. May be
″*NO″ or ″*YES″. ″*NO″ is the default.
v CWBOBJ_KEY_WSCUSTMOBJ
Specifies the name of the workstation customizing object.
v CWBOBJ_KEY_WSCUSTMOBJL
Specifies the name of the workstation customizing object library.

800 Client Access Express Programming


cwbOBJ_SetConnectionsToKeep
Purpose: Set the number of connections that should be left active for a particular
system. Normally, the cwbobj.dll will time out and drop connections after they
have not been used for a while. With this API you can force it to leave open a
certain number of connections for this system.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetConnectionsToKeep(


const char *systemName
unsigned int connections
cwbSV_ErrHandle errorHandle);

Parameters:
const char *systemName - input
Pointer to the system name contained in ASCIIZ string.
unsigned int connections - input
The number to of connections to keep open.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_PARAMETER
Invalid parameter specified.

Usage: The default number of connections left open per system is 0. The
connections are made per process, so this API only affects connections under the
process it is called under. Setting the number of connections to be left open does
not open any new connections.

Chapter 3. Express C/C++ APIs 801


cwbOBJ_SetListAttrsToRetrieve
Purpose: An optional function that may be applied to list handle before the list is
opened. The purpose of doing this is to improve efficiency by allowing the
cwbOBJ_OpenList() API to retrieve just the attributes of each object that the
application will b using.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetListAttrsToRetrieve(


cwbOBJ_ListHandle listHandle,
unsigned long numKeys,
const cwbOBJ_KeyID *keys,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
List handle to apply the list of attribute keys to.
unsigned long numKeys - input
The number of keys pointed to by the ’keys’ parameter. May be 0, which
means that no attributes are needed for objects in the list.
const cwbOBJ_KeyID *keys - input
An array of numKeys keys that are the IDs of the attributes to be retrieved for
each object in the list when the list is opened.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated list handle.
CWB_INVALID_PARAMETER
Invalid parameter specified.

Usage: This call is used to provide a clue to the cwbOBJ_OpenList() API as to


what attributes the application is interested in for the objects that are listed. Using
this information, the cwbOBJ_OpenList() API can be more efficient. The attribute
keys that are valid in the ’keys’ list depend on type of object being listed (set on
cwbOBJ_CreateListHandle()) Call cwbOBJ_ResetListAttrsToRetrieve() to reset the
list to its default list of keys.

802 Client Access Express Programming


cwbOBJ_SetListFilter
Purpose: Sets filters for the list. This filter is applied the next time
cwbOBJ_OpenList() is called.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetListFilter(


cwbOBJ_ListHandle listHandle,
cwbOBJ_KeyID key,
const char *value,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
List handle that this filter will be applied to.
cwbOBJ_KeyID key - input
The id of the filtering field to be set.
const void *value - input
The value this field should be set to.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_INVALID_HANDLE
List handle not found.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: The value of key will determine the type that is pointed to value. The
length of value is determined by its type. The following filters may be set against
these list types Spooled File Lists:
v CWBOBJ_LIST_SPLF:
CWBOBJ_KEY_USER
Specifies which user’s spooled files are to be listed. May be a specific user
ID or one of these special values: *ALL - all users. *CURRENT - list
spooled files for the current user only. *CURRENT is the default.
CWBOBJ_KEY_OUTQUELIB
Specifies which libraries to search for output queues in. May be a specific
name or one of these special values: ″″ - if the OUTQUEUE key word is
*ALL, this combination will search all output queue on the system.
*CURLIB - the current library *LIBL - the library list *LIBL is the default if
the OUTQUE filter is not *ALL. ″″ is the default if the OUTQU filter is set
to *ALL.

Chapter 3. Express C/C++ APIs 803


CWBOBJ_KEY_OUTQUE
Specifies which output queues to search for spooled files on May be a
specific name or the special value *ALL. *ALL is the default.
CWBOBJ_KEY_FORMTYPE
Specifies which spooled files are listed by the form type attribute that
they have. May be a specific name or one of these special values: *ALL -
spooled files with any form type are listed. *STD - spooled files with the
form type of *STD are listed *ALL is the default.
CWBOBJ_KEY_USERDATA
Specifies which spooled files are listed by the user data that they have.
May be a specific value or one of these special values: *ALL - spooled
files with any user data value are listed. *ALL is the default.

Output Queue Lists:


v CWBOBJ_LIST_OUTQ:
CWBOBJ_KEY_OUTQUELIB
Specifies which libraries to search for output queues in. May be a specific
name, a generic name or any of these special values: *ALL - all libraries
*ALLUSER - all user-defined libraries, plus libraries containing user data
and having names starting with Q *CURLIB - the current library *LIBL -
the library list *USRLIBL - the user portion o the library list. *LIBL is the
default.

CWBOBJ_KEY_OUTQUE
Specifies which output queues to list. May be a specific name, a
generic name or *ALL. *ALL is the default.

Printer Device Description Lists:


v CWBOBJ_LIST_PRTD:
CWBOBJ_KEY_PRINTER
Specifies which printer device to list. May be a specific name, a generic
name or *ALL. *ALL is the default.

Printer File Lists:


v CWBOBJ_LIST_PRTF:
CWBOBJ_KEY_PRTRFILELIB
Specifies which libraries to search for printer files in. May be a specific
name, a generic name or any of these special values:
*ALL - all libraries
*ALLUSER - all user-defined libraries, plus libraries containing user
data and having names starting with Q
*CURLIB - the current library
*LIBL - the library list
*USRLIBL - the user portion o the library list.
*ALL is the default.
CWBOBJ_KEY_PRTRFILE
Specifies which printer files to list. May be a specific name, a generic
name or *ALL. *ALL is the default.

Writer Job Lists:

804 Client Access Express Programming


v CWBOBJ_LIST_WTR:
CWBOBJ_KEY_WRITER
Specifies which writer jobs to list. May be a specific name, a generic name
or *ALL. *ALL is the default.
CWBOBJ_KEY_OUTQUELIB & CWBOBJ_KEY_OUTQUE
These filters are used together to get a list of writers activ to a particular
output queue. If the OUTQUE key is specified the WRITER key is
ignored. (all writers for the specified output queue are listed). If the
OUTQUE key is specified and the OUTQUELIB isn’t, the OUTQUEULIB
will default to *LIBL - the system library list. The default is for neither of
these to be specified.

Library Lists:
v CWBOBJ_LIST_LIB:
CWBOBJ_KEY_LIBRARY
Specifies which libraries to list. May be a specific name, a generic name or
any of these special values:
*ALL - all libraries
*CURLIB - the current library
*LIBL - the library list
*USRLIBL - the user portion o the library list.
*USRLIBL is the default.
v CWBOBJ_LIST_RSC:
Resources can be lists in a spooled file (lists all of the external AFP resources
used by this spooled file) or in a library or set of libraries. To list resources
for a spooled file, use the cwbOBJ_SetListFilterWithSplF API along with the
SetListFilter API for the RSCTYPE and RSCNAME attributes.
CWBOBJ_KEY_RSCLIB
Specifies which libraries to search for resources in. This filter is
ignored if the list is filter by spooled file (i.e. SetListFilterWithSplF).
May be a specific name, a generic name or any of these special values:
*ALL - all libraries
*ALLUSR - All user-defined libraries, plus libraries containing user
data and having names starting with Q.
*CURLIB - the current library
*LIBL - the library list
*USRLIBL - the user portion o the library list.
*LIBL is the default.
CWBOBJ_KEY_RSCNAME
Specifies which resources to list by name. May be a specific name, a
generic name or *ALL.
*ALL is the default.
CWBOBJ_KEY_RESCTYPE
Specifies which type of resources to list. May be any combination of
the following bits logically OR’d together:
CWBOBJ_AFPRSC_FONT
CWBOBJ_AFPRSC_FORMDEF
CWBOBJ_AFPRSC_OVERLAY

Chapter 3. Express C/C++ APIs 805


CWBOBJ_AFPRSC_PAGESEG
CWBOBJ_AFPRSC_PAGEDEF

806 Client Access Express Programming


cwbOBJ_SetListFilterWithSplF
Purpose: Sets filter for a list to a spooled file. For listing resources this limits the
resources returned by the openList to those used by the spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetListFilterWithSplF(


cwbOBJ_ListHandle listHandle,
cwbOBJ_ObjHandle splFHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ListHandle listHandle - input
List handle that this filter will be applied to.
cwbOBJ_ObjHandle splFHandle - input
Handle of the spooled file to filter on.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWBOBJ_RC_INVALID_TYPE
Incorrect type of list.
CWB_INVALID_HANDLE
List handle not found or bad spooled file handle.

Usage: Filtering by spooled file is used when listing AFP resources so the list type
must be CWBOBJ_LIST_RSC. If you filter resources based on a spooled file you
cannot also filter based on a library or libraries. The resource library filter will be
ignored if both are specified. Resetting a list filter will also reset the spooled file
filter to nothing.

Chapter 3. Express C/C++ APIs 807


cwbOBJ_SetObjAttrs
Purpose: Change the attributes of the object on the server.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetObjAttrs(


cwbOBJ_ObjHandle objectHandle,
cwbOBJ_ParmHandle parmListHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle objectHandle - input
Handle to the object that is to be changed.
cwbOBJ_ParmHandle parmListHandle - input
Handle to the parameter object which contains the attributes that are to be
modified for the object.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not an allocated object handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: The following objects allow these attributes to be changed:


v CWBOBJ_LIST_SPLF (spooled files):
CWBOBJ_KEY_ALIGN - Align page
CWBOBJ_KEY_BKOVRLLIB - Back overlay library name
CWBOBJ_KEY_BKOVRLAY - Back overlay
CWBOBJ_KEY_BKOVL_ACR - Back overlay offset across
CWBOBJ_KEY_BKOVL_DWN - Back overlay offset down
CWBOBJ_KEY_COPIES - Copies
CWBOBJ_KEY_ENDPAGE - Ending page
CWBOBJ_KEY_FILESEP - File separators
CWBOBJ_KEY_FORMFEED - Form feed
CWBOBJ_KEY_FORMTYPE - Form type
CWBOBJ_KEY_FTOVRLLIB - Front overlay library name
CWBOBJ_KEY_FTOVRLAY - Front overlay
CWBOBJ_KEY_FTOVL_ACR - Front overlay offset across
CWBOBJ_KEY_FTOVL_DWN - Front overlay offset down
CWBOBJ_KEY_OUTPTY - Output priority
CWBOBJ_KEY_OUTQUELIB - Output queue library name
CWBOBJ_KEY_OUTQUE - Output queue
CWBOBJ_KEY_MULTIUP - Logical number of pages per side
CWBOBJ_KEY_FIDELITY - Print fidelity
CWBOBJ_KEY_DUPLEX - Print on both sides
CWBOBJ_KEY_PRTQUALITY - Print quality

808 Client Access Express Programming


CWBOBJ_KEY_PRTSEQUENCE - Print sequence
CWBOBJ_KEY_PRINTER - Printer
CWBOBJ_KEY_RESTART - Where to restart printing at
CWBOBJ_KEY_SAVESPLF - Save spooled file after printing
CWBOBJ_KEY_SCHEDULE - When spooled file available
CWBOBJ_KEY_STARTPAGE - Starting page
CWBOBJ_KEY_USERDATA - User data
CWBOBJ_KEY_USRDFNDTA - User defined data
CWBOBJ_KEY_USRDFNOPTS - User defined options
CWBOBJ_KEY_USRDFNOBJLIB - User defined object library
CWBOBJ_KEY_USRDFNOBJ - User defined object
CWBOBJ_KEY_USRDFNOBJTYP - User defined object type
v CWBOBJ_LIST_PRTF (printer files):
CWBOBJ_KEY_ALIGN - Align page
CWBOBJ_KEY_BKMGN_ACR - Back margin offset across
CWBOBJ_KEY_BKMGN_DWN - Back margin offset down
CWBOBJ_KEY_BKOVRLLIB - Back overlay library name
CWBOBJ_KEY_BKOVRLAY - Back overlay
CWBOBJ_KEY_BKOVL_ACR - Back overlay offset across
CWBOBJ_KEY_BKOVL_DWN - Back overlay offset down
CWBOBJ_KEY_CPI - Characters Per Inch
CWBOBJ_KEY_CODEPAGE - Code page
CWBOBJ_KEY_CODEDFNTLIB - Coded font library name
CWBOBJ_KEY_CODEDFNT - Coded font name
CWBOBJ_KEY_COPIES - Copies
CWBOBJ_KEY_DBCSDATA - Contains DBCS Data
CWBOBJ_KEY_DBCSEXTENSN - Process DBCS Extension characters
CWBOBJ_KEY_DBCSROTATE - DBCS character rotation
CWBOBJ_KEY_DBCSCPI - DBCS CPI
CWBOBJ_KEY_DBCSSISO - DBCS SO/SI spacing
CWBOBJ_KEY_DFR_WRITE - Defer writing
CWBOBJ_KEY_ENDPAGE - Ending page
CWBOBJ_KEY_FILESEP - File Separators(*FILE not
allowed)
CWBOBJ_KEY_FOLDREC - Fold records
CWBOBJ_KEY_FONTID - Font identifier
CWBOBJ_KEY_FORMFEED - Form feed
CWBOBJ_KEY_FORMTYPE - Form type
CWBOBJ_KEY_FTMGN_ACR - Front margin offset across
CWBOBJ_KEY_FTMGN_DWN - Front margin offset down
CWBOBJ_KEY_FTOVRLLIB - Front overlay library name
CWBOBJ_KEY_FTOVRLAY - Front overlay
CWBOBJ_KEY_FTOVL_ACR - Front overlay offset across
CWBOBJ_KEY_FTOVL_DWN - Front overlay offset down
CWBOBJ_KEY_CHAR_ID - Graphic character set ID
CWBOBJ_KEY_JUSTIFY - Hardware Justification
CWBOBJ_KEY_HOLD - Hold spooled file
CWBOBJ_KEY_LPI - Lines per inch
CWBOBJ_KEY_MAXRECORDS - Maximum spooled file records
CWBOBJ_KEY_OUTPTY - Output priority
CWBOBJ_KEY_OUTQUELIB - Output queue library name
CWBOBJ_KEY_OUTQUE - Output queue
CWBOBJ_KEY_OVERFLOW - Overflow line number
CWBOBJ_KEY_PAGELEN - Page Length
CWBOBJ_KEY_MEASMETHOD - Measurement method
CWBOBJ_KEY_PAGEWIDTH - Page width
CWBOBJ_KEY_MULTIUP - Logical number of pages per side
CWBOBJ_KEY_POINTSIZE - The default font's point size
CWBOBJ_KEY_FIDELITY - Print fidelity
CWBOBJ_KEY_DUPLEX - Print on both sides
CWBOBJ_KEY_PRTQUALITY - Print quality
CWBOBJ_KEY_PRTTEXT - Print text
CWBOBJ_KEY_PRINTER - Printer
CWBOBJ_KEY_PRTDEVTYPE - Printer Device Type
CWBOBJ_KEY_RPLUNPRT - Replace unprintable characters
CWBOBJ_KEY_RPLCHAR - Replacement character

Chapter 3. Express C/C++ APIs 809


CWBOBJ_KEY_SAVESPLF - Save spooled file after printing
CWBOBJ_KEY_SRCDRWR - Source drawer
CWBOBJ_KEY_SPOOL - Spool the data
CWBOBJ_KEY_SCHEDULE - When spooled file available
CWBOBJ_KEY_STARTPAGE - Starting page
CWBOBJ_KEY_DESCRIPTION - Text description
CWBOBJ_KEY_UNITOFMEAS - Unit of measure
CWBOBJ_KEY_USERDATA - User data
CWBOBJ_KEY_USRDFNDTA - User defined data
CWBOBJ_KEY_USRDFNOPTS - User defined options
CWBOBJ_KEY_USRDFNOBJLIB - User defined object library
CWBOBJ_KEY_USRDFNOBJ - User defined object
CWBOBJ_KEY_USRDFNOBJTYP - User defined object type
v CWBOBJ_LIST_OUTQ (output queues):
v CWBOBJ_LIST_PRTD (printer devices):
v CWBOBJ_LIST_WTR (writers):
v CWBOBJ_LIST_LIB (libraries):
NONE

810 Client Access Express Programming


cwbOBJ_SetParameter
Purpose: Sets the value of a parameter in a parameter list object.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_SetParameter(


cwbOBJ_ParmHandle parmListHandle,
cwbOBJ_KeyID key,
const void *value,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ParmHandle parmListHandle - input
Handle of the parameter object.
cwbOBJ_KeyID key - input
The id of the parameter to set.
void *value - input
The value to set the parameter to. The type that value points to is determined
by the value of key.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not a parameter object handle.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: None

Chapter 3. Express C/C++ APIs 811


cwbOBJ_StartWriter
Purpose: Starts an AS/400 writer job.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_StartWriter(


cwbOBJ_ObjHandle *printerHandle,
cwbOBJ_ObjHandle *outputQueueHandle,
cwbOBJ_ParmHandle *parmListHandle,
cwbOBJ_ObjHandle *writerHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle *printerHandle - input
Required. A pointer to a valid printer object handle that identifies which
printer this writer is to be started to.
cwbOBJ_ObjHandle *outputQueueHandle - input
Optional. A pointer to a valid output queue object handle that identifies which
output queue this writer is to be started from. If the parmListHandle is also
specified and contains the CWBOBJ_KEY_OUTQUE parameter key, this
parameter is ignored.
cwbOBJ_ParmHandle *parmListHandle - input
Optional. A pointer to a valid parameter list object handle that contains
parameters for starting the writer.
cwbOBJ_ObjHandle *writerHandle - output
Optional. A pointer to a writer object handle that will be filled in upon
successful return from this API. If this parameter is specified, the caller must
call cwbOBJ_DeleteObjHandle() to release resources allocated for this writer
handle.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid.
CWB_INVALID_PARAMETER
Invalid parameter specified.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: Calling this API causes the writer job to be submitted to run. The writer
job may fail to start even though this API returns successfully (the job may be

812 Client Access Express Programming


successfully submitted, but fail to start). This is the behavior of the STRPRTWTR
command on the AS/400. The following parameter keys may be set in the
parmListHandle object:
CWBOBJ_KEY_ALIGN - Align page
CWBOBJ_KEY_ALWDRTPRT - Allow direct printing
CWBOBJ_KEY_AUTOEND - Automatically end writer (*YES,*NO)
CWBOBJ_KEY_DRWRSEP - Drawer to use for separators
CWBOBJ_KEY_FILESEP - Number of file separators
CWBOBJ_KEY_FORMTYPE - Name of the form to be used
CWBOBJ_KEY_JOBNAME - Name of the job that created file
CWBOBJ_KEY_JOBNUMBER - Number of the job that created file
CWBOBJ_KEY_USER - Name of the user that created file
CWBOBJ_KEY_FORMTYPEMSG - Form type message option
CWBOBJ_KEY_MSGQUELIB - Message queue library
CWBOBJ_KEY_MSGQUE - Message queue name
CWBOBJ_KEY_OUTQUELIB - Output queue library
CWBOBJ_KEY_OUTQUE - Output queue
CWBOBJ_KEY_SPOOLFILE - Spool file name
CWBOBJ_KEY_SPLFNUM - Spool file number
CWBOBJ_KEY_WTRSTRPAGE - Page to start the writer on
CWBOBJ_KEY_WTREND - When to end the writer
CWBOBJ_KEY_WRITER - Writer job name
CWBOBJ_KEY_WTRINIT - When to initialize the printer device

Chapter 3. Express C/C++ APIs 813


cwbOBJ_WriteNewSplF
Purpose: Writes data into a newly created spooled file.

Syntax:

unsigned int CWB_ENTRY cwbOBJ_WriteNewSplF(


cwbOBJ_ObjHandle newSplFHandle,
const char *data,
unsigned long dataLen,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbOBJ_ObjHandle newSplFHandle - input
New spooled file handle. This is the handle passed back on the
cwbOBJ_CreateNewSplF() API.
const char *data - input
Pointer to the data buffer that will be written into the spooled file.
unsigned long ulDataLen - input
Length of the data to be written.
cwbSV_ErrHandle errorHandle - output
Optional, may be 0. Any returned messages will be written to this object. It is
created with the cwbSV_CreateErrHandle() API. The messages may be
retrieved through the cwbSV_GetErrText() API. If the parameter is set to zero,
no messages will be retrievable.

Return Codes: The following list shows common return values.


CWB_NO_ERROR
Successful completion.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory.
CWB_INVALID_HANDLE
Handle is not valid spooled file handle.
CWBOBJ_RC_HOST_ERROR
Host error occurred. Text may be in errorHandle.

Usage: None

814 Client Access Express Programming


Example: Using Express AS/400 Objects APIs
The following example shows a typical calling sequence for retrieving a list of
spooled files:
/********************************************************/
/* List all spooled files for the current user and */
/* display them to the user. */
/********************************************************/

#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h>

#include <stdio.h>
#include "CWBOBJ.H"
main(int argc, char *argv[ ], char *envp[ ])
{
cwbOBJ_ListHandle listHandle;
cwbOBJ_ObjHandle splFHandle;
unsigned int ulRC;
unsigned long ulListSize, ulObjPosition, ulBytesNeeded;
cwbOBJ_KeyID keysWanted[] = { CWBOBJ_KEY_SPOOLFILE,
CWBOBJ_KEY_USER };
unsigned long ulNumKeysWanted = sizeof(keysWanted)/sizeof(*keysWanted);
char szSplFName[11];
char szUser[11];

ulRC = cwbOBJ_CreateListHandle(_TEXT("ANYAS400"),
CWBOBJ_LIST_SPLF,
&listHandle,
0);
if (ulRC == CWB_OK)
{

/* Set up the filter for the list to be opened with */


/* NOTE: this is just for example, the user defaults */
/* to *CURRENT, so this isn't really needed. */

cwbOBJ_SetListFilter(listHandle, CWBOBJ_KEY_USER,
_TEXT("*CURRENT"), 0);

/* Optionally call to cwbOBJ_SetListAttrsToRetrieve to*/


/* make walking the list faster */
ulRC = cwbOBJ_SetListAttrsToRetrieve(listHandle,
ulNumKeysWanted,
keysWanted,
0);

/* open the list - this will build the list of spooled*/


/* files. */
ulRC = cwbOBJ_OpenList(listHandle,
CWBOBJ_LIST_OPEN_SYNCH,
0);
if (ulRC == CWB_OK)
{
/* Get the number of items that are in the list */
ulRC = cwbOBJ_GetListSize(listHandle,
&ulListSize,
(cwbOBJ_List_Status *)0,
0);
if (ulRC == CWB_OK)
{

/* walk through the list of items, displaying */


/* each item to the user */

Chapter 3. Express C/C++ APIs 815


ulObjPosition = 0;
while (ulObjPosition < ulListSize)
{
/*******************************************/
/* Get a handle to the next spooled file in*/
/* the list. This handle is valid while */
/* the list is open. If you want to */
/* maintain a handle to the spooled file */
/* after the list is closed, you could call*/
/* cwbOBJ_CopyObjHandle() after this call. */
/*******************************************/
ulRC = cwbOBJ_GetObjHandle(listHandle,
ulObjPosition,
&splFHandle,
0);
if (ulRC == CWB_OK)
{

/****************************************/
/* call cwbOBJ_GetObjAttr() to get info */
/* about this spooled file. May also */
/* call spooled file specific APIs */
/* with this handle, such as */
/* cwbOBJ_HoldSplF(). */
/****************************************/

ulRC = cwbOBJ_GetObjAttr(splFHandle,
CWBOBJ_KEY_SPOOLFILE,
(void *)szSplFName,
sizeof(szSplFName),
&ulBytesNeeded,
NULL,
0);
if (ulRC == CWB_OK)
{
ulRC = cwbOBJ_GetObjAttr(splFHandle,
CWBOBJ_KEY_USER,
(void *)szUser,
sizeof(szUser),
&ulBytesNeeded,
NULL,
0);
if (ulRC == CWB_OK)
{
printf("%3u: %11s %s\n",
ulObjPosition, szSplFName, szUser);
} else {
/* ERROR on GetObjAttr! */
}
} else {
/* ERROR on GetObjAttr! */
}
/* free this object handle */
cwbOBJ_DeleteObjHandle(splFHandle, 0);
} else {
/* ERROR on GetObjHandle! */
}
ulObjPosition++;
}
} else {
/* ERROR on GetListSize! */
}
cwbOBJ_CloseList(listHandle, 0);
} else {
/* ERROR on OpenList! */

816 Client Access Express Programming


}

cwbOBJ_DeleteListHandle(listHandle, 0);
}

Express Remote Command/Distributed Program Call APIs


Express Remote Command APIs:
The Client Access Express Remote Command application programming
interfaces (APIs) enable your PC application to start non-interactive
commands on the AS/400 system and to receive completion messages from
these commands. The AS/400 command can send up to ten reply
messages.
Express Distributed Program Call API:
The Client Access Express Distributed Program Call API allows your PC
application to call any AS/400 program or command. Input, output and
in/out parameters are handled through this function. If the program runs
correctly, the output and the in/out parameters will contain the data
returned by the AS/400 program that was called. If the program fails to
run correctly on the AS/400, the program can send up to ten reply
messages.
The Express Remote Command/Distributed Program Call APIs allow the
PC application programmer to access functions on the AS/400 system.
User program and system commands can be called without requiring an
emulation session. A single AS/400 program serves commands and
programs, so only one AS/400 job is started for both.
Express Remote Command/Distributed Program Call APIs required files:

Header file Import library Dynamic Link Library


cwbrc.h cwbapi.lib cwbrc.dll

Express Toolkit:
The Client Access Express Toolkit provides Remote Command and
Distributed Program Call documentation, access to the cwbrc.h header file,
and links to sample programs. To access this information, open the Express
Toolkit and select either Remote Command or Distributed Program Call
—> C/C++ APIs.
Express Remote Command/Distributed Program Call APIs topics:
v “Typical use of Express Remote Command/Distributed Program Call
APIs” on page 818
v Express Remote Command/Distributed Program Call APIs listing
v “Example: Using Remote Express Command/Distributed Program Call
APIs” on page 839
v “Express Remote Command/Distributed Program Call APIs return
codes” on page 27
Related topics:
v “AS/400 system name formats for APIs” on page 10
v “OEM, ANSI, and Unicode considerations” on page 10

Chapter 3. Express C/C++ APIs 817


Typical use of Express Remote Command/Distributed Program
Call APIs
An application that uses the Express Remote Command/Distributed Program Call
function uses objects. Each of these objects are identified to the application through
a handle:
System object
This represents an AS/400 system. The handle to the system object is
provided to the StartSysEx function to identify the system on which the
commands or APIs will be run.
Command request object
This represents the request to the AS/400 system. Commands can be run
and programs can be called on this object.

Note: The Command Request object previously was known as the ″system
object″ in Client Access.
Program object
This represents the AS/400 program. Parameters can be added, and the
program can be sent to the system to run the program.

There is not a separate object for commands. The command string is sent directly
to the command request.

An application that uses the Remote Command/Distributed Program Call APIs


first creates a system object by calling the “cwbCO_CreateSystem” on page 56
function. This function returns a handle to the system object. This handle then is
used with the “cwbRC_StartSysEx” on page 836 function to start a conversation
with the AS/400 system. The cwbRC_StartSysEx function returns a handle to the
command request. Use the command request handle to call programs or to run
commands. The APIs that are associated with the command request object are:
“cwbRC_StartSysEx” on page 836
“cwbRC_CallPgm” on page 822
“cwbRC_RunCmd” on page 831
“cwbRC_StopSys” on page 838

A command is a character string that is to be run on the AS/400 system. Because it


is a simple object (a character string) no additional object will need to be created in
order to run a command. The command string simply is a parameter on the
cwbRC_RunCmd API.

A program is a complex object that is created with the cwbRC_CreatePgm API,


which requires the program name and the library name as parameters. The handle
that is returned by this function can have 0 to 35 parameters associated with it.
Parameters are added with the cwbRC_AddParm function. Parameters types can
be input, output, or input/output. These parameters need to be in a format with
which the AS/400 program can work (that is, one for which no data transform or
data conversion will occur). When all of the parameters have been added, the
program handle is used with the cwbRC_CallPgm API on the command request
object. The APIs that are associated with the program object are:
“cwbRC_CreatePgm” on page 823
“cwbRC_AddParm” on page 820
“cwbRC_GetParmCount” on page 829
“cwbRC_GetParm” on page 828

818 Client Access Express Programming


“cwbRC_GetPgmName” on page 830
“cwbRC_GetLibName” on page 827
“cwbRC_SetParm” on page 833
“cwbRC_SetPgmName” on page 835
“cwbRC_SetLibName” on page 832
“cwbRC_DeletePgm” on page 824

Express Remote Command/Distributed Program Call APIs


listing
The following Express Remote Command/Distributed Program Call APIs are listed
alphabetically, and are grouped according to function:

Express Remote Command/Distributed Program


Function Call APIs
Access the remote command server cwbRC_StartSysEx
program on the AS/400 system.The cwbRC_GetClientCCSID
request handle is used to run cwbRC_GetHostCCSID
commands and to call programs. cwbRC_StopSys
Run an AS/400 command. cwbRC_RunCmd
Access programs and their parameters. cwbRC_CreatePgm
cwbRC_AddParm
cwbRC_CallPgm
cwbRC_GetParmCount
cwbRC_GetParm
cwbRC_GetPgmName
cwbRC_GetLibName
cwbRC_SetParm
cwbRC_SetPgmName
cwbRC_SetLibName
cwbRC_DeletePgm

Chapter 3. Express C/C++ APIs 819


cwbRC_AddParm
Purpose: Add a parameter to the program that is identified by the handle. This
function should be called once for each parameter that is to be added to the
program. When the program is called the parameters will be in the same order that
they are added using this function.

Syntax:
unsigned int CWB_ENTRY cwbRC_AddParm(
cwbRC_PgmHandle program,
unsigned short type,
unsigned long length,
const unsigned char *parameter);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
unsigned short type - input
The type of parameter this is. Use one of the defined parameter types:
CWBRC_INPUT, CWBRC_OUTPUT, CWBRC_INOUT. If you want to
automatically convert between local CCSID and host CCSID, add the
appropriate convert flag to this field with a bitwise, or use one of the defined
parameter types:
CWBRC_TEXT_CONVERT
CWBRC_TEXT_CONVERT_INPUT
CWBRC_TEXT_CONVERT_OUTPUT
The last two types are intended for use with CWBRC_INOUT when conversion
is only needed in one direction.
unsigned long length - input
The length of the parameter. If this is an CWBRC_OUTPUT parameter, the
length should be the length of the buffer where the returned parameter will be
written.
const unsigned char * parameter - input
Pointer to a buffer that will contain: the value if the type is CWBRC_INPUT or
CWBRC_INOUT, or the place where the returned parameter is to be written if
the type is CWBRC_OUTPUT or CWBRC_INOUT.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWBRC_INVALID_TYPE
Invalid type specified.
CWBRC_INVALID_PARM_LENGTH
Invalid parameter length.
CWBRC_INVALID_PARM
Invalid parameter.

820 Client Access Express Programming


Usage: Parameter data is assumed to be binary. No conversion will be performed
on the parameter data unless one of the conversion flags is set. For example:
cwbRC_AddParm( hPgm,
CWBRC_INOUT | CWBRC_TEXT_CONVERT_OUTPUT,
bufferSize,
buffer );

will use the buffer as is to send to the host, and will convert the output (eg to
ASCII) before putting the result into the buffer.

Chapter 3. Express C/C++ APIs 821


cwbRC_CallPgm
Purpose: Calls the program identified by the handle. The return code will indicate
the success or failure of the program. Additional messages can be returned by
using the message handle that is returned.

Syntax:

unsigned int CWB_ENTRY cwbRC_CallPgm(


cwbRC_SysHandle system,
cwbRC_PgmHandle program,
cwbSV_ErrHandle msgHandle);

Parameters:
cwbRC_SysHandle system - input
Handle that was returned by a previous call to the cwbRC_StartSysEx function.
It identifies the AS/400 system.
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object. object.
cwbSV_ErrHandle msgHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrTextIndexed API. If the parameter is set to zero, no messages
will be retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWBRC_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBRC_USER_EXIT_ERROR
Error in user exit program.
CWBRC_PROGRAM_NOT_FOUND
Program not found.
CWBRC_PROGRAM_ERROR
Error when calling program.

Usage: None

822 Client Access Express Programming


cwbRC_CreatePgm
Purpose: This function creates a program object given a program and library
name. The handle that is returned can be used to add parameters to the program
and then call the program.

Syntax:

unsigned int CWB_ENTRY cwbRC_CreatePgm(


const char *programName,
const char *libraryName,
cwbRC_PgmHandle *program);

Parameters:
const char *programName - input
Pointer to an ASCIIZ string that contains the name of the program that you
want to call.
const char *libraryName - input
Pointer to an ASCIIZ string that contains the name of the library where the
program resides.
cwbRC_PgmHandle * program - output
Pointer to a cwbRC_PgmHandle where the handle of the program will be
returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_PROGRAM_NAME
Program name is too long.
CWBRC_LIBRARY_NAME
Library name is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: You should create a separate program object for each program you want
to call on the AS/400. You can use the functions described in this file to change the
values of the parameters being sent to the program, but cannot change the number
of parameters being sent.

Chapter 3. Express C/C++ APIs 823


cwbRC_DeletePgm
Purpose: This function deletes the program object that is identified by the handle
provided.

Syntax:

unsigned int CWB_ENTRY cwbRC_DeletePgm(


cwbRC_PgmHandle program);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBRC_INVALID_PROGRAM
Invalid program handle.

Usage: None.

824 Client Access Express Programming


cwbRC_GetClientCCSID
Purpose: Get the coded character set identifier (CCSID) associated with the
current process. This CCSID along with the host CCSID can be used to convert
EBCDIC data returned by some AS/400 program to ASCII data that can be used in
client applications.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetClientCCSID(


cwbRC_SysHandle system,
unsigned long *clientCCSID);

Parameters:
cwbRC_SysHandle system - input
Handle that was returned by a previous call to the cwbRC_StartSysEx function.
It identifies the AS/400 system.
unsigned long * clientCCSID - output
Pointer to an unsigned long where the client CCSID will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.

Usage: See related APIs in the CWBNLCNV.H file.

Chapter 3. Express C/C++ APIs 825


cwbRC_GetHostCCSID
Purpose: Get the coded character set identifier (CCSID) associated with the
AS/400 server job. This CCSID along with the client CCSID can be used to convert
EBCDIC data returned by some AS/400 programs to ASCII data that can be used
in client applications.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetHostCCSID(


cwbRC_SysHandle system,
unsigned long *hostCCSID);

Parameters:
cwbRC_SysHandle system - input
Handle that was returned by a previous call to the cwbRC_StartSysEx function.
It identifies the AS/400 system.
unsigned long * hostCCSID - output
Pointer to an unsigned long where the host CCSID will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.

Usage: See related APIs in the CWBNLCNV.H file.

826 Client Access Express Programming


cwbRC_GetLibName
Purpose: Get the name of the library that was used when creating this program
object.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetLibName(


cwbRC_PgmHandle program,
char *libraryName);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
char * libraryName - output
Pointer to a ten character buffer where the name of the library will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate the temporary buffer.
CWB_API_ERROR
General API failure.

Usage: None

Chapter 3. Express C/C++ APIs 827


cwbRC_GetParm
Purpose: Retrieve the parameter identified by the index. The index will range
from 0 to the total number of parameters - 1. This number can be obtained by
calling the cwbRC_GetParmCount API.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetParm(


cwbRC_PgmHandle program,
unsigned short index,
unsigned short *type,
unsigned long *length,
unsigned char **parameter);

Parameters:
cwbRC_PgmHandle handle - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
unsigned short index - input
The number of the specific parameter in this program that should be retrieved.
This index is zero-based.
unsigned short * type - output
Pointer to the type of parameter this is. The value will be one of the defined
parameter types:
CWBRC_INPUT
CWBRC_OUTPUT
CWBRC_INOUT
unsigned long * length - input
Pointer to the length of the parameter.
unsigned char * * parameter - output
Pointer to a buffer that will contain the address of the actual parameter.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWBRC_INDEX_RANGE_ERROR
Index is out of range.

Usage: None

828 Client Access Express Programming


cwbRC_GetParmCount
Purpose: Get the number of parameters for this program object.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetParmCount(


cwbRC_PgmHandle program,
unsigned short *count);

Parameters:
cwbRC_PgmHandle handle - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
unsigned short * count - output
Pointer to an unsigned short where the parameter count will be written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_PROGRAM
Invalid program handle.

Usage: None

Chapter 3. Express C/C++ APIs 829


cwbRC_GetPgmName
Purpose: Get the name of the program that was used when creating this program.

Syntax:

unsigned int CWB_ENTRY cwbRC_GetPgmName(


cwbRC_PgmHandle program,
char *programName);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
char * programName - output
Pointer to a ten character buffer where the name of the program will be
written.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate the temporary buffer.
CWB_API_ERROR
General API failure.

Usage: None

830 Client Access Express Programming


cwbRC_RunCmd
Purpose: Issues the command on the system identified by the handle. The return
code will indicate success or failure of the command. Additional messages can be
returned by using the message handle that is returned.

Syntax:

unsigned int CWB_ENTRY cwbRC_RunCmd(


cwbRC_SysHandle system,
const char *commandString,
cwbSV_ErrHandle msgHandle);

Parameters:
cwbRC_SysHandle system - input
Handle that was returned by a previous call to the cwbRC_StartSysEx function.
It identifies the AS/400 system.
const char *commandString - input
Pointer to a string that contains the command to be issued on the AS/400
system. This is an ASCIIZ string.
cwbSV_ErrHandle msgHandle - output
Any messages returned from the AS/400 will be written to this object. It is
created with the cwbSV_CreateErrHandle API. The messages may be retrieved
through the cwbSV_GetErrTextIndexed API. If the parameter is set to zero, no
messages will be retrieved.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_POINTER
Bad or NULL pointer.
CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.
CWBRC_REJECTED_USER_EXIT
Command rejected by user exit program.
CWBRC_USR_EXIT_ERROR
Error in user exit program.
CWBRC_COMMAND_FAILED
Command failed.
CWBRC_COMMAND_TOO_LONG
Command string is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: None

Chapter 3. Express C/C++ APIs 831


cwbRC_SetLibName
Purpose: Set the name of the library for this program object.

Syntax:

unsigned int CWB_ENTRY cwbRC_SetLibName(


cwbRC_PgmHandle program,
const char *libraryName);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
const char *libraryName - input
Pointer to an ASCIIZ string that contains the name of the library where the
program resides.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWBRC_LIBRARY_NAME
Library name is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: Use this function to change the name of the name of the library that
contains the program you want to call. This function should not be used to call a
different program with different parameters.

832 Client Access Express Programming


cwbRC_SetParm
Purpose: Set the parameter value identified by the index. The index will range
from 0 to the total number of parameters - 1. This number can be obtained by
calling the cwbRC_GetParmCount API. Note that this function is to be used to
change a parameter. Use cwbRC_AddParm to create the parameter.

Syntax:

unsigned int CWB_ENTRY cwbRC_SetParm(


cwbRC_PgmHandle program,
unsigned short index,
unsigned short type,
unsigned long length,
const unsigned char *parameter);

Parameters:
cwbRC_PgmHandle handle - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
unsigned short index - input
The number of the specific parameter in this program that should be changed.
This index is zero-based.
unsigned short type - input
The type of parameter this is. Use one of the defined parameter types:
CWBRC_INPUT
CWBRC_OUTPUT
CWBRC_INOUT
If you want to automatically convert between local CCSID and host CCSID,
add the appropriate convert flag to this field with a bitwise-OR. Use one of the
defined parameter types:
CWBRC_TEXT_CONVERT
CWBRC_TEXT_CONVERT_INPUT
CWBRC_TEXT_CONVERT_OUTPUT
The latter two are intended for use with CWBRC_INOUT when conversion is
only needed in one direction.
unsigned long length - input
The length of the parameter. If this is an CWBRC_OUT parameter, the length
should be the length of the buffer where the returned parameter will be
written.
const unsigned char * parameter - input
Pointer to a buffer that will contain the value if the type is CWBRC_INPUT or
CWBRC_INOUT, or the place where the return parameter is to be written if
the type is CWBRC_OUTPUT or CWBRC_INOUT.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBRC_INVALID_PROGRAM
Invalid program handle.

Chapter 3. Express C/C++ APIs 833


CWBRC_INVALID_TYPE
Invalid type specified.
CWBRC_INVALID_PARM_LENGTH
Invalid parameter length.
CWBRC_INVALID_PARM
Invalid parameter.

Usage: Parameter data is assumed to be binary. No conversion will be performed


on the parameter data unless one of the conversion flags is set. For example:
cwbRC_SetParm( hPgm,
CWBRC_INOUT | CWBRC_TEXT_CONVERT_OUTPUT,
bufferSize,
buffer );

will use the buffer as is to send to the host, and will convert the output (for
example, to ASCII) before putting the result into the buffer.

834 Client Access Express Programming


cwbRC_SetPgmName
Purpose: Set the name of the program for this program object.

Syntax:

unsigned int CWB_ENTRY cwbRC_SetPgmName(


cwbRC_PgmHandle program,
const char *programName);

Parameters:
cwbRC_PgmHandle program - input
Handle that was returned by a previous call to the cwbRC_CreatePgm API. It
identifies the program object.
const char *programName - input
Pointer to an ASCIIZ string that contains the name of the program that you
want to call.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWBRC_INVALID_PROGRAM
Invalid program handle.
CWBRC_PROGRAM_NAME
Program name is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

Usage: Use this function to change the name of the program that you want to
call. This function should not be used to change the program object to call a
different program with different parameters.

Chapter 3. Express C/C++ APIs 835


cwbRC_StartSysEx
Purpose: This function starts a conversation with the specified system. If the
conversation is successfully started, a handle is returned. Use this handle with all
subsequent calls to issue commands or call programs. When the conversation no
longer is needed, use the handle with the cwbRC_StopSys API to end the
conversation. The cwbRC_StartSysEx API may be called multiple times within an
application. If the same system object handle is used on StartSysEx calls, only one
conversation with the AS/400 will be started. If you want multiple conversations
to be active, you must call StartSysEx multiple times, specifying different system
object handles.

Syntax:

unsigned int CWB_ENTRY cwbRC_StartSysEx(


const cwbCO_SysHandle systemObj,
cwbRC_SysHandle *request);

Parameters:
const cwbCO_SysHandle systemObj - input
Handle to an existing system object of the system on which you want
programs and commands to be run.
cwbRC_SysHandle *request - output
Pointer to a cwbRC_SysHandle where the handle of the command request will
be returned.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_COMMUNICATIONS_ERROR
A communications error occurred.
CWB_SERVER_PROGRAM_NOT_FOUND
AS/400 application not found.
CWB_HOST_NOT_FOUND
AS/400 system inactive or does not exist.
CWB_SECURITY_ERROR
A security error has occurred.
CWB_LICENSE_ERROR
A license error has occurred.
CWB_CONFIG_ERROR
A configuration error has occurred.
CWBRC_SYSTEM_NAME
System name is too long.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory; may have failed to allocate temporary buffer.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input Unicode characters have no representation in the
codepage being used.
CWB_API_ERROR
General API failure.

836 Client Access Express Programming


Usage: None.

Chapter 3. Express C/C++ APIs 837


cwbRC_StopSys
Purpose: This function stops a conversation with the system specified by the
handle. This handle can no longer be used to issue program calls or commands.

Syntax:

unsigned int CWB_ENTRY cwbRC_StopSys(


cwbRC_SysHandle system);

Parameters:
cwbRC_SysHandle system - input
Handle that was returned by a previous call to the cwbRC_StartSysEx function.
It identifies the AS/400 system.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBRC_INVALID_SYSTEM_HANDLE
Invalid system handle.

Usage: None

838 Client Access Express Programming


Example: Using Remote Express Command/Distributed
Program Call APIs
#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h>

// Include the necessary RC/DPC Classes


#include <stdlib.h>
#include <iostream.h>
#include <TCHAR.H>
#include "cwbrc.h"
#include "cwbcosys.h"
/**********************************************************************/

void main()
{
cwbCO_SysHandle system;
cwbRC_SysHandle request;
cwbRC_PgmHandle program;

// Create the system object


if ( (cwbCO_CreateSystem("AS/400SystemName",&system)) != CWB_OK )
return;

// Start the system


if ( (cwbRC_StartSysEx(system,&request)) != CWB_OK )
return;

// Call the command to create a library


char* cmd1 = "CRTLIB LIB(RCTESTLIB) TEXT('RC TEST LIBRARY')";
if ( (cwbRC_RunCmd(request, cmd1, 0)) != CWB_OK )
return;

cout << "Created Library" << endl;

// Call the command to delete a library


char* cmd2 = "DLTLIB LIB(RCTESTLIB)";
if ( (cwbRC_RunCmd(request, cmd2, 0)) != CWB_OK )
return;

cout << "Deleted Library" << endl;

// Create a program object to create a user space


if ( cwbRC_CreatePgm(_TEXT("QUSCRTUS"),
_TEXT("QSYS"),
&program) != CWB_OK )
return;

// Add the parameters


// name is DPCTESTSPC/QGPL
unsigned char name[20] = {0xC4,0xD7,0xC3,0xE3,0xC5,0xE2,0xE3,0xE2,0xD7,0xC3,
0xD8,0xC7,0xD7,0xD3,0x40,0x40,0x40,0x40,0x40,0x40};

// extended attribute is not needed


unsigned char attr[10] = {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};

// initial size is 100 bytes


unsigned long size = 0x64000000;

// initial value is blank


unsigned char init = 0x40;

// public authority is CHANGE


unsigned char auth[10] = {0x5C,0xC3,0xC8,0xC1,0xD5,0xC7,0xC5,0x40,0x40,0x40};

Chapter 3. Express C/C++ APIs 839


// description is DPC TEMP SPACE
unsigned char desc[50] = {0xC4,0xD7,0xC3,0x40,0xE3,0xC5,0xD4,0xD7,0x40,0xE2,
0xD7,0xC1,0xC3,0xC5,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};

if ( cwbRC_AddParm(program, CWBRC_INPUT, 20, name) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 10, attr) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 4, (unsigned char*)&size) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 1, &init) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 10, auth) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 50, desc) != CWB_OK)


return;

// Call the program


if ( cwbRC_CallPgm(request, program, 0) != CWB_OK )
return;

cout << "Created User Space" << endl;

// Delete the program


if ( cwbRC_DeletePgm(program) != CWB_OK )
return;

// Create a program object to delete a user space


if ( cwbRC_CreatePgm(_TEXT("QUSDLTUS"),
_TEXT("QSYS"),
&program) != CWB_OK )
return;

// Add the parameters


// error code structure will not be used
unsigned long err = 0x00000000;

if ( cwbRC_AddParm(program, CWBRC_INPUT, 20, name) != CWB_OK)


return;

if ( cwbRC_AddParm(program, CWBRC_INOUT, 4, (unsigned char*)&err) != CWB_OK)


return;

// Call the program


if ( cwbRC_CallPgm(request, program, 0) != CWB_OK )
return;

// Delete the program


if ( cwbRC_DeletePgm(program) != CWB_OK )
return;

cout << "Deleted User Space" << endl;

// Stop the system


if ( cwbRC_StopSys(request) != CWB_OK )
return;

// Delete the system object

840 Client Access Express Programming


if ( cwbCO_DeleteSystem(system) != CWB_OK )
return;

Express Serviceability APIs


The Client Access Express Serviceability application programming interfaces (APIs)
allow you to log service file messages and events within your program. A set of
APIs allows you to read the records from the service files that are created. These
APIs allow you to write a customized service-file browser.

The following general categories of Express Serviceability API functions are


provided:
v Writing message text to the History log
v Writing Trace entries to the Trace file
v Reading service files
v Retrieving message text that is associated with error handles
Why you should use Express Serviceability APIs:
The Express Serviceability APIs provide an efficient means of adding
message logging and trace points to your code. Incorporate these functions
into programs that are shipped as part of your product, and use them to
help debug programs that are under development. The file structure
supports multiple programs (that are identified by unique product and
component strings) logging to the same files simultaneously. This provides
a complete picture of logging activity on the client workstation.
Express Serviceability APIs required files:

Header file Import library Dynamic Link Library


cwbsv.h cwbapi.lib cwbsv.dll

Express Toolkit:
The Client Access Express Toolkit provides Serviceability documentation,
access to the cwbsv.h header file, and links to sample programs. To access
this information, open the Express Toolkit and select Error Handling —>
C/C++ APIs.
Express Serviceability APIs topics:
v “History log and trace files”
v “Error handles” on page 843
v “Typical use of Serviceability APIs” on page 843
v Express Serviceability APIs listing
v “Example: Using Express Serviceability APIs” on page 910
v “Express Serviceability APIs return codes” on page 28

History log and trace files


History log:
The log functions allow you to write message text the Client Access
Express History Log. The message text needs to be displayable ASCII
character data.
Client Access Express has instrumented all of its programs to log messages
to the Client Access Express History Log. Messages also are logged by the
DLLs that are supplied with the product.

Chapter 3. Express C/C++ APIs 841


The History Log is a file where message text strings are logged through the
cwbSV_LogMessageText API. The log provides a history of activity that
has taken place on the client workstation.
Trace files:
The trace functions allow you to log low-level events that occur as your
program runs. For example, you want to track various return codes that
were received from calling other functions. If your program is sending and
receiving data, you may want to log the significant fields of the data (for
example, function byte or bytes, and data length) to aid in debugging if
something goes wrong. Use the Detailed data trace function
(cwbSV_LogTraceData) to accomplish this.
Another form of trace, the Entry Point trace function, allows you to track
entry into and exit from your routines. Client Access Express defines two
different types of entry point trace points:
API trace point:
Use the API (application programming interface) trace point to
track entry and exit from routines that you externalize to other
programs.
SPI trace point:
Use the SPI (system programming interface) trace point to track
entry and exit from key internal routines of the program that you
want to trace.

The key piece of information that is provided on the APIs is a one-byte


eventID. It allows you to identify which API or SPI is being entered or
exited. Data such as input values can be traced on entry, as well as tracing
output values on exit from a routine. These trace functions are intended to
be used in pairs (for example, cwbSV_LogAPIEntry and
cwbSV_LogAPIExit) in the routines that utilize them. These types of trace
points provide a flow of control through the code.

Client Access Express has instrumented the procedural APIs described in


this topic with Entry/Exit API trace points. When one of these procedural
APIs is called, entry and exit trace points are logged to the Entry Point
trace file if tracing is active. Client Access The Entry/Exit SPI trace logs
internal calling sequences. The Detailed data trace function logs data which
is useful in debugging problems.

Client Access Express supports the following types of traces:


Detailed (Data):
Allows you to trace a buffer of information at a point in your code
via the cwbSV_LogTraceData API. This buffer can be a mixture of
ASCII and/or binary values (for example, C-struct). The data is
logged in binary form.
Entry/Exit (API):
A specialized form of trace which allows you to trace entry into
and exit from your externalized routines via the
cwbSV_LogAPIEntry and cwbSV_LogAPIExit APIs.
Entry/Exit (SPI):
A specialized form of trace that allows you to trace entry into and
exit from your key internal routines by using the
cwbSV_LogSPIEntry and cwbSV_LogSPIExit APIs.

842 Client Access Express Programming


Error handles
The error handle functions allow you to create an error handle
(cwbSV_CreateErrHandle) to use on Express APIs that support it. If an error occurs
(a non-zero return code) on the Express API call, you can call other error handle
functions to retrieve information such as:
v The number of error messages (cwbSV_GetErrCount) that are associated with
the return code
v The message text (cwbSV_GetErrTextIndexed) for each of the error messages

Typical use of Serviceability APIs


History log:
Serviceability APIs provide a tracking mechanism for activity that is taking
place on the client workstation. As a result, you can use the
message-logging APIs to log messages to the Client Access Express History
Log. Examples of messages to log include an indication that your
application was started, and other significant events. For example, a log
message may indicate that a file successfully was transferred to the
AS/400, a database query failed for some reason, or that a job was
submitted for printing.
The product and component strings that you provide when you are using
the Serviceability APIs allow your messages and events to be distinguished
from other entries in the service files. The recommended hierarchy is to
define a product ID, with one or many component IDs defined under it.
Error handles:
Use the error-handle parameter on Express C/C++ APIs to retrieve
message text that is associated with a failure return code. This enables your
application to display the message text, instead of providing your own text
for the set of Client Access return codes.

Express Serviceability APIs listing


Note: Distinguish between API & SPI trace points:
Definitions:
- API (Application Programming Interface)
- SPI (System Programming Interface)

The recommended convention is that API entry/exit trace points should be


put in routines that you externalize (export) to your users. Use SPI
entry/exit trace points in key internal (non-exported) routines that you want
to trace.

The following Express Serviceability APIs are listed alphabetically, and are grouped
according to function:

Function Express Serviceability APIs


Writing message text to a history log cwbSV_CreateMessageTextHandle
cwbSV_DeleteMessageTextHandle
cwbSV_LogMessageText
cwbSV_SetMessageComponent
cwbSV_SetMessageProduct
cwbSV_SetMessageClass

Chapter 3. Express C/C++ APIs 843


Function Express Serviceability APIs
Writing trace data to a detail trace file cwbSV_CreateTraceDataHandle
cwbSV_DeleteTraceDataHandle
cwbSV_LogTraceData
cwbSV_SetTraceComponent
cwbSV_SetTraceProduct
Writing trace points to an entry/exit trace cwbSV_CreateTraceAPIHandle
file cwbSV_CreateTraceSPIHandle
cwbSV_DeleteTraceAPIHandle
cwbSV_DeleteTraceSPIHandle
cwbSV_LogAPIEntry
cwbSV_LogAPIExit
cwbSV_LogSPIEntry
cwbSV_LogSPIExit
cwbSV_SetAPIComponent
cwbSV_SetAPIProduct
cwbSV_SetSPIComponent
cwbSV_SetSPIProduct
Reading service files cwbSV_ClearServiceFile
cwbSV_CloseServiceFile
cwbSV_GetMaxRecordSize
cwbSV_GetRecordCount
cwbSV_GetServiceFileName
cwbSV_OpenServiceFile
Reading service file records cwbSV_CreateServiceRecHandle
cwbSV_DeleteServiceRecHandle
cwbSV_ReadNewestRecord
cwbSV_ReadNextRecord
cwbSV_ReadOldestRecord
cwbSV_ReadPrevRecord
Reading service record header information cwbSV_GetComponent
cwbSV_GetDateStamp
cwbSV_GetProduct
cwbSV_GetServiceType
cwbSV_GetTimeStamp
Reading history log service records cwbSV_GetMessageText
Reading detail trace file service records cwbSV_GetTraceData
Reading entry/exit trace file service records cwbSV_GetTraceAPIData
cwbSV_GetTraceAPIID
cwbSV_GetTraceAPIType
cwbSV_GetTraceSPIData
cwbSV_GetTraceSPIID
cwbSV_GetTraceSPIType
Retrieving message text associated with cwbSV_CreateErrHandle
error handles cwbSV_DeleteErrHandle
cwbSV_GetErrClass
cwbSV_GetErrClassIndexed
cwbSV_GetErrCount
cwbSV_GetErrFileName
cwbSV_GetErrFileNameIndexed
cwbSV_GetErrLibName
cwbSV_GetErrLibNameIndexed
cwbSV_GetErrSubstText
cwbSV_GetErrSubstTextIndexed
cwbSV_GetErrText
cwbSV_GetErrTextIndexed

844 Client Access Express Programming


cwbSV_ClearServiceFile
Purpose: Clears the service file that is identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_ClearServiceFile(


cwbSV_ServiceFileHandle serviceFile,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile()
function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_FILE_IO_ERROR
File could not be cleared.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

Chapter 3. Express C/C++ APIs 845


cwbSV_CloseServiceFile
Purpose: Closes the service file identified by the handle provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_CloseServiceFile(


cwbSV_ServiceFileHandle serviceFile,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile()
function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_FILE_IO_ERROR
File could not be closed.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

846 Client Access Express Programming


cwbSV_CreateErrHandle
Purpose: This function creates an error message object and returns a handle to it.
This error handle can be passed to Client Access/400 APIs that support it. If an
error occurs on one of these APIs, the error handle can be used to retrieve the error
messages text that is associated with the API error.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateErrHandle(


cwbSV_ErrHandle *errorHandle);

Parameters:
cwbSV_ErrHandle *errorHandle - input/output
Pointer to a cwbSV_ErrHandle where the handle will be returned.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as handle address.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: None

Chapter 3. Express C/C++ APIs 847


cwbSV_CreateMessageTextHandle
Purpose: This function creates a message text object and returns a handle to it.
This message handle can be used in your program to write message text to the
currently active history log. The message text is supplied in a buffer passed on the
cwbSV_LogMessageText() call.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateMessageTextHandle(


char *productID,
char *componentID,
cwbSV_MessageTextHandle *messageTextHandle);

Parameters:
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this message entry. Parameter is optional, if null, no productID is set.
NOTE: A maximum of CWBSV_MAX_PRODUCT_ID characters will be logged
for the product ID. Larger strings will be truncated.
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this message entry. Parameter is optional, if null, no componentID is
set. NOTE: A maximum of CWBSV_MAX_COMP_ID characters will be logged
for the component ID. Larger strings will be truncated.
cwbSV_MessageTextHandle * messageTextHandle - input/output
Pointer to a cwbSV_MessageTextHandle where the handle will be returned.
This handle should be used in subsequent calls to the message text functions.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: It is recommended that you set a unique product ID and component ID in


the message handle before using it to log message text. These ID’s will distinguish
your messages from other messages in the history log.

848 Client Access Express Programming


cwbSV_CreateServiceRecHandle
Purpose: This function creates a service record object and returns a handle to it.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateServiceRecHandle(


cwbSV_ServiceRecHandle *serviceRecHandle);

Parameters:
cwbSV_ServiceRecHandle * serviceRecHandle - input/output
Pointer to a cwbSV_ServiceRecordHandle where the handle will be returned.
This handle should be used in subsequent calls to the service record functions.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as handle address.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: This handle can be used in your program to read records from an open
service file and extract information from the record.

Chapter 3. Express C/C++ APIs 849


cwbSV_CreateTraceAPIHandle
Purpose: This function creates a trace API object and returns a handle to it. This
trace API handle can be used in your program to log entry to and exit from your
API entry points.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateTraceAPIHandle(


char *productID,
char *componentID,
cwbSV_TraceAPIHandle *traceAPIHandle);

Parameters:
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this message entry. Parameter is optional, if null, no productID is set.
NOTE: A maximum of CWBSV_MAX_PRODUCT_ID characters will be logged
for the product ID. Larger strings will be truncated.
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this message entry. Parameter is optional, if null, no componentID is
set. NOTE: A maximum of CWBSV_MAX_COMP_ID characters will be logged
for the component ID. Larger strings will be truncated.
cwbSV_TraceAPIHandle * traceAPIHandle - input/output
Pointer to a cwbSV_TraceAPIHandle where the handle will be returned. This
handle should be used in subsequent calls to the trace API functions.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: It is recommended that you set a unique product ID and component ID in


the trace data handle before using it to log trace entries. These ID’s will distinguish
your trace entries from other entries in the trace file.

850 Client Access Express Programming


cwbSV_CreateTraceDataHandle
Purpose: This function creates a trace data object and returns a handle to it. This
trace handle can be used in your program to log trace information to trace files.
The trace information is supplied in a buffer passed on cwbSV_LogTraceData()
calls.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateTraceDataHandle(


char *productID,
char *componentID,
cwbSV_TraceDataHandle *traceDataHandle);

Parameters:
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this message entry. Parameter is optional, if null, no productID is set.
NOTE: A maximum of CWBSV_MAX_PRODUCT_ID characters will be logged
for the product ID. Larger strings will be truncated.
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this message entry. Parameter is optional, if null, no componentID is
set. NOTE: A maximum of CWBSV_MAX_COMP_ID characters will be logged
for the component ID. Larger strings will be truncated.
cwbSV_TraceDataHandle * traceDataHandle - input/output
Pointer to a cwbSV_TraceDataHandle where the handle will be returned. This
handle should be used in subsequent calls to the trace data functions.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: It is recommended that you set a unique product ID and component ID in


the trace data handle before using it to log trace entries. These ID’s will distinguish
your trace entries from other entries in the trace file.

Chapter 3. Express C/C++ APIs 851


cwbSV_CreateTraceSPIHandle
Purpose: This function creates a trace SPI object and returns a handle to it. This
trace SPI handle can be used in your program to log entry to and exit from your
SPI entry points.

Syntax:

unsigned int CWB_ENTRY cwbSV_CreateTraceSPIHandle(


char *productID,
char *componentID,
cwbSV_TraceSPIHandle *traceSPIHandle);

Parameters:
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this message entry. Parameter is optional, if null, no productID is set.
NOTE: A maximum of CWBSV_MAX_PRODUCT_ID characters will be logged
for the product ID. Larger strings will be truncated.
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this message entry. Parameter is optional, if null, no componentID is
set. NOTE: A maximum of CWBSV_MAX_COMP_ID characters will be logged
for the component ID. Larger strings will be truncated.
cwbSV_TraceSPIHandle * traceSPIHandle - input/output
Pointer to a cwbSV_TraceSPIHandle where the handle will be returned. This
handle should be used in subsequent calls to the trace SPI functions.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: It is recommended that you set a unique product ID and component ID in


the trace data handle before using it to log trace entries. These ID’s will distinguish
your trace entries from other entries in the trace file.

852 Client Access Express Programming


cwbSV_DeleteErrHandle
Purpose: This function deletes the error message object that is identified by the
handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteErrHandle(


cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ErrHandle errorHandle - output
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should be made when the handle is no longer needed.

Chapter 3. Express C/C++ APIs 853


cwbSV_DeleteMessageTextHandle
Purpose: This function deletes the message text object that is identified by the
handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteMessageTextHandle(


cwbSV_MessageTextHandle messageTextHandle);

Parameters:
cwbSV_MessageTextHandle messageTextHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateMessageTextHandle() function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Unusable handle passed in on request.

Usage: This call should be made when the handle is no longer needed.

854 Client Access Express Programming


cwbSV_DeleteServiceRecHandle
Purpose: This function deletes the service record object that is identified by the
handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteServiceRecHandle(


cwbSV_ServiceRecHandle serviceRecHandle);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should be made when the handle is no longer needed.

Chapter 3. Express C/C++ APIs 855


cwbSV_DeleteTraceAPIHandle
Purpose: This function deletes the trace API object that is identified by the handle
that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteTraceAPIHandle(


cwbSV_TraceAPIHandle traceAPIHandle);

Parameters:
cwbSV_TraceAPIHandle traceAPIHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateTraceAPIHandle() function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should be made when the handle is no longer needed.

856 Client Access Express Programming


cwbSV_DeleteTraceDataHandle
Purpose: This function deletes the trace data object that is identified by the trace
handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteTraceDataHandle(


cwbSV_TraceDataHandle traceDataHandle);

Parameters:
cwbSV_TraceDataHandle traceDataHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateTraceDataHandle() function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should be made when the handle is no longer needed.

Chapter 3. Express C/C++ APIs 857


cwbSV_DeleteTraceSPIHandle
Purpose: This function deletes the trace SPI object that is identified by the handle
that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_DeleteTraceSPIHandle(


cwbSV_TraceSPIHandle traceSPIHandle);

Parameters:
cwbSV_TraceSPIHandle traceSPIHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateTraceSPIHandle() function.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should be made when the handle is no longer needed.

858 Client Access Express Programming


cwbSV_GetComponent
Purpose: Returns the component ID value for the service record object that is
identified by the handle provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetComponent(


cwbSV_ServiceRecHandle serviceRecHandle,
char *componentID,
unsigned long componentIDLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
char * componentID - input/output
Pointer to a buffer that will receive the component ID that is stored in the
record that is identified by the handle.
unsigned long componentIDLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_COMP_ID.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: The service record handle needs to be filled in by a call to a ″read″


function before calling this routine, otherwise a NULL string will be returned. This
function is valid for all service record types.

Chapter 3. Express C/C++ APIs 859


cwbSV_GetDateStamp
Purpose: Returns the date stamp (in localized format) for the service record that
is identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetDateStamp(


cwbSV_ServiceRecHandle serviceRecHandle,
char *dateStamp,
unsigned long dateStampLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
char * dateStamp - input/output
Pointer to a buffer that will receive the datestamp that is stored in the record
that is identified by the handle.
unsigned long dateStampLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_DATE_VALUE.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: The service record handle needs to be filled in by a call to a ″read″


function before calling this routine, otherwise a NULL string will be returned. This
function is valid for all service record types.

860 Client Access Express Programming


cwbSV_GetErrClass
Purpose: Returns the message class associated with the top-level (most recent)
error that is identified by the error handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrClass(


cwbSV_ErrHandle errorHandle,
unsigned long *errorClass);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.
unsigned long * errorClass - output
Pointer to a variable that will receive the error class that is stored in the error
that is identified by the handle.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_NO_ERROR_MESSAGES
No error messages associated with error handle.

Usage: None

Chapter 3. Express C/C++ APIs 861


cwbSV_GetErrClassIndexed
Purpose: Returns the message class associated with the error index provided. An
index value of 1 will retrieve the lowest-level (for example, the oldest) message
that is associated with the error handle. An index value of ″cwbSV_GetErrCount()’s
returned errorCount″ will retrieve the top-level (for example, the most recent)
message associated with the error handle.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrClassIndexed(


cwbSV_ErrHandle errorHandle,
unsigned long errorIndex,
unsigned long *errorClass);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.
unsigned long errorIndex - input
Index value that indicates which error text to return if multiple errors are
associated with the error handle.
unsigned long * errorClass - output
Pointer to a variable that will receive the error class that is stored in the error
that is identified by the index.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_NO_ERROR_MESSAGES
No error messages associated with error handle.

Usage: Valid index values are from 1 to cwbSV_GetErrCount()’s return value.


Index values less than 1 act as if 1 was passed. Index values greater than
cwbSV_GetErrCount() act as if errorCount was passed.

862 Client Access Express Programming


cwbSV_GetErrCount
Purpose: Returns the number of messages associated with the error handle
provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrCount(


cwbSV_ErrHandle errorHandle,
unsigned long *errorCount);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.
unsigned long * errorCount - input/output
Pointer to variable that receives the number of messages associated with this
error handle. If zero is returned, no errors are associated with the error handle.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

Chapter 3. Express C/C++ APIs 863


cwbSV_GetErrFileName
Purpose: Returns the message file name for the top-level (the. most recent)
message added to the error handle provided. This message attribute only pertains
to messages returned from the AS/400. The file name is the name of the AS/400
message file that contains the message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrFileName(


cwbSV_ErrHandle errorHandle,
char *fileName,
unsigned long fileNameLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
char * fileName - input/output
Pointer to a buffer that will receive the message file name stored in the error
identified by the handle. The value returned is an ASCIIZ string.
unsigned long fileNameLength - input
Length of the receive buffer passed in. It should include space for the
terminating null character. If the buffer is too small, the value will be truncated
and CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_MSGFILE_NAME.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the message file name for the AS/400 messages contained in the
error handle. If there is no message file name attribute for the message, return code
CWBSV_ATTRIBUTE_NOT_SET will be returned.

864 Client Access Express Programming


cwbSV_GetErrFileNameIndexed
Purpose: Returns the message file name for the message identified by the index
provided. This message attribute only pertains to messages returned from the
AS/400. The file name is the name of the AS/400 message file containing the
message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrFileNameIndexed(


cwbSV_ErrHandle errorHandle,
unsigned long index,
char *fileName,
unsigned long fileNameLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
unsigned long index - input
Index value indicating which message file name to return if multiple errors are
associated with the error handle. The valid index range is from 1 to the
number of messages contained in the error handle. The number of messages
can be obtained by calling the cwbSV_GetErrCount() API.
char * fileName - input/output
Pointer to a buffer that will receive the message file name stored in the error
identified by the index. The value returned is an ASCIIZ string.
unsigned long fileNameLength - input
Length of the receive buffer passed in. It should include space for the
terminating null character. If the buffer is too small, the value will be truncated
and CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_MSGFILE_NAME.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

Chapter 3. Express C/C++ APIs 865


Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the message file name for the AS/400 messages contained in the
error handle. If there is no message file name attribute for the message, return code
CWBSV_ATTRIBUTE_NOT_SET will be returned. An index value of 1 works with
the lowest-level (i.e. oldest) message in the error handle. An index value equal to
the count returned by the cwbSV_GetErrCount() API works with the top-level (i.e.
most recent) message in the error handle. Index values less than 1 act as if 1 was
passed in. Index values greater than the number of messages contained in the error
handle act as if the returned count value from the cwbSV_GetErrCount() API was
passed in.

866 Client Access Express Programming


cwbSV_GetErrLibName
Purpose: Returns the message file library name for the top-level (i.e. most recent)
message added to the error handle provided. This message attribute only pertains
to messages returned from the AS/400. The library name is the name of the
AS/400 library containing the message file for the message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrLibName(


cwbSV_ErrHandle errorHandle,
char *libraryName,
unsigned long libraryNameLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
char * libraryName - input/output
Pointer to a buffer that will receive the message file library name stored in the
error identified by the handle. The value returned is an ASCIIZ string.
unsigned long libraryNameLength - input
Length of the receive buffer passed in. It should include space for the
terminating null character. If the buffer is too small, the value will be truncated
and CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_MSGFILE_LIBR.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the message file library name for the AS/400 messages contained in
the error handle. If there is no message file library name attribute for the message,
return code CWBSV_ATTRIBUTE_NOT_SET will be returned.

Chapter 3. Express C/C++ APIs 867


cwbSV_GetErrLibNameIndexed
Purpose: Returns the message file library name for the message identified by the
index provided. This message attribute only pertains to messages returned from
the AS/400. The library name is the name of the AS/400 library containing the
message file for the message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrLibNameIndexed(


cwbSV_ErrHandle errorHandle,
unsigned long index,
char *libraryName,
unsigned long libraryNameLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
unsigned long index - input
Index value indicating which message file library name to return if multiple
errors are associated with the error handle. The valid index range is from 1 to
the number of messages contained in the error handle. The number of
messages can be obtained by calling the cwbSV_GetErrCount() API.
char * libraryName - input/output
Pointer to a buffer that will receive the message file library name stored in the
error identified by the index. The value returned is an ASCIIZ string.
unsigned long libraryNameLength - input
Length of the receive buffer passed in. It should include space for the
terminating null character. If the buffer is too small, the value will be truncated
and CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_MSGFILE_LIBR.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

868 Client Access Express Programming


Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the message file library name for the AS/400 messages contained in
the error handle. If there is no message file library name attribute for the message,
return code CWBSV_ATTRIBUTE_NOT_SET will be returned. An index value of 1
works with the lowest-level (i.e. oldest) message in the error handle. An index
value equal to the count returned by the cwbSV_GetErrCount() API works with
the top-level (i.e. most recent) message in the error handle. Index values less than 1
act as if 1 was passed in. Index values greater than the number of messages
contained in the error handle act as if the returned count value from the
cwbSV_GetErrCount() API was passed in.

Chapter 3. Express C/C++ APIs 869


cwbSV_GetErrSubstText
Purpose: Returns the message substitution text for the top-level (the most recent)
message identified by the error handle provided. This message attribute only
pertains to messages returned from the AS/400. The substitution text is the data
inserted into the substitution variable fields defined for the message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrSubstText(


cwbSV_ErrHandle errorHandle,
char *substitutionText,
unsigned long substitutionTextLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
char * substitutionText - input/output
Pointer to a buffer that will receive the substitution text for the message
identified by the handle. NOTE: The data returned is binary, hence it is NOT
returned as an ASCIIZ string. Any character strings contained in the
substitution text are returned as EBCDIC values.
unsigned long substitutionTextLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small. It will also be set to
the actual number of bytes of output data returned upon successful
completion.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the substitution text for the AS/400 messages contained in the error
handle. If there is no substitution text for the message, return code
CWBSV_ATTRIBUTE_NOT_SET will be returned. Use the returnLength parameter

870 Client Access Express Programming


to determine the actual number of bytes returned in the substitution text when the
return code is CWB_OK. The substitution text returned on this API could be used
on a subsequent host retrieve message API call (QSYS/QMHRTVM) to retrieve the
format of the substitution text or to return secondary help text with the
substitution text added in. Host API’s are called using the cwbRC_CallPgm() API.

Chapter 3. Express C/C++ APIs 871


cwbSV_GetErrSubstTextIndexed
Purpose: Returns the message substitution text for the message identified by the
index provided. This message attribute only pertains to messages returned from
the AS/400. The substitution text is the data inserted into the substitution variable
fields defined for the message.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrSubstTextIndexed(


cwbSV_ErrHandle errorHandle,
unsigned long index,
char *substitutionText,
unsigned long substitutionTextLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
API.
unsigned long index - input
Index value indicating which substitution text to return if multiple errors are
associated with the error handle. The valid index range is from 1 to the
number of messages contained in the error handle. The number of messages
can be obtained by calling the cwbSV_GetErrCount() API.
char * substitutionText - input/output
Pointer to a buffer that will receive the substitution text stored in the error
identified by the index. Note: The data returned is binary, hence it is NOT
returned as an ASCIIZ string. Any character strings contained in the
substitution text are returned as EBCDIC values.
unsigned long substitutionTextLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small. It will also be set to
the actual number of bytes of output data returned upon successful
completion.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Invalid handle.
CWBSV_NO_ERROR_MESSAGES
No messages are in the error handle.
CWBSV_ATTRIBUTE_NOT_SET
Attribute not set in current message.

872 Client Access Express Programming


Usage: AS/400 messages may be added to the error handle when using the
cwbRC_CallPgm() and cwbRC_RunCmd() API’s. In these cases, you can use this
API to retrieve the substitution text for the AS/400 messages contained in the error
handle. If there is no substitution text for the message, return code
CWBSV_ATTRIBUTE_NOT_SET will be returned. An index value of 1 works with
the lowest-level (i.e. oldest) message in the error handle. An index value equal to
the count returned by the cwbSV_GetErrCount() API works with the top-level (i.e.
most recent) message in the error handle. Index values less than 1 act as if 1 was
passed in. Index values greater than the number of messages contained in the error
handle act as if the returned count value from the cwbSV_GetErrCount() API was
passed in. Use the returnLength parameter to determine the actual number of
bytes returned in the substitution text when the return code is CWB_OK. The
substitution text returned on this API could be used on a subsequent host retrieve
message API call (QSYS/QMHRTVM) to retrieve the format of the substitution text
or to return secondary help text with the substitution text added in. Host API’s are
called using the cwbRC_CallPgm() API.

Chapter 3. Express C/C++ APIs 873


cwbSV_GetErrText
Purpose: Returns the message text associated with the top-level (for example, the
most recent) error that is identified by the error handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrText(


cwbSV_ErrHandle errorHandle,
char *errorText,
unsigned long errorTextLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.
char * errorText - input/output
Pointer to a buffer that will receive the error message text that is stored in the
error that is identified by the handle.
unsigned long errorTextLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_NO_ERROR_MESSAGES
No error messages associated with error handle.

Usage: None

874 Client Access Express Programming


cwbSV_GetErrTextIndexed
Purpose: Returns the message text associated with the error index provided. An
index value of 1 will retrieve the lowest-level (for example, the oldest) message
that is associated with the error handle. An index value of ″cwbSV_GetErrCount()’s
returned errorCount″ will retrieve the top-level (for example, the most recent)
message associated with the error handle.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetErrTextIndexed(


cwbSV_ErrHandle errorHandle,
unsigned long errorIndex,
char *errorText,
unsigned long errorTextLength,
unsigned long *returnLength);

Parameters:
cwbSV_ErrHandle errorHandle - input
Handle that was returned by a previous call to the cwbSV_CreateErrHandle()
function.
unsigned long errorIndex - input
Index value that indicates which error text to return if multiple errors are
associated with the error handle.
char * errorText - input/output
Pointer to a buffer that will receive the error message text that is stored in the
error that is identified by the index.
unsigned long errorTextLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_NO_ERROR_MESSAGES
No error messages associated with error handle.

Usage: Valid index values are from 1 to cwbSV_GetErrCount()’s return value.


Index values less than 1 act as if 1 was passed. Index values greater than
cwbSV_GetErrCount() act as if errorCount was passed.

Chapter 3. Express C/C++ APIs 875


cwbSV_GetMaxRecordSize
Purpose: Returns the size (in bytes) of the largest record in the service file that is
identified by the file handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetMaxRecordSize(


cwbSV_ServiceFileHandle serviceFile,
unsigned long *maxRecordSize);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function.
unsigned long * recordCount - input/output
Pointer to variable that receives the size of the largest record in the file.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

876 Client Access Express Programming


cwbSV_GetMessageText
Purpose: Returns the message text portion of the service record object that is
identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetMessageText(


cwbSV_ServiceRecHandle serviceRecHandle,
char *messageText,
unsigned long messageTextLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
char * messageText - input/output
Pointer to a buffer that will receive the message text that is stored in the record
that is identified by the handle.
unsigned long messageTextLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated, and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_MESSAGE_REC.

Usage: If the record type is not CWBSV_MESSAGE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

Chapter 3. Express C/C++ APIs 877


cwbSV_GetProduct
Purpose: Returns the product ID value for the service record object that is
identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetProduct(


cwbSV_ServiceRecHandle serviceRecHandle,
char *productID,
unsigned long productIDLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
char * productID - input/output
Pointer to a buffer that will receive the product ID that is stored in the record
that is identified by the handle.
unsigned long productIDLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_PRODUCT_ID.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: The service record handle needs to be filled in by a call to a ″read″


function before calling this routine, otherwise a NULL string will be returned. This
function is valid for all service record types.

878 Client Access Express Programming


cwbSV_GetRecordCount
Purpose: Returns the total numbers of records in the service file that is identified
by the file handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetRecordCount(


cwbSV_ServiceFileHandle serviceFile,
unsigned long *recordCount);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function.
unsigned long * recordCount - input/output
Pointer to variable that receives the total number of records in the file.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

Chapter 3. Express C/C++ APIs 879


cwbSV_GetServiceFileName
Purpose: Returns the fully-qualified path and file name of where the service
records are being logged to for a particular file type.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetServiceFileName(


cwbSV_ServiceFileType serviceFileType,
char *fileName,
unsigned long fileNameLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceFileType serviceFileType - input
Value indicating which service file name you want returned. -
CWBSV_HISTORY_LOG - CWBSV_PROBLEM_LOG -
CWBSV_DETAIL_TRACE_FILE - CWBSV_ENTRY_EXIT_TRACE_FILE
char * fileName - input/output
Pointer to a buffer that will receive the service file name associated with the
one that was requested.
unsigned long fileNameLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_FILE_PATH.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWBSV_INVALID_FILE_TYPE
Unusable file type passed-in.

Usage: The filename string returned could be used as input to the


cwbSV_OpenServiceFile() routine.

880 Client Access Express Programming


cwbSV_GetServiceType
Purpose: Returns the type of record (trace, message, entry/exit, and so forth) for
the service record that is identified by the handle that is provided. Note: The
service record needs to be filled in by a call to a ″read″ function before calling this
function.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetServiceType(


cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_ServiceRecType *serviceType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
cwbSV_ServiceRecType * serviceType - output
Pointer to a cwbSV_ServiceRecType where the serviceType will be returned. -
CWBSV_MESSAGE_REC - CWBSV_PROBLEM_REC -
CWBSV_DATA_TRACE_REC - CWBSV_API_TRACE_REC -
CWBSV_SPI_TRACE_REC
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Unusable record type detected.

Usage: The service record handle needs to be filled in by a call to a ″read″


function before calling this routine, otherwise CWBSV_INVALID_RECORD_TYPE
will be returned.

Chapter 3. Express C/C++ APIs 881


cwbSV_GetTimeStamp
Purpose: Returns the timestamp (in localized format) for the service record that is
identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTimeStamp(


cwbSV_ServiceRecHandle serviceRecHandle,
char *timeStamp,
unsigned long timeStampLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
char * timeStamp - input/output
Pointer to a buffer that will receive the timestamp that is stored in the record
that is identified by the handle.
unsigned long timeStampLength - input
Length of the receive buffer passed in. It should include space for the ending
null character. If the buffer is too small, the value will be truncated, and
CWB_BUFFER_OVERFLOW and returnLength will be set. NOTE: The
recommended size is CWBSV_MAX_TIME_VALUE.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output string if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: The service record handle needs to be filled in by a call to a ″read″


function before calling this routine, otherwise a NULL string will be returned. This
function is valid for all service record types.

882 Client Access Express Programming


cwbSV_GetTraceAPIData
Purpose: Returns the API trace data portion of the service record that is identified
by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceAPIData(


cwbSV_ServiceRecHandle serviceRecHandle,
char *apiData,
unsigned long apiDataLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
char * apiData - input/output
Pointer to a buffer that will receive the API trace data that is stored in the
record that is identified by the handle. Note: The data that is returned is
binary. Hence, it is NOT returned as an ASCIIZ string.
unsigned long apiDataLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated, and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_API_TRACE_REC.

Usage: If the record type is not CWBSV_API_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

Chapter 3. Express C/C++ APIs 883


cwbSV_GetTraceAPIID
Purpose: Returns the API event ID of the service record object that is identified
by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceAPIID(


cwbSV_ServiceRecHandle serviceRecHandle,
char *apiID);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
char * apiID - input/output
Pointer to one-byte field that receives the API event ID.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_API_TRACE_REC.

Usage: If the record type is not CWBSV_API_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

884 Client Access Express Programming


cwbSV_GetTraceAPIType
Purpose: Returns the API event type of the service record object that is identified
by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceAPIType(


cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_EventType *eventType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
cwbSV_EventType * eventType - output
Pointer to a cwbSV_EventType where the eventType will be returned. -
CWBSV_ENTRY_POINT - CWBSV_EXIT_POINT
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_API_TRACE_REC.
CWBSV_INVALID_EVENT_TYPE
Unusable event type detected.

Usage: If the record type is not CWBSV_API_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

Chapter 3. Express C/C++ APIs 885


cwbSV_GetTraceData
Purpose: Returns the trace data portion of the service record object that is
identified by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceData(


cwbSV_ServiceRecHandle serviceRecHandle,
char *traceData,
unsigned long traceDataLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
char * traceData - input/output
Pointer to a buffer that will receive the trace data that is stored in the record
that is identified by the handle. Note: The data that is returned is binary.
Hence, it is NOT returned as an ASCIIZ string.
unsigned long traceDataLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated, and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_DATA_TRACE_REC.

Usage: If the record type is not CWBSV_TRACE_DATA_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

886 Client Access Express Programming


cwbSV_GetTraceSPIData
Purpose: Returns the SPI trace data portion of the service record that is identified
by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceSPIData(


cwbSV_ServiceRecHandle serviceRecHandle,
char *spiData,
unsigned long spiDataLength,
unsigned long *returnLength);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
char * spiData - input/output
Pointer to a buffer that will receive the SPI trace data that is stored in the
record that is identified by the handle. Note: The data that is returned is
binary. Hence, it is NOT returned as an ASCIIZ string.
unsigned long spiDataLength - input
Length of the receive buffer passed in. If the buffer is too small, the value will
be truncated, and CWB_BUFFER_OVERFLOW and returnLength will be set.
unsigned long * returnLength - input/output
Optional, may be NULL. A return address to store the number of bytes needed
to hold the output data if the receive buffer is too small.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_BUFFER_OVERFLOW
Output buffer too small, data truncated.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_SPI_TRACE_REC.

Usage: If the record type is not CWBSV_SPI_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

Chapter 3. Express C/C++ APIs 887


cwbSV_GetTraceSPIID
Purpose: Returns the SPI event ID of the service record object that is identified by
the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceSPIID(


cwbSV_ServiceRecHandle serviceRecHandle,
char *spiID);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
char * spiID - input/output
Pointer to one-byte field that receives the SPI event ID.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_SPI_TRACE_REC.

Usage: If the record type is not CWBSV_SPI_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

888 Client Access Express Programming


cwbSV_GetTraceSPIType
Purpose: Returns the SPI event type of the service record object that is identified
by the handle that is provided.

Syntax:

unsigned int CWB_ENTRY cwbSV_GetTraceSPIType(


cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_EventType *eventType,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle() function.
cwbSV_EventType * eventType - output
Pointer to a cwbSV_EventType where the eventType will be returned. -
CWBSV_ENTRY_POINT - CWBSV_EXIT_POINT
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed on output parameter.
CWB_INVALID_HANDLE
Handle is not valid.
CWBSV_INVALID_RECORD_TYPE
Type is not CWBSV_SPI_TRACE_REC.
CWBSV_INVALID_EVENT_TYPE
Unusable event type detected.

Usage: If the record type is not CWBSV_SPI_TRACE_REC, a return code of


CWBSV_INVALID_RECORD_TYPE will be returned. (note:
cwbSV_GetServiceType() returns the current record type)

Chapter 3. Express C/C++ APIs 889


cwbSV_LogAPIEntry
Purpose: This function will log an API entry point to the currently active
entry/exit trace file. The product and component ID’s set in the entry will be
written along with the date and time of the when the data was logged. The apiID,
along with any optional data that is passed on the request, will also be logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogAPIEntry(


cwbSV_TraceAPIHandle traceAPIHandle,
unsigned char apiID,
char *apiData,
unsigned long apiDataLength);

Parameters:
cwbSV_TraceAPIHandle traceAPIHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceAPIHandle().
unsigned char apiID - input
A unique one-character code that will distinguish this API trace point from
others that are logged by your program. Definition of these codes are left up to
the caller of this API. The recommended approach is to use the defined range
(0x00 - 0xFF) for each unique component in your product (that is, start at 0x00
for each component)
char * apiData - input
Points to a buffer that contains additional data (for example, input parameter
values from your caller) that you want to log along with this entry point.
Parameter is optional, it is ignored if the address is NULL or the data length is
zero. This buffer can contain binary data because the length parameter is used
in determining the amount to trace.
unsigned long apiDataLength - input
Specifies the number of bytes in the API data buffer to log for this trace entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should allows be used in conjunction with a corresponding


″cwbSV_LogAPIExit()″. It is recommended that these calls would be put at the
beginning and end of an API routine that you write. The other method would be
to use these log functions around calls to external routines that are not written by
you.

890 Client Access Express Programming


cwbSV_LogAPIExit
Purpose: This function will log an API exit point to the currently active entry/exit
trace file. The product and component ID’s set in the entry will be written along
with the date and time of the when the data was logged. The API ID, along with
any optional data that is passed on the request, will also be logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogAPIExit(


cwbSV_TraceAPIHandle traceAPIHandle,
unsigned char apiID,
char *apiData,
unsigned long apiDataLength);

Parameters:
cwbSV_TraceAPIHandle traceAPIHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceAPIHandle().
unsigned char apiID - input
A unique one-character code that will distinguish this API trace point from
others that are logged by your program. Definition of these codes are left up to
the caller of this API. The recommended approach is to use the defined range
(0x00 - 0xFF) for each unique component in your product (that is, start at 0x00
for each component)
char * apiData - input
Points to a buffer that contains additional data (for example, output parameter
values passed back to your caller) that you want to log along with this exit
point. Parameter is optional, it is ignored if the address is NULL or the data
length is zero. This buffer can contain binary data because the length
parameter is used in determining the amount to trace.
unsigned long apiDataLength - input
Specifies the number of bytes in the API data buffer to log for this trace entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should allows be used in conjunction with a corresponding


″cwbSV_LogAPIEntry()″. It is recommended that these calls would be put at the
beginning and end of an API routine that you write. The other method would be
to use these log functions around calls to external routines that are not written by
you.

Chapter 3. Express C/C++ APIs 891


cwbSV_LogMessageText
Purpose: This function will log the supplied message text to the currently active
history log. The product and component ID’s set in the entry will be written along
with the date and time of the when the text was logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogMessageText(


cwbSV_MessageTextHandle messageTextHandle,
char *messageText,
unsigned long messageTextLength);

Parameters:
cwbSV_MessageTextHandle messageTextHandle - input
Handle that was returned by a previous call to
cwbSV_CreateMessageTextHandle().
char * messageText - input
Points to a buffer that contains the message text you want to log.
unsigned long messageTextLength - input
Specifies the number of bytes in the message text buffer to log for this message
entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Unusable handle passed in on request.

Usage: None

892 Client Access Express Programming


cwbSV_LogSPIEntry
Purpose: This function will log an SPI entry point to the currently active
entry/exit trace file. The product and component ID’s set in the entry will be
written along with the date and time of the when the data was logged. The spiID,
along with any optional data that is passed on the request, will also be logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogSPIEntry(


cwbSV_TraceSPIHandle traceSPIHandle,
unsigned char spiID,
char *spiData,
unsigned long spiDataLength);

Parameters:
cwbSV_TraceSPIHandle traceSPIHandle - input
Handle that was returned by a previous call to cwbSV_CreateTraceSPIHandle().
unsigned char spiID - input
A unique one-character code that will distinguish this SPI trace point from
others that are logged by your program. Definition of these codes are left up to
the caller of this API. The recommended approach is to use the defined range
(0x00 - 0xFF) for each unique component in your product (that is, start at 0x00
for each component)
char * spiData - input
Points to a buffer that contains additional data (for example, input parameter
values from your caller) that you want to log along with this entry point.
Parameter is optional, it is ignored if the address is NULL or the data length is
zero. This buffer can contain binary data because the length parameter is used
in determining the amount to trace.
unsigned long spiDataLength - input
Specifies the number of bytes in the SPI data buffer to log for this trace entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
IHandle is not valid.

Usage: This call should allows be used in conjunction with a corresponding


″cwbSV_LogSPIExit()″. It is recommended that these calls would be put at the
beginning and end of an API routine that you write. The other method would be
to use these log functions around calls to external routines that are not written by
you.

Chapter 3. Express C/C++ APIs 893


cwbSV_LogSPIExit
Purpose: This function will log an SPI exit point to the currently active entry/exit
trace file. The product and component ID’s set in the entry will be written along
with the date and time of the when the data was logged. The spiID, along with
any optional data that is passed on the request, will also be logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogSPIExit(


cwbSV_TraceSPIHandle traceSPIHandle,
unsigned char spiID,
char *spiData,
unsigned long spiDataLength);

Parameters:
cwbSV_TraceSPIHandle traceSPIHandle - input
Handle that was returned by a previous call to cwbSV_CreateTraceSPIHandle().
unsigned char spiID - input
A unique one-character code that will distinguish this SPI trace point from
others that are logged by your program. Definition of these codes are left up to
the caller of this API. The recommended approach is to use the defined range
(0x00 - 0xFF) for each unique component in your product (that is, start at 0x00
for each component)
char * spiData - input
Points to a buffer that contains additional data (for example, output parameter
values passed back to your caller) that you want to log along with this exit
point. Parameter is optional, it is ignored if the address is NULL or the data
length is zero. This buffer can contain binary data because the length
parameter is used in determining the amount to trace.
unsigned long spiDataLength - input
Specifies the number of bytes in the SPI data buffer to log for this trace entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This call should allows be used in conjunction with a corresponding


″cwbSV_LogSPIEntry()″. It is recommended that these calls would be put at the
beginning and end of an API routine that you write. The other method would be
to use these log functions around calls to external routines that are not written by
you.

894 Client Access Express Programming


cwbSV_LogTraceData
Purpose: This function will log the supplied trace data to the currently active
trace file. The product and component ID’s set in the entry will be written along
with the date and time of the when the data was logged.

Syntax:

unsigned int CWB_ENTRY cwbSV_LogTraceData(


cwbSV_TraceDataHandle traceDataHandle,
char *traceData,
unsigned long traceDataLength);

Parameters:
cwbSV_TraceDataHandle traceDataHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceDataHandle().
char * traceData - input
Points to a buffer that contains the trace data you want to log. The buffer can
contain binary data because the length parameter is used in determining the
amount to trace.
unsigned long traceDataLength - input
Specifies the number of bytes in the trace data buffer to log for this trace entry.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: None

Chapter 3. Express C/C++ APIs 895


cwbSV_OpenServiceFile
Purpose: Opens the specified service file for READ access (history log, trace file,
and so forth) and returns a handle to it.

Syntax:

unsigned int CWB_ENTRY cwbSV_OpenServiceFile(


char *serviceFileName,
cwbSV_ServiceFileHandle *serviceFileHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
char * serviceFileName - input
Points to a buffer that contains the fully-qualified name (for example,
c:\path\filename.ext) of the service file to open.
cwbSV_ServiceFileHandle * serviceFileHandle - input/output
Pointer to a cwbSV_ServiceFileHandle where the handle will be returned. This
handle should be used in subsequent calls to the service file functions.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL passed as handle address.
CWB_FILE_IO_ERROR
File could not be opened.
CWB_NOT_ENOUGH_MEMORY
Insufficient memory to create handle.

Usage: None

896 Client Access Express Programming


cwbSV_ReadNewestRecord
Purpose: Reads the newest record in the service file into the record handle that is
provided. Subsequent calls can be made to retrieve the information that is stored in
this record (for example, GetProduct(), GetDateStamp(), and so forth). Note: This
record is the one with the newest time and date stamp in the file.

Syntax:

unsigned int CWB_ENTRY cwbSV_ReadNewestRecord(


cwbSV_ServiceFileHandle serviceFileHandle,
cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function.
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_END_OF_FILE
End of file has been reached.
CWB_FILE_IO_ERROR
Record could not be read.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This read would be used as a ″priming-type″ read before issuing a series
of cwbSV_ReadPrevRecord() calls until the end-of-file indicator is returned.

Chapter 3. Express C/C++ APIs 897


cwbSV_ReadNextRecord
Purpose: Reads the next record in the service file into the record handle that is
provided. Subsequent calls can be made to retrieve the information that is stored in
this record (for example, GetProduct(), GetDateStamp(), and so forth).

Syntax:

unsigned int CWB_ENTRY cwbSV_ReadNextRecord(


cwbSV_ServiceFileHandle serviceFileHandle,
cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function.
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_END_OF_FILE
End of file has been reached.
CWB_FILE_IO_ERROR
Record could not be read.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This read would normally be used once the priming read,
″ReadOldestRecord()″ is performed.

898 Client Access Express Programming


cwbSV_ReadOldestRecord
Purpose: Reads the oldest record in the service file into the record handle that is
provided. Subsequent calls can be made to retrieve the information that is stored in
this record (for example, GetProduct(), GetDateStamp(), and so forth). Note: This
record is the one with the oldest time and date stamp in the file.

Syntax:

unsigned int CWB_ENTRY cwbSV_ReadOldestRecord(


cwbSV_ServiceFileHandle serviceFileHandle,
cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function.
cwbSV_ServiceRecHandle serviceRecHandle - input
Handle that was returned by a previous call to the
cwbSV_CreateServiceRecHandle function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_END_OF_FILE
End of file has been reached.
CWB_FILE_IO_ERROR
Record could not be read.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This read would be used as a ″priming-type″ read before issuing a series
of cwbSV_ReadNextRecord() calls until the end-of-file indicator is returned.

Chapter 3. Express C/C++ APIs 899


cwbSV_ReadPrevRecord
Purpose: Reads the previous record in the service file into the record handle that
is provided. Subsequent calls can be made to retrieve the information that is stored
in this record (for example, GetProduct(), GetDateStamp(), and so forth).

Syntax:

unsigned int CWB_ENTRY cwbSV_ReadPrevRecord(


cwbSV_ServiceFileHandle serviceFileHandle,
cwbSV_ServiceRecHandle serviceRecHandle,
cwbSV_ErrHandle errorHandle);

Parameters:
cwbSV_ServiceFileHandle serviceFileHandle - input
Handle that was returned by a previous call to the cwbSV_OpenServiceFile
function. V_ServiceRecHandle serviceRecHandle -input Handle that was
returned by a previous call to the cwbSV_CreateServiceRecHandle function.
cwbSV_ErrHandle errorHandle - output
Any returned messages will be written to this object. It is created with the
cwbSV_CreateErrHandle API. The messages may be retrieved through the
cwbSV_GetErrText API. If the parameter is set to zero, no messages will be
retrieved.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_END_OF_FILE
End of file has been reached.
CWB_FILE_IO_ERROR
Record could not be read.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This read would normally be used once the priming read,
″ReadNewestRecord()″ is performed.

900 Client Access Express Programming


cwbSV_SetMessageClass
Purpose: This function allows setting of the message class (severity) to associate
with the message being written to the history log.

Syntax:
unsigned int CWB_ENTRY cwbSV_SetMessageClass(
cwbSV_MessageTextHandle messageTextHandle,
cwbSV_MessageClass messageClass);

Parameters:
cwbSV_MessageTextHandle messageTextHandle - input
Handle that was returned by a previous call to
cwbSV_CreateMessageTextHandle().
cwbSV_MessageClass messageClass - input
One of the following:
CWBSV_CLASS_INFORMATIONAL
CWBSV_CLASS_WARNING
CWBSV_CLASS_ERROR

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Unusable handle passed in on request.
CWBSV_INVALID_MSG_CLASS
Invalid message class passed in.

Usage: This value should be set before calling the corresponding log function,
″cwbSV_LogMessageText()″.

Chapter 3. Express C/C++ APIs 901


cwbSV_SetMessageComponent
Purpose: This function allows setting of a unique component identifier in the
message handle that is provided. Along with setting the product ID (see
cwbSV_SetMessageProduct), this call should be used to distinguish your message
entries from other product’s entries in the history log.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetMessageComponent(


cwbSV_MessageTextHandle messageTextHandle,
char *componentID);

Parameters:
cwbSV_MessageTextHandle messageTextHandle - input
Handle that was returned by a previous call to
cwbSV_CreateMessageTextHandle().
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this message entry. NOTE: A maximum of CWBSV_MAX_COMP_ID
characters will be logged for the component ID. Larger strings will be
truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Unusable handle passed in on request.

Usage: This value should be set before calling the corresponding log function,
″cwbSV_LogMessageData()″. The suggested hierarchy is that you would define a
product ID with one or many components that are defined under it.

902 Client Access Express Programming


cwbSV_SetMessageProduct
Purpose: This function allows setting of a unique product identifier in the
message handle that is provided. Along with setting the component ID (see
cwbSV_SetMessageComponent), this call should be used to distinguish your
message entries from other product’s entries in the history log.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetMessageProduct(


cwbSV_MessageTextHandle messageTextHandle,
char *productID);

Parameters:
cwbSV_MessageTextHandle messageTextHandle - input
Handle that was returned by a previous call to
cwbSV_CreateMessageTextHandle().
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this message entry. NOTE: A maximum of CWBSV_MAX_PRODUCT_ID
characters will be logged for the product ID. Larger strings will be truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Unusable handle passed in on request.

Usage: This value should be set before calling the corresponding log function,
″cwbSV_LogMessageData()″. The suggested hierarchy is that you would define a
product ID with one or many components that are defined under it.

Chapter 3. Express C/C++ APIs 903


cwbSV_SetAPIComponent
Purpose: This function allows setting of a unique component identifier in trace
entry that is provided. Along with setting the product ID (see
cwbSV_SetAPIProduct), this call should be used to distinguish your trace entries
from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetAPIComponent(


cwbSV_TraceAPIHandle traceAPIHandle,
char *componentID);

Parameters:
cwbSV_TraceAPIHandle traceAPIHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceAPIHandle().
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this trace entry. NOTE: A maximum of CWBSV_MAX_COMP_ID
characters will be logged for the component ID. Larger strings will be
truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log functions,
″cwbSV_LogAPIEntry()″ and ″cwbSV_LogAPIExit(). The suggested hierarchy is
that you would define a product ID with one or many components that are
defined under it.

904 Client Access Express Programming


cwbSV_SetAPIProduct
Purpose: This function allows setting of a unique product identifier in the trace
handle that is provided. Along with setting the component ID (see
cwbSV_SetAPIComponent), this call should be used to distinguish your trace
entries from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetAPIProduct(


cwbSV_TraceAPIHandle traceAPIHandle,
char *productID);

Parameters:
cwbSV_TraceAPIHandle traceAPIHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceAPIHandle().
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this trace entry. NOTE: A maximum of CWBSV_MAX_PRODUCT_ID
characters will be logged for the product ID. Larger strings will be truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log functions,
″cwbSV_LogAPIEntry()″ and ″cwbSV_LogAPIExit(). The suggested hierarchy is
that you would define a product ID with one or many components that are
defined under it.

Chapter 3. Express C/C++ APIs 905


cwbSV_SetSPIComponent
Purpose: This function allows setting of a unique component identifier in trace
entry that is provided. Along with setting the product ID (see
cwbSV_SetSPIProduct), this call should be used to distinguish your trace entries
from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetSPIComponent(


cwbSV_TraceSPIHandle traceSPIHandle,
char *componentID);

Parameters:
cwbSV_TraceSPIHandle traceSPIHandle - input
Handle that was returned by a previous call to cwbSV_CreateTraceSPIHandle().
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this trace entry. NOTE: A maximum of CWBSV_MAX_COMP_ID
characters will be logged for the component ID. Larger strings will be
truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log functions,
″cwbSV_LogAPIEntry()″ and ″cwbSV_LogAPIExit(). The suggested hierarchy is
that you would define a product ID with one or many components that are
defined under it.

906 Client Access Express Programming


cwbSV_SetSPIProduct
Purpose: This function allows setting of a unique product identifier in the trace
handle that is provided. Along with setting the component ID (see
cwbSV_SetSPIComponent), this call should be used to distinguish your trace
entries from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetSPIProduct(


cwbSV_TraceSPIHandle traceSPIHandle,
char *productID);

Parameters:
cwbSV_TraceSPIHandle traceSPIHandle - input
Handle that was returned by a previous call to cwbSV_CreateTraceSPIHandle().
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this trace entry. NOTE: A maximum of CWBSV_MAX_PRODUCT_ID
characters will be logged for the product ID. Larger strings will be truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log functions,
″cwbSV_LogAPIEntry()″ and ″cwbSV_LogAPIExit(). The suggested hierarchy is
that you would define a product ID with one or many components that are
defined under it.

Chapter 3. Express C/C++ APIs 907


cwbSV_SetTraceComponent
Purpose: This function allows setting of a unique component identifier in service
entry that is provided. Along with setting the product ID (see
cwbSV_SetTraceProduct), this call should be used to distinguish your trace entries
from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetTraceComponent(


cwbSV_TraceDataHandle traceDataHandle,
char *componentID);

Parameters:
cwbSV_TraceDataHandle traceDataHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceDataHandle().
char * componentID - input
Points to a null-terminated string that contains a component identifier to be
used on this trace entry. NOTE: A maximum of CWBSV_MAX_COMP_ID
characters will be logged for the component ID. Larger strings will be
truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log function,
″cwbSV_LogTraceData()″. The suggested hierarchy is that you would define a
product ID with one or many components that are defined under it.

908 Client Access Express Programming


cwbSV_SetTraceProduct
Purpose: This function allows setting of a unique product identifier in the trace
handle that is provided. Along with setting the component ID (see
cwbSV_SetTraceComponent), this call should be used to distinguish your trace
entries from other product’s entries in the trace file.

Syntax:

unsigned int CWB_ENTRY cwbSV_SetTraceProduct(


cwbSV_TraceDataHandle traceDataHandle,
char *productID);

Parameters:
cwbSV_TraceDataHandle traceDataHandle - input
Handle that was returned by a previous call to
cwbSV_CreateTraceDataHandle().
char * productID - input
Points to a null-terminated string that contains a product identifier to be used
on this trace entry. NOTE: A maximum of CWBSV_MAX_PRODUCT_ID
characters will be logged for the product ID. Larger strings will be truncated.

Return Codes: The following list shows common return values.


CWB_OK
Successful completion.
CWB_INVALID_HANDLE
Handle is not valid.

Usage: This value should be set before calling the corresponding log function,
cwbSV_LogTraceData. The suggested hierarchy is that you would define a product
ID with one or many components that are defined under it.

Chapter 3. Express C/C++ APIs 909


Example: Using Express Serviceability APIs
The following example uses the Express Serviceability APIs to log a message string
to the Client Access Express History Log:
#include <stdio.h>
#include "CWBSV.H"

unsigned int logMessageText(char *msgtxt)


/* Write a message to the active message log. */
{
cwbSV_MessageTextHandle messageTextHandle;
unsigned int rc;

/* Create a handle to a message text object, so that we may write */


/* message text to the active message log. */
if ((rc = cwbSV_CreateMessageTextHandle("ProductID", "ComponentID",
&messageTextHandle)) != CWB_OK)
return(rc);

/* Log the supplied message text to the active message log. */


rc = cwbSV_LogMessageText(messageTextHandle, msgtxt, strlen(msgtxt));

/* Delete the message text object identified by the handle provided.*/


cwbSV_DeleteMessageTextHandle(messageTextHandle);

return(rc);
}

unsigned int readMessageText(char **bufptr, cwbSV_ErrHandle errorHandle)


/* Read a message from the active message log. */
{
cwbSV_ServiceFileHandle serviceFileHandle;
cwbSV_ServiceRecHandle serviceRecHandle;
static char buffer[BUFSIZ];
unsigned int rc;

/* Retrieve the fully-qualified path and file name of the active */


/* message log. */
if ((rc = cwbSV_GetServiceFileName(CWBSV_HISTORY_LOG, buffer, BUFSIZ,
NULL)) != CWB_OK)
return(rc);

/* Open the active message log for READ access and return a handle */
/* to it. */
if ((rc = cwbSV_OpenServiceFile(buffer, &serviceFileHandle, errorHandle))
!= CWB_OK)
return(rc);

/* Create a service record object and return a handle to it. */


if ((rc = cwbSV_CreateServiceRecHandle(&serviceRecHandle)) != CWB_OK) {
cwbSV_CloseServiceFile(serviceFileHandle, 0);
return(rc);
}

/* Read the newest record in the active message log into the */
/* record handle provided. */
if ((rc = cwbSV_ReadNewestRecord(serviceFileHandle, serviceRecHandle,
errorHandle)) != CWB_OK) {
cwbSV_DeleteServiceRecHandle(serviceRecHandle);
cwbSV_CloseServiceFile(serviceFileHandle, 0);
return(rc);
}

/* Retrieve the message text portion of the service record object */


/* identified by the handle provided. */
if ((rc = cwbSV_GetMessageText(serviceRecHandle, buffer, BUFSIZ, NULL))
== CWB_OK || rc == CWB_BUFFER_OVERFLOW) {

910 Client Access Express Programming


*bufptr = buffer;
rc = CWB_OK;
}

/* Delete the service record object identified by the */


/* handle provided. */
cwbSV_DeleteServiceRecHandle(serviceRecHandle);

/* Close the active message log identified by the handle provided.*/


cwbSV_CloseServiceFile(serviceFileHandle, errorHandle);

return(rc);
}

void main(int argc, char *argv[ [)


{
cwbSV_ErrHandle errorHandle;
char *msgtxt = NULL, errbuf[BUFSIZ];
unsigned int rc;

/* Write a message to the active message log. */


if (logMessageText("Sample message text") != CWB_OK)
return;

/* Create an error message object and return a handle to it. */


cwbSV_CreateErrHandle(&errorHandle);

/* Read a message from the active message log. */


if (readMessageText(&msgtxt, errorHandle) != CWB_OK) {
if ((rc = cwbSV_GetErrText(errorHandle, errbuf, BUFSIZ, NULL)) ==
CWB_OK || rc == CWB_BUFFER_OVERFLOW)
fprintf(stdout, "%s\n", errbuf);
}
else if (msgtxt)
fprintf(stdout, "Message text: \"%s\"\n", msgtxt);

/* Delete the error message object identified by the */


/* handle provided. */
cwbSV_DeleteErrHandle(errorHandle);
}

Express System Object Access (SOA) APIs


System Object Access enables you to view and manipulate AS/400 objects through
a graphical user interface. Client Access Express System Object Access application
programming interfaces (APIs) provide direct access to object attributes. For
example, to obtain the number of copies for a given spool file, you can call a series
of SOA APIs, and change the value as needed.
Express System Object Access APIs required files:

Interface definition file Import library Dynamic Link Library


cwbsoapi.h cwbapi.lib cwbsoapi.dll

Express Toolkit:
The Client Access Express Toolkit provides System Object Access
documentation, access to the cwbsoapi.h header file, and links to sample
programs. To access this information, open the Express Toolkit and select
AS/400 Operations —> C/C++ APIs.
Express System Object Access APIs topics:
v “SOA objects” on page 912
v “AS/400 object views” on page 912

Chapter 3. Express C/C++ APIs 911


v “Typical use of Express System Object Access APIs”
v Express System Object Access APIs listing
v “Express System Object Access APIs return codes” on page 29
Related topic:
v “AS/400 system name formats for APIs” on page 10

SOA objects
Use System Object Access to view and to manipulate the following AS/400 objects:
You can view and manipulate these objects:
v Jobs
v Printers
v Printed output
v Messages
v Spooled files
You only can manipulate these objects:
v Users and groups
v TCP/IP interfaces
v TCP/IP routes
v Ethernet lines
v Token-ring lines
v Hardware resources
v Software resources
v Libraries in QSYS

AS/400 object views


Two types of AS/400 object views are provided with Client Access Express:
List view:
Displays a customizable graphical list view of the selected AS/400 objects.
The user can perform a variety of actions on one or more objects.
Properties view:
Displays a detailed graphical view of the attributes of a specific AS/400
object. The user can view all attributes if desired, and make changes to
those attributes that are changeable.

Typical use of Express System Object Access APIs


Links to three summaries for and examples of System Object Access API usage are
provided below. Each example is presented twice; a typical sequence of API calls is
shown in summary form, and then an actual C-language sample program is
presented. The summary indicates which APIs are required (R) and which are
optional (O). Normally, additional code would be required to check for and handle
errors on each function call; this has been omitted for illustration purposes.
Typical use of Express SOA APIs summaries and examples:
v “Displaying a customized list of AS/400 objects” on page 913
v “Sample program: Displaying a customized list of AS/400 objects” on
page 913
v “Displaying the Properties view for an AS/400 Object” on page 914
v “Sample program: Displaying the Properties view of an object” on
page 915
v “Accessing and updating data for AS/400 Objects” on page 916
v “Sample program: Accessing and updating data for AS/400 objects” on
page 917

912 Client Access Express Programming


Displaying a customized list of AS/400 objects
A list object for a list of AS/400 spool files is created. After setting the desired sort
and filter criteria, the list is displayed to the user, with the user interface
customized so that certain user actions are disabled. When the user is finished
viewing the list, the filter criteria are saved in the application profile and the
program exits.

Displaying a customized list of AS/400 objects (summary)


(O) cwbRC_StartSys Start a conversation with an AS/400

(R) CWBSO_CreateListHandle Create a list of AS/400 objects

(O) CWBSO_SetListProfile Set name of application

(O) CWBSO_ReadListProfile Load application preferences

(O) CWBSO_SetListFilter Set list filter criteria

(O) CWBSO_SetListSortFields Set list sort criteria

(O) CWBSO_DisallowListFilter Do not allow user to change filter criteria


(O) CWBSO_DisallowListActions Disallow selected list actions

(O) CWBSO_SetListTitle Set title of list

(R) CWBSO_CreateErrorHandle Create an error object

(R) CWBSO_DisplayList Display the customized list

(O) CWBSO_DisplayErrMsg Display error message if error occurred

(O) CWBSO_WriteListProfile Save list filter criteria

(R) CWBSO_DeleteErrorHandle Delete error object

(R) CWBSO_DeleteListHandle Delete list


(O) cwbRC_StopSys End AS/400 conversation

To view the example:


“Sample program: Displaying a customized list of AS/400 objects”

Sample program: Displaying a customized list of AS/400 objects


#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h> // Windows APIs and datatypes
#include "cwbsoapi.h" // System Object Access APIs
#include "cwbrc.h" // Client Access DPC APIs
#include "cwbun.h" // Client Access Operations Navigator APIs
#define APP_PROFILE "APPPROF" // Application profile name

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,


LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg; // Message structure
HWND hWnd; // Window handle
cwbRC_SysHandle hSystem; // System handle
CWBSO_LIST_HANDLE hList = CWBSO_NULL_HANDLE; // List handle
CWBSO_ERR_HANDLE hError = CWBSO_NULL_HANDLE; // Error handle
cwbCO_SysHandle hSystemHandle; // System object handle
unsigned int rc; // System Object Access return codes

unsigned short sortIDs[] = { CWBSO_SFL_SORT_UserData,


CWBSO_SFL_SORT_Priority };
// Array of sort IDs
unsigned short actionIDs[] = { CWBSO_ACTN_PROPERTIES };
// Array of action IDs

//******************************************************************
// Start a conversation with AS/400 system SYSNAME. Specify
// application name APPNAME.
//******************************************************************
cwbUN_GetSystemHandle((char *)"SYSNAME", (char *)"APPNAME", &hSystemHandle);

cwbRC_StartSysEx(hSystemHandle, &hSystem);
//*******************************************************************
// Create a list of spooled files. Set desired sort/filter criteria.

// Create a list of spooled files on system SYSNAME


CWBSO_CreateListHandleEx(hSystemHandle,
CWBSO_LIST_SFL,
&hList);

// Identify the name of the application profile


CWBSO_SetListProfile(hList, APP_PROFILE);

// Create an error handle


CWBSO_CreateErrorHandle(&hError);

Chapter 3. Express C/C++ APIs 913


// Load previous filter criteria
CWBSO_ReadListProfile(hList, hError);

// Only show spooled files on printer P3812 for user TLK


CWBSO_SetListFilter(hList, CWBSO_SFLF_DeviceFilter, "P3812");
CWBSO_SetListFilter(hList, CWBSO_SFLF_UserFilter, "TLK");

// Sort by 'user specified data', then by 'output priority'


CWBSO_SetListSortFields(hList, sortIDs, sizeof(sortIDs) / sizeof(short));

//*******************************************************************
// Customize the UI by disabling selected UI functions. Set the list title.
//*******************************************************************
// Do not allow users to change list filter
CWBSO_DisallowListFilter(hList);

// Do not allow the 'properties' action to be selected


CWBSO_DisallowListActions(hList, actionIDs, sizeof(actionIDs) / sizeof(short));

// Set the string that will appear in the list title bar
CWBSO_SetListTitle(hList, "Application Title");

//*******************************************************************
// Display the list.
//*******************************************************************

// Display the customized list of spooled files


rc = CWBSO_DisplayList(hList, hInstance, nCmdShow, &hWnd, hError);
// If an error occurred, display a message box
if (rc == CWBSO_ERROR_OCCURRED)
CWBSO_DisplayErrMsg(hError);
else
{
// Dispatch messages for the list window
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// List window has been closed - save filter criteria in application profile
CWBSO_WriteListProfile(hList, hError);
}

//*******************************************************************
// Processing complete - clean up and exit.
//*******************************************************************
// Clean up handles
CWBSO_DeleteErrorHandle(hError);
CWBSO_DeleteListHandle(hList);

// End the conversation started by EHNDP_StartSys


cwbRC_StopSys(hSystem);

//********************************************************************
// Return from WinMain.
//********************************************************************

return rc;
}

Displaying the Properties view for an AS/400 Object


A list object for a list of AS/400 spool files is created. After setting the desired filter
criteria, the list is opened, and a handle to the first object in the list is obtained. A
properties view that shows the attributes for this object is displayed to the user.

Displaying the properties view for an object (Summary)


(O) cwbRC_StartSys Start a conversation with an AS/400

(R) CWBSO_CreateListHandle Create a list of AS/400 objects

(O) CWBSO_SetListFilter Set list filter criteria

(R) CWBSO_CreateErrorHandle Create an error object

(R) CWBSO_OpenList Open the list (builds a list on the AS/400)

(O) CWBSO_DisplayErrMsg Display error message if error occurred

(O) CWBSO_GetListSize Get number of objects in the list

(R) CWBSO_GetObjHandle Get an object from the list

(R) CWBSO_DisplayObjAttr Display the properties view for the object

914 Client Access Express Programming


(R) CWBSO_DeleteObjHandle Delete the object

(O) CWBSO_CloseList Close the list

(R) CWBSO_DeleteErrorHandle Delete error object

(R) CWBSO_DeleteListHandle Delete list

(O) cwbRC_StopSys End AS/400 conversation

To view the example:


“Sample program: Displaying the Properties view of an object”

Sample program: Displaying the Properties view of an object


#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h> // Windows APIs and datatypes
#include "cwbsoapi.h" // System Object Access APIs
#include "cwbrc.h" // Client Access DPC APIs
#include "cwbun.h" // Client Access Operations Navigator APIs
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg; // Message structure
HWND hWnd; // Window handle
cwbRC_SysHandle hSystem; // System handle
CWBSO_LIST_HANDLE hList = CWBSO_NULL_HANDLE; // List handle
CWBSO_ERR_HANDLE hError = CWBSO_NULL_HANDLE; // Error handle
CWBSO_OBJ_HANDLE hObject = CWBSO_NULL_HANDLE; // Object handle
cwbCO_SysHandle hSystemHandle; // System object handle
unsigned long listSize = 0; // List size
unsigned short listStatus = 0; // List status
unsigned int rc; // System Object Access return codes

//*******************************************************************
// Start a conversation with AS/400 system SYSNAME. Specify
// application name APPNAME.
//******************************************************************

cwbUN_GetSystemHandle((char *)"SYSNAME", (char *)"APPNAME", &hSystemHandle);

cwbRC_StartSysEx(hSystemHandle, &hSystem);
//*******************************************************************
// Create a list of spooled files. Set desired filter criteria.
//*******************************************************************
// Create a list of spooled files on system SYSNAME
CWBSO_CreateListHandleEx(hSystemHandle,
CWBSO_LIST_SFL,
&hList);

// Only include spooled files on printer P3812 for user TLK


CWBSO_SetListFilter(hList, CWBSO_SFLF_DeviceFilter, "P3812");
CWBSO_SetListFilter(hList, CWBSO_SFLF_UserFilter, "TLK");

//*******************************************************************
// Open the list.
//*******************************************************************

// Create an error handle


CWBSO_CreateErrorHandle(&hError);

// Open the list of spooled files


rc = CWBSO_OpenList(hList, hError);
// If an error occurred, display a message box
if (rc == CWBSO_ERROR_OCCURRED)
CWBSO_DisplayErrMsg(hError);
else
{
//*****************************************************************
// Display the properties of the first object in the list
//*****************************************************************

// Get the number of objects in the list


CWBSO_GetListSize(hList, &listSize, &listStatus, hError);

if (listSize > 0)
{
// Get the first object in the list
CWBSO_GetObjHandle(hList, 0, &hObject, hError);

// Display the properties window for this object


CWBSO_DisplayObjAttr(hObject, hInstance, nCmdShow, &hWnd, hError);

// Dispatch messages for the properties window


while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Properties window has been closed - delete object handle

Chapter 3. Express C/C++ APIs 915


CWBSO_DeleteObjHandle(hObject);
}
}

//*******************************************************************
// Processing complete - clean up and exit.
//*******************************************************************

// Close the list


CWBSO_CloseList(hList, hError);

// Clean up handles
CWBSO_DeleteErrorHandle(hError);
CWBSO_DeleteListHandle(hList);

// End the conversation started by EHNDP_StartSys


cwbRC_StopSys(hSystem);

//********************************************************************
// Return from WinMain.
//********************************************************************

return rc;
}

Accessing and updating data for AS/400 Objects


In “Sample program: Accessing and updating data for AS/400 objects” on
page 917, all spooled files for device P3812 that have 10 or more pages have their
output priority changed to 9 so that they will not print before smaller files.

A list object for a list of AS/400 spool files is created. After setting the desired filter
criteria, the list is opened. A parameter object is created which will be used to
change the output priority for each spooled file in the list. After storing the desired
output priority value of ″9″ in the parameter object, a loop is entered. Each object
in the list is examined in turn, and if a spooled file is found to have more than 10
pages then its output priority is changed.

Accessing and updating data for AS/400 objects (Summary)


(R) CWBSO_CreateListHandle Create a list of AS/400 objects

(O) CWBSO_SetListFilter Set list filter criteria

(R) CWBSO_CreateErrorHandle Create an error object

(R) CWBSO_OpenList Open the list (automatically starts


a conversation with the AS/400)

(O) CWBSO_DisplayErrMsg Display error message if error occurred

(R) CWBSO_CreateParmObjHandle Create a parameter object

(R) CWBSO_SetParameter Set new value for object attribute


or attributes

(R) CWBSO_WaitForObj Wait until first object is available

. . . Loop through all objects


.
. (R) CWBSO_GetObjHandle Get an object from the list
.
. (R) CWBSO_GetObjAttr Read data for a particular attribute
.
. (R) CWBSO_SetObjAttr Update an attribute on the AS/400
.
. (R) CWBSO_DeleteObjHandle Clean up object handle
.
. (R) CWBSO_WaitForObj Wait for next object in list
.
..............

(R) CWBSO_DeleteParmObjHandle Delete the parameter object

916 Client Access Express Programming


(O) CWBSO_CloseList Close the list

(R) CWBSO_DeleteErrorHandle Delete error object

(R) CWBSO_DeleteListHandle Delete list (automatically ends the


AS/400 conversation)
To view the example:
“Sample program: Accessing and updating data for AS/400 objects”

Sample program: Accessing and updating data for AS/400


objects
#include <windows.h> // Windows APIs and datatypes
#include <stdlib.h> // For atoi
#include "cwbsoapi.h" // System Object Access APIs

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,


LPSTR lpszCmdLine, int nCmdShow)
{
CWBSO_LIST_HANDLE hList = CWBSO_NULL_HANDLE; // List handle
CWBSO_ERR_HANDLE hError = CWBSO_NULL_HANDLE; // Error handle
CWBSO_PARMOBJ_HANDLE hParmObject = CWBSO_NULL_HANDLE; // Parm object
CWBSO_OBJ_HANDLE hObject = CWBSO_NULL_HANDLE; // Object handle
unsigned int rc, setRC; // System Object Access return codes
unsigned long bytesNeeded = 0; // Bytes needed
unsigned short errorIndex = 0; // Error index (SetObjAttr)
char szString[100]; // Buffer for formatting
int totalPages = 0; // Total pages
int i = 0; // Loop counter
int nNbrChanged = 0; // Count of changed objects

MessageBox(GetFocus(), "Start of Processing", "PRIORITY", MB_OK);

//********************************************************************
// Create a list of spooled files. Set desired filter criteria.
//********************************************************************

// Create a list of spooled files on system SYSNAME


CWBSO_CreateListHandle("SYSNAME",
"APPNAME",
CWBSO_LIST_SFL,
&hList);

// Only include spooled files for device P3812


CWBSO_SetListFilter(hList, CWBSO_SFLF_DeviceFilter, "P3812");

//*******************************************************************
// Open the list.
//*******************************************************************

// Create an error handle


CWBSO_CreateErrorHandle(&hError);

// Open the list of spooled files


rc = CWBSO_OpenList(hList, hError);

// If an error occurred, display a message box


if (rc == CWBSO_ERROR_OCCURRED)
CWBSO_DisplayErrMsg(hError);
else
{
//*****************************************************************
// Set up to change output priority for all objects in the list.

Chapter 3. Express C/C++ APIs 917


//*****************************************************************

// Create a parameter object to hold the attribute changes


CWBSO_CreateParmObjHandle(&hParmObject);

// Set the parameter to change the output priority to '9'


CWBSO_SetParameter(hParmObject,
CWBSO_SFL_OutputPriority,
"9",
hError);

//******************************************************************
// Loop through the list, changing the output priority for any
// files that have more than 10 total pages. Loop will
// terminate when CWBSO_WaitForObj
// returns CWBSO_BAD_LIST_POSITION, indicating that there
// are no more objects in the list.
//******************************************************************

// Wait for first object in the list


rc = CWBSO_WaitForObj(hList, i, hError);

// Loop through entire list


while (rc == CWBSO_NO_ERROR)
{
// Get the list object at index i
CWBSO_GetObjHandle(hList, i, &hObject, hError);

// Get the total pages attribute for this spooled file


CWBSO_GetObjAttr(hObject,
CWBSO_SFL_TotalPages,
szString,
sizeof(szString),
&bytesNeeded,;
hError);

totalPages = atoi(szString);

// Update the output priority if necessary


if (totalPages > 10)
{
// Change the spool file's output priority to '9'
setRC = CWBSO_SetObjAttr(hObject, hParmObject, &errorIndex, hError);
if (setRC == CWBSO_NO_ERROR)
nNbrChanged++;
}

// Delete the object handle


CWBSO_DeleteObjHandle(hObject);

// Increment list item counter


i++;

// Wait for next list object


rc = CWBSO_WaitForObj(hList, i, hError);

} /* end while */

// Parameter object no longer needed


CWBSO_DeleteParmObjHandle(hParmObject);

} /* end if */

// Display the number of spooled files that had priority changed


wsprintf (szString, "Number of spool files changed: %d", nNbrChanged);

918 Client Access Express Programming


MessageBox(GetFocus(), szString, "PRIORITY", MB_OK);

//********************************************************************
// Processing complete - clean up and exit.
//********************************************************************

// Close the list


CWBSO_CloseList(hList,hError);

// Clean up handles
CWBSO_DeleteErrorHandle(hError);
CWBSO_DeleteListHandle(hList);

//********************************************************************
// Return from WinMain.
//********************************************************************

return 0;
}

Express System Object Access programming considerations


See the following topics for important SOA programming considerations:
v “About System Object Access errors”
v “System Object Access application profiles”
v “Managing AS/400 communications sessions for application programs” on
page 920

About System Object Access errors


All System Object Access APIs use return codes to report error conditions. Check
for errors on each function call. In addition, certain APIs incorporate a handle to
an “error object” in their interface. The error object is used to provide additional
information for errors which occurred during the processing of a request. Often
these errors are encountered while interacting with the AS/400, in which case the
error object will contain the AS/400 error message text.

If a function call returns CWBSO_ERROR_OCCURRED then the error object will


have been filled in with information that describe the error.
CWBSO_GetErrMsgText may be used to retrieve the error message text. The
message will have been translated into the language that is specified for the user’s
execution environment. Alternatively, the error message may be displayed to the
user directly by calling CWBSO_DisplayErrMsg.

For internal processing errors, error objects automatically log an entry in the
System Object Access log file soa.log, in the Client Access install directory. This
file is English only and is intended for use by IBM personnel for problem analysis.
Related topic:
“Express System Object Access APIs return codes” on page 29

System Object Access application profiles


By default, user-specified list filter criteria are not saved to disk. System Object
Access provides APIs for:
v Requesting the use of an application-specific registry key for loading the filter
data from the registry into a given list object
v Saving the data for a particular list object in the registry

The data is saved by AS/400 system name, and within system name by object
type. To read or write profile data, a system name must be specified on the
CWBSO_CreateListHandle call for the list object.

Chapter 3. Express C/C++ APIs 919


Managing AS/400 communications sessions for application
programs
Express System Object Access APIs communicate with the AS/400 through the use
of one or more client/server conversations. Because it often takes several seconds
to establish a conversation, your application may experience delays when a list
first is opened. This topic explains how to control and manage the initiation of
conversations so that the performance impact on application programs is
minimized.

The default behavior of System Object Access may be summarized as follows:


v If no conversation has been established with the AS/400 system object that is
identified on the CWBSO_CreateListHandleEx API, a conversation
automatically will be started when the list is opened or displayed. If Client
Access Express has not yet established a connection to the specified system, a
dialog box will appear prompting the user for the appropriate UserID and
password.
v If another instance of the application program starts, the above process repeats
itself. No conversation sharing occurs between application programs that run in
different processes (that is, with different instance handles).
v When the application program deletes the last System Object Access list, the
conversation with the AS/400 is automatically ended (Note that
CWBSO_CloseList does not end the conversation with the AS/400).

A System Object Access conversation may be started using the cwbRC_StartSysEx


API. This API accepts an AS/400 system object as a parameter, and returns a
system handle. Save this handle for later use on the cwbRC_StopSys API, when
the application is terminating and it is time to end the conversation with the
AS/400.

When the cwbRC_StartSysEx API is called, the application is blocked until the
conversation is established. Therefore, it is good practice to inform the user that a
connection is about to be attempted immediately before the call. On return, the
conversation will have been initiated, and System Object Access list processing will
use this conversation instead of starting a new one.

When cwbRC_StartSysEx is used in this way, the last list to be deleted will not
end the conversation. You must call cwbRC_StopSys explicitly before you exit the
application.

Express System Object Access APIs listing


The following Client Access Express System Object Access APIs are listed
alphabetically:

920 Client Access Express Programming


Express System Object Access APIs
CWBSO_CloseList CWBSO_GetErrMsgText
CWBSO_CopyObjHandle CWBSO_GetListSize
CWBSO_CreateErrorHandle CWBSO_GetObjAttr
CWBSO_CreateListHandle CWBSO_GetObjHandle
CWBSO_CreateListHandleEx CWBSO_OpenList
CWBSO_CreateObjHandle CWBSO_ReadListProfile
CWBSO_CreateParmObjHandle CWBSO_RefreshObj
CWBSO_DeleteErrorHandle CWBSO_ResetParmObj
CWBSO_DeleteListHandle CWBSO_SetListFilter
CWBSO_DeleteObjHandle CWBSO_SetListProfile
CWBSO_DeleteParmObjHandle CWBSO_SetListSortFields
CWBSO_DisallowListActions CWBSO_SetListTitle
CWBSO_DisallowListFilter CWBSO_SetObjAttr
CWBSO_DisplayErrMsg CWBSO_SetParameter
CWBSO_DisplayList CWBSO_WaitForObj
CWBSO_DisplayObjAttr CWBSO_WriteListProfile

See “SOA attribute special values” on page 962 for related information.
SOA enablers:
System Object Access also includes enablers (APIs), which applications can
use to access data in AS/400 objects or to request graphical lists and
attribute views of the object data. The APIs for manipulating lists of objects
must be called in the correct order. The basic flow is as follows:
CreateErrorHandle -- Creates a handle to an "error" object
to be passed to other APIs
CreateListHandle -- Instantiates a list object on the client
OpenList -- Builds list on AS/400 associated with client
list
(Manipulate the list and its objects using various generic
and subclass APIs)
CloseList -- Closes list and release resource on AS/400
DeleteListHandle -- Destroys list object on the client

The “CWBSO_CreateListHandle” on page 926 API must be called to create


a list before any other list APIs are called. The CWBSO_CreateListHandle
API returns a list handle to the caller. The list handle must be passed as
input to all other list APIs.

After the list is allocated, the “CWBSO_SetListFilter” on page 953 API can
be called to change the filter criteria for the list. CWBSO_SetListFilter is
optional; if it is not called, the list will be built with the default filter
criteria. Similarly, the “CWBSO_SetListSortFields” on page 955 API can be
called to define the attributes on which the list will be sorted. If it is not
called the list will not be sorted.

The “CWBSO_OpenList” on page 949 API must be called to build the list
of objects. This will result in a request to be sent to the AS/400. The list
will be built on the AS/400, and some or all of the objects (records) in the
list will be buffered down to the list on the client. Although all objects in
the list are not necessarily cached on the client, the APIs will behave as if
they are. Once the CWBSO_OpenList API is called successfully, the
following APIs can be called:
“CWBSO_GetObjHandle” on page 947
Retrieves a handle to a specific object in the list. The object handle
can then be used to manipulate the specific object.

Chapter 3. Express C/C++ APIs 921


“CWBSO_DeleteObjHandle” on page 934
Releases the handle returned by CWBSO_GetObjHandle.
“CWBSO_DisplayList” on page 939
Displays the spreadsheet view of the list.
“CWBSO_GetListSize” on page 944
Retrieves the number of objects in the list.
“CWBSO_CloseList” on page 923
Closes the list on the AS/400 and destroy all client objects in the
list. All object handles returned by CWBSO_GetListObject no
longer are valid after the list is closed. After the list is closed, the
APIs in this list cannot be called until the “CWBSO_OpenList” on
page 949 API is called again. The “CWBSO_DeleteListHandle” on
page 933 API should be called to destroy the list object.

922 Client Access Express Programming


CWBSO_CloseList
Purpose: Closes the list of objects and frees up resources allocated on the AS/400.

Syntax:

unsigned int CWB_ENTRY CWBSO_CloseList(


CWBSO_LIST_HANDLE listHandle,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error that was returned by a previous call to
CWBSO_CreateErrorHandle. When the value that is returned by this API is
CWBSO_ERROR_OCCURRED, the error handle may be used to retrieve the
error message text or display the error to the user.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_ERROR_OCCURRED
An error occurred. Use the error handle for more information.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. The list must currently be open. The list is opened by calling
CWBSO_OpenList. This API will not end the conversation with the AS/400. For
the conversation to be ended the list must be deleted using
CWBSO_DeleteListHandle.

Chapter 3. Express C/C++ APIs 923


CWBSO_CopyObjHandle
Purpose: Creates a new instance of an object and returns a handle to the new
instance. This does not create a new object on the AS/400. It merely creates an
additional instance of an AS/400 object on the client. Object handles that are
returned by CWBSO_GetObjHandle are always destroyed when the list that
contains the object is closed. This API allows the creation of an instance of the
object that will persist after the list is closed. The object instance that was created
by this API is kept in sync with the object in the list. In other words, if one of the
objects is changed, the changes will be apparent in the other object.

Syntax:

unsigned int CWB_ENTRY CWBSO_CopyObjHandle(


CWBSO_OBJ_HANDLE objectHandle,
CWBSO_OBJ_HANDLE far* lpNewObjectHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that was returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.
CWBSO_OBJ_HANDLE far* lpNewObjectHandle - output
A long pointer to a handle which will be set to a new handle for the same
AS/400 object. This handle may be used with any other API that accepts an
object handle with the exception that some APIs only operate on specific types
of objects.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_BAD_OBJ_HANDLE
The object handle that is specified is not valid.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API. When the object is
no longer needed, the calling program is responsible for doing the following:
v Call CWBSO_DeleteObjHandle to free up resources that are allocated on the
client.

924 Client Access Express Programming


CWBSO_CreateErrorHandle
Purpose: Creates an error handle. An error handle is used to contain error
messages that are returned from other APIs. The error handle may be used to
display the error in a dialog or retrieve the associated error message text.

Syntax:

unsigned int CWB_ENTRY CWBSO_CreateErrorHandle(


CWBSO_ERR_HANDLE far* lpErrorHandle);

Parameters:
CWBSO_ERR_HANDLE far* lpErrorHandle - output
A long pointer to a handle which will be set to the handle for an error.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.

Usage: When the error handle is no longer needed, the calling program is
responsible for doing the following:
v Call CWBSO_DeleteErrorHandle to free up resources that are allocated on the
client.

Chapter 3. Express C/C++ APIs 925


CWBSO_CreateListHandle
Purpose: Creates a new list and returns a handle to the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_CreateListHandle(


char far* lpszSystemName,
char far* lpszApplicationName,
CWBSO_LISTTYPE type,
CWBSO_LIST_HANDLE far* lpListHandle);

Parameters:
char far* lpszSystemName - input
The name of the AS/400 system on which the list will be built. The name that
is specified must be a configured AS/400. If the client is not currently
connected to the AS/400, a connection will be established when the list is
opened. If NULL is specified for the system name, the current Client
Access/400 default system will be used.
char far* lpszApplicationName - input
A character string that identifies the application that will be interacting with
the list. The maximum length of this string is 10 characters, excluding the
NULL terminator.
CWBSO_LISTTYPE type - input
The type of list to be built. Specify one of the following:
CWBSO_LIST_JOB
List of jobs.
CWBSO_LIST_SJOB
List of server jobs.
CWBSO_LIST_SJOB
List of server jobs.
CWBSO_LIST_MSG
List of messages.
CWBSO_LIST_PRT
List of printers.
CWBSO_LIST_SFL
List of spooled files.
CWBSO_LIST_IFC
List interfaces.
CWBSO_LIST_ELN
List Ethernet lines.
CWBSO_LIST_TLN
List token-ring lines.
CWBSO_LIST_HWL
List hardware resources.
CWBSO_LIST_SW
List software products.
CWBSO_LIST_RTE
List TCP/IP route.

926 Client Access Express Programming


CWBSO_LIST_PRF
List user profiles.
CWBSO_LIST_SMP
List libraries in QSYS.
CWBSO_LIST_HANDLE far* lpListHandle - output
A long pointer to a handle that will be set to the handle for the newly created
list. This handle may be used with any other API that accepts a list handle.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LISTTYPE
The value that is specified for type of list is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_BAD_SYSTEM_NAME
The system name that is specified is not a valid AS/400 system name.

Usage: When the list is no longer needed, the calling program is responsible for
doing the following:
v Call CWBSO_DeleteListHandle to free up resources that are allocated on the
client.

Chapter 3. Express C/C++ APIs 927


CWBSO_CreateListHandleEx
Purpose: Creates a new list and returns a handle to the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_CreateListHandleEx(


cwbCO_SysHandle systemObjectHandle,
CWBSO_LISTTYPE type,
CWBSO_LIST_HANDLE far* lpListHandle);

Parameters:
cwbCO_SysHandle systemObjectHandle - input
A handle to the system object that represents the AS/400 system on which the
list will be built. The handle specified must be for a configured AS/400.
CWBSO_LISTTYPE
The type of list to be built. Specify one of the following:
CWBSO_LIST_JOB
List of jobs.
CWBSO_LIST_SJOB
List of server jobs.
CWBSO_LIST_SJOB
List of server jobs.
CWBSO_LIST_MSG
List of messages.
CWBSO_LIST_PRT
List of printers.
CWBSO_LIST_SFL
List of spooled files.
CWBSO_LIST_IFC
List interfaces.
CWBSO_LIST_ELN
List Ethernet lines.
CWBSO_LIST_TLN
List token-ring lines.
CWBSO_LIST_HWL
List hardware resources.
CWBSO_LIST_SW
List software products.
CWBSO_LIST_RTE
List TCP/IP route.
CWBSO_LIST_PRF
List user profiles.
CWBSO_LIST_SMP
List libraries in QSYS.
CWBSO_LIST_HANDLE far* lpListHandle - output
A long pointer to a handle that will be set to the handle for the newly created
list. This handle may be used with any other API that accepts a list handle.

928 Client Access Express Programming


Return Codes: The following list shows common return values.
CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LISTTYPE
The value that is specified for type of list is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_BAD_SYSTEM_NAME
The system name that is specified is not a valid AS/400 system name.

Usage: When the list is no longer needed, the calling program is responsible for
doing the following:
v Call CWBSO_DeleteListHandle to free up resources that are allocated on the
client.

Chapter 3. Express C/C++ APIs 929


CWBSO_CreateObjHandle
Purpose: Creates a new object handle and returns a handle to the object. Use this
API to access remote object that do not conform to the list format.

Syntax:

unsigned int CWB_ENTRY CWBSO_CreateObjHandle(


char far* lpszSystemName,
char far* lpszApplicationName,
CWBSO_OBJTYPE type,
CWBSO_OBJ_HANDLE far* lpObjHandle);

Parameters:
char far* lpszSystemName - input
The name of the AS/400 system on which the object will be built. The name
that is specified must be a configured AS/400. If the client is not currently
connected to the AS/400, a connection will be established when the list is
opened. If NULL is specified for the system name, the current Client
Access/400 default system will be used.
char far* lpszApplicationName - input
A character string that identifies the application that will be interacting with
the list. The maximum length of this string is 10 characters, excluding the
NULL terminator.
CWBSO_OBJTYPE type - input
The type of object to be built. Specify the following:
v CWBSO_OBJ_TCIPATTR - TCP/IP attributes

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_BAD_SYSTEM_NAME
The system name that is specified is not a valid AS/400 system name.

Usage: When the list is no longer needed, the calling program is responsible for
doing the following:
v Call CWBSO_DeleteObjHandle to free up resources that are allocated on the
client.

930 Client Access Express Programming


CWBSO_CreateParmObjHandle
Purpose: Creates a parameter object and returns a handle to the object. A
parameter object contains a set of parameter IDs and values which may be passed
as input to other APIs.

Syntax:

unsigned int CWB_ENTRY CWBSO_CreateParmObjHandle(


CWBSO_PARMOBJ_HANDLE far* lpParmObjHandle);

Parameters:
CWBSO_PARMOBJ_HANDLE far* lpParmObjHandle - output
A long pointer to a handle which will be set to the handle for the new
parameter object.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.

Usage: When the parameter object is no longer needed, the calling program is
responsible for doing the following:
v Call CWBSO_DeleteParmObjHandle to free up resources that are allocated on
the client.

Chapter 3. Express C/C++ APIs 931


CWBSO_DeleteErrorHandle
Purpose: Deletes an error handle and frees up resources allocated on the client.

Syntax:

unsigned int CWB_ENTRY CWBSO_DeleteErrorHandle(


CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_ERR_HANDLE errorHandle - input
An error handle that is returned by a previous call to
CWBSO_CreateErrorHandle.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.

Usage: CWBSO_CreateErrorHandle must be called prior to calling this API. The


error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API.

932 Client Access Express Programming


CWBSO_DeleteListHandle
Purpose: Deletes the list of objects and frees up resources allocated on the client.

Syntax:

unsigned int CWB_ENTRY CWBSO_DeleteListHandle(


CWBSO_LIST_HANDLE listHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that is returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API.

Chapter 3. Express C/C++ APIs 933


CWBSO_DeleteObjHandle
Purpose: Deletes an object handle returned from a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.

Syntax:

unsigned int CWB_ENTRY CWBSO_DeleteObjHandle(


CWBSO_OBJ_HANDLE objectHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that is returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_OBJ_HANDLE
The object handle that is specified is not valid.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API.

934 Client Access Express Programming


CWBSO_DeleteParmObjHandle
Purpose: Deletes a parameter object handle and frees up resources allocated on
the client.

Syntax:

unsigned int CWB_ENTRY CWBSO_DeleteParmObjHandle(


CWBSO_PARMOBJ_HANDLE parmObjHandle);

Parameters:
CWBSO_PARMOBJ_HANDLE parmObjHandle - input
A handle to a parameter object that is returned by a previous call to
CWBSO_CreateParmObjHandle.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_PARMOBJ_HANDLE
The parameter object handle that is specified is not valid.

Usage: CWBSO_CreateParmObjHandle must be called prior to calling this API.


The parameter object handle that is returned by CWBSO_CreateParmObjHandle
must be passed as input to this API.

Chapter 3. Express C/C++ APIs 935


CWBSO_DisallowListActions
Purpose: Sets actions the user is not allowed to perform on objects in a list. This
affects the actions available when the list is displayed by calling
CWBSO_DisplayList. Disallowed actions do not appear in the menu bar, tool bar,
or object pop-up menus. This API can only be called once for a list, and it must be
called prior to displaying the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_DisallowListActions(


CWBSO_LIST_HANDLE listHandle,
unsigned short far* lpusActionIDs,
unsigned short usCount);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that is returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned short far* lpusActionIDs - input
A long pointer to an array of action identifier values These values identify
which actions the user will not be allowed to perform. The valid values for this
parameter depend on the type of objects in the list. See the appropriate header
files for the valid values:
v cwbsojob.h
v cwbsomsg.h
v cwbsoprt.h
v cwbsosfl.h
unsigned short usCount - input
The number of action identifier values specified.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ACTION_ID
An action ID specified is not valid for the type of list.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_NOT_ALLOWED_NOW
The action that was requested is not allowed at this time.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API.

936 Client Access Express Programming


CWBSO_DisallowListFilter
Purpose: Sets the list to disallow the user from changing the filter values for the
list. This disables the INCLUDE choice from the VIEW pull-down menu when the
list is displayed. The list is displayed by calling CWBSO_DisplayList. This API is
only meaningful for lists which are displayed by using the CWBSO_DisplayList
API. This API can only be called once for a list, and it must be called prior to
displaying the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_DisallowListFilter(


CWBSO_LIST_HANDLE listHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that is returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API.

Chapter 3. Express C/C++ APIs 937


CWBSO_DisplayErrMsg
Purpose: Displays an error message in a dialog box. This API should only be
called when CWBSO_ERROR_OCCURRED is the return value from a call to
another API. In this case, there is an error message that is associated with the error
handle.

Syntax:

unsigned int CWB_ENTRY CWBSO_DisplayErrMsg(


CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_NO_ERROR_MESSAGE
The error handle that is specified contains no error message.
CWBSO_DISP_MSG_FAILED
The request to display the message failed.

Usage: CWBSO_CreateErrorHandle must be called prior to calling this API. The


error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API.

938 Client Access Express Programming


CWBSO_DisplayList
Purpose: Displays the list in a window. From this window, the user is allowed to
perform actions on the objects in the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_DisplayList(


CWBSO_LIST_HANDLE listHandle,
HINSTANCE hInstance,
int nCmdShow,
HWND far* lphWnd ,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
HINSTANCE hInstance - input
The program instance passed to the calling program’s WinMain procedure.
int nCmdShow - input
The show window parameter passed to the calling program’s WinMain
procedure. Alternatively, any of the constants defined for the Windows API
ShowWindow() may be used.
HWND far* lphWnd - output
A long pointer to a window handle. This will be set to the handle of the
window in which the list is displayed.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message text or display the error to
the user.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_DISPLAY_FAILED
The window could not be created.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. It is not necessary to call CWBSO_OpenList or CWBSO_CloseList
when using this API. CWBSO_DisplayList handles both the opening and closing of

Chapter 3. Express C/C++ APIs 939


the list. Your program must have a message loop to receive the Windows messages
that will be sent during the use of the system object list.

This API only applies to the following list types: Jobs, Messages, Printers, Printer
Output, and Spooled Files.

940 Client Access Express Programming


CWBSO_DisplayObjAttr
Purpose: Displays the attributes window for an object. From this window, the
user is allowed to view the object attributes and change attributes that are
changeable.

Syntax:

unsigned int CWB_ENTRY CWBSO_DisplayObjAttr(


CWBSO_OBJ_HANDLE objectHandle,
HINSTANCE hInstance,
int nCmdShow,
HWND far* lphWnd ,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that was returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.
HINSTANCE hInstance - input
The program instance passed to the calling program’s WinMain procedure.
int nCmdShow - input
The show window parameter passed to the calling program’s WinMain
procedure. Alternatively, any of the constants defined for the Windows API
ShowWindow() may be used.
HWND far* lphWnd - output
A long pointer to a window handle. This will be set to the handle of the
window in which the object attributes are displayed.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_OBJ_HANDLE
The object handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_DISPLAY_FAILED
The window could not be created.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API.
CWBSO_CreateErrorHandle must be called prior to calling this API. The error
handle that is returned by CWBSO_CreateErrorHandle must be passed as input to

Chapter 3. Express C/C++ APIs 941


this API. Your program must have a message loop to receive the Windows
messages that will be sent during the use of the system object attributes window.

This API only applies to the following list types: Jobs, Messages, Printers, Printer
Output, and Spooled Files.

942 Client Access Express Programming


CWBSO_GetErrMsgText
Purpose: Retrieves the message text from an error handle. This API should only
be called when CWBSO_ERROR_OCCURRED is the return value from a call to
another API. In this case there is an error message associated with the error
handle.

Syntax:

unsigned int CWB_ENTRY CWBSO_GetErrMsgText(


CWBSO_ERR_HANDLE errorHandle ,
char far* lpszMsgBuffer ,
unsigned long ulBufferLength,
unsigned long far* lpulBytesNeeded);

Parameters:
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.
char far* lpszMsgBuffer - output
A long pointer to the output buffer where the message text will be placed. The
message text that is returned by this API will be translated text. The output
buffer is not changed when the return code is not set to CWBSO_NO_ERROR.
unsigned long ulBufferLength - input
The size, in bytes, of the output buffer argument.
unsigned long far* lpulBytesNeeded - output
A long pointer to an unsigned long that will be set to the number of bytes
needed to place the entire message text in the output buffer. When this value is
less than or equal to the size of output buffer that is specified, the entire
message text is placed in the output buffer. When this value is greater than the
size of output buffer that is specified, the output buffer contains a null string.
The output buffer is not changed beyond the bytes that are needed for the
message text. This value is set to zero when the return code is not set to
CWBSO_NO_ERROR.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_NO_ERROR_MESSAGE
The error handle that is specified contains no error message.
CWBSO_GET_MSG_FAILED
The error message text could not be retrieved.

Usage: CWBSO_CreateErrorHandle must be called prior to calling this API. The


error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. For errors which occurred on the AS/400, the message text will
be in the language that is specified for the user’s execution environment. All other
message text will be in the language that is specified in the Windows Control
Panel on the user’s personal computer.

Chapter 3. Express C/C++ APIs 943


CWBSO_GetListSize
Purpose: Retrieves the number of objects in a list.

Syntax:

unsigned int CWB_ENTRY CWBSO_GetListSize(


CWBSO_LIST_HANDLE listHandle,
unsigned long far* lpulSize,
unsigned short far* lpusStatus,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned long far* lpulSize - output
A long pointer to an unsigned long that will be set to the number of entries
currently in the list. If the list status indicates that the list is complete, this
value represents the total number of objects for the list. If the list status
indicates that the list is not completely built, this value represents the number
of objects currently available from the host and a subsequent call to this API
may indicate that more entries are available.
unsigned short far* lpusStatus - output
A long pointer to an unsigned short that will be set to indicate whether the list
is completely built. The value will be set to 0 if the list is not completely built
or it will be set to 1 if the list is completely built.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. The list must currently be open. The list is opened by calling
CWBSO_OpenList. If CWBSO_CloseList is called to close a list, CWBSO_OpenList
must be called again before this API can be called.

944 Client Access Express Programming


CWBSO_GetObjAttr
Purpose: Retrieves the value of an attribute from an object.

Syntax:

unsigned int CWB_ENTRY CWBSO_GetObjAttr(


CWBSO_OBJ_HANDLE objectHandle,
unsigned short usAttributeID,
char far* lpszBuffer,
unsigned long ulBufferLength,
unsigned long far* lpulBytesNeeded,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that was returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.
unsigned short usAttributeID - input
The identifier of the attribute to be retrieved. The valid values for this
parameter depend on the type of object. See the appropriate header files for
the valid values:
v cwbsojob.h
v cwbsomsg.h
v cwbsoprt.h
v cwbsosfl.h
char far* lpszBuffer - output
A long pointer to the output buffer where the attribute value will be placed.
The value that is returned by this API is NOT a translated string. For instance,
*END would be returned instead of Ending page for the ending page attribute
of a spooled file. See “SOA attribute special values” on page 962 for
information on special values that may be returned for each type of object. The
output buffer is not changed when the return code is not set to
CWBSO_NO_ERROR.
unsigned long ulBufferLength - input
The size, in bytes, of the output buffer argument.
unsigned long far* lpulBytesNeeded - output
A long pointer to an unsigned long that will be set to the number of bytes
needed to place the entire attribute value in the output buffer. When this value
is less than or equal to the size of output buffer that is specified, the entire
attribute value is placed in the output buffer. When this value is greater than
the size of output buffer that is specified, the output buffer contains a null
string. The output buffer is not changed beyond the bytes that are needed for
the attribute value. This value is set to zero when the return code is not set to
CWBSO_NO_ERROR.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.

Chapter 3. Express C/C++ APIs 945


CWBSO_BAD_OBJ_HANDLE
The object handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_BAD_ATTRIBUTE_ID
The attribute key is not valid for this object.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API.
CWBSO_CreateErrorHandle must be called prior to calling this API. The error
handle that is returned by CWBSO_CreateErrorHandle must be passed as input to
this API.

946 Client Access Express Programming


CWBSO_GetObjHandle
Purpose: Gets a handle to an object in a list. The object handle that is returned by
this API is valid until the list is closed or until the object handle is deleted. The
object handle may be used to call the following APIs:
v CWBSO_CopyObjHandle
v CWBSO_DeleteObjHandle
v CWBSO_DisplayObjAttr
v CWBSO_GetObjAttr
v CWBSO_RefreshObj
v CWBSO_SetObjAttr
v CWBSO_WaitForObj

Syntax:

unsigned int CWB_ENTRY CWBSO_GetObjHandle(


CWBSO_LIST_HANDLE listHandle,
unsigned long ulPosition,
CWBSO_OBJ_HANDLE far* lpObjectHandle,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that is returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned long ulPosition - input
The position of the object within the list for which a handle is needed. NOTE:
The first object in a list is considered position 0.
CWBSO_OBJ_HANDLE far* lpObjectHandle - output
A long pointer to a handle which will be set to the handle for the AS/400
object. This handle may be used with any other API that accepts an object
handle with the exception that some APIs only operate on specific types of
objects.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_BAD_LIST_POSITION
The position in list that is specified is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Chapter 3. Express C/C++ APIs 947


Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. The list must currently be open. The list is opened by calling
CWBSO_OpenList. If CWBSO_CloseList is called to close a list, CWBSO_OpenList
must be called again before this API can be called. You cannot access an object by
using this API until that object has been included in the list. For example, if you
issue this API to get the object in position 100 immediately after calling
CWBSO_OpenList, the object may not immediately available. In such instances, use
CWBSO_WaitForObj to wait until an object is available. The object handle that is
returned by this API must be deleted by a subsequent call to
CWBSO_DeleteObjHandle.

948 Client Access Express Programming


CWBSO_OpenList
Purpose: Opens the list. A request is sent to the AS/400 system to build the list.

Syntax:

unsigned int CWB_ENTRY CWBSO_OpenList(


CWBSO_LIST_HANDLE listHandle,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error that was returned by a previous call to
CWBSO_CreateErrorHandle. When the value that is returned by this API is
CWBSO_ERROR_OCCURRED, the error handle may be used to retrieve the
error message text or display the error to the user.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use the error for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API. When the list is no longer needed, the calling program is
responsible for doing the following:
v Call CWBSO_CloseList to close the list and free up resources that are allocated
on the AS/400.
v Call CWBSO_DeleteListHandle to free up resources that are allocated on the
client.

Chapter 3. Express C/C++ APIs 949


CWBSO_ReadListProfile
Purpose: Reads the filter information for the list from the Windows Registry. The
application name must have been set using the CWBSO_SetListProfile API. This
API should be called prior to opening the list by using the CWBSO_OpenList or
CWBSO_DisplayList APIs.

Syntax:

unsigned int CWB_ENTRY CWBSO_ReadListProfile(


CWBSO_LIST_HANDLE listHandle,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object that was created by a previous call to
CWBSO_CreateErrorHandle. When the value that is returned by this API is
CWBSO_ERROR_OCCURRED, the error handle may be used to retrieve the
error message text or display the error to the user.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_SYSTEM_NAME_DEFAULTED
No system name was specified on the CWBSO_CreateListHandle call for
the list.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use the error handle for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_SetListProfile must be called prior to calling this API. This API
has no effect on a list that has been opened. In order for the filter criteria in the
profile to take effect, the list must be opened after calling this API.

950 Client Access Express Programming


CWBSO_RefreshObj
Purpose: Refreshes an object’s attributes from the AS/400. Refreshes all open
System Object Access views of the object.

Syntax:

unsigned int CWB_ENTRY CWBSO_RefreshObj(


CWBSO_OBJ_HANDLE objectHandle,
HWND hWnd ,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that was returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.
HWND hWnd - input
Handle of window to receive the focus after the refresh is complete. This
parameter may be NULL. If this API is being called from an application
window procedure, then the current window handle should be supplied.
Otherwise, focus will shift to the most recently opened System Object Access
window if one is open.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_OBJ_HANDLE
The object handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API.
CWBSO_CreateErrorHandle must be called prior to calling this API. The error
handle that is returned by CWBSO_CreateErrorHandle must be passed as input to
this API.

Chapter 3. Express C/C++ APIs 951


CWBSO_ResetParmObj
Purpose: Resets a parameter object to remove any attribute values from the object.

Syntax:

unsigned int CWB_ENTRY CWBSO_ResetParmObj(


CWBSO_PARMOBJ_HANDLE parmObjHandle);

Parameters:
CWBSO_PARMOBJ_HANDLE parmObjHandle - input
A handle to a parameter object that was returned by a previous call to
CWBSO_CreateParmObjHandle.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_PARMOBJ_HANDLE
The parameter object handle is not valid.

Usage: CWBSO_CreateParmObjHandle must be called prior to calling this API.


The parameter object handle that is returned by CWBSO_CreateParmObjHandle
must be passed as input to this API.

952 Client Access Express Programming


CWBSO_SetListFilter
Purpose: Sets a filter value for a list. Depending on the type of list, various filter
values may be set. The filter values control which objects will be included in the
list when the list is built by a call to CWBSO_OpenList.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetListFilter(


CWBSO_LIST_HANDLE listHandle,
unsigned short usFilterID,
char far* lpszValue);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned short usFilterID - input
The filter identifier specifies which portion of the filter to set. The valid values
for this parameter depend on the type of objects in the list. See the appropriate
header files for the valid values:
v cwbsojob.h
v cwbsomsg.h
v cwbsoprt.h
v cwbsosfl.h
char far* lpszValue - input
The value for the filter attribute. If multiple items are specified, they must be
separated by commas. Filter value items that specify AS/400 object names
must be in uppercase. Qualified object names must be in the form of
library/object. Qualified job names must be in the form of
job-number/user/job-name. Filter value items specifying special values
(beginning with asterisk) must be specified in upper case. See “SOA attribute
special values” on page 962 for information on the special values that may be
supplied for each type of object.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_FILTER_ID
The filter ID specified is not valid for the type of list.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. This API has no effect on a list that has been opened. In order for the
filter criteria to take effect, the list must be opened after calling this API. Caution
should be used when requesting complex filters as list performance may be
adversely affected.

Chapter 3. Express C/C++ APIs 953


CWBSO_SetListProfile
Purpose: Sets the profile name by adding the application name into the Windows
Registry. Use CWBSO_ReadListProfile to read the filter information from the
Registry prior to displaying a list. Use CWBSO_WriteListProfile to write the
updated filter information to the Registry before deleting the list. If this API is not
called, CWBSO_ReadListProfile and CWBSO_WriteListProfile will have no effect.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetListProfile(


CWBSO_LIST_HANDLE listHandle,
char far* lpszKey);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or to CWBSO_CreateListHandleEx.
char far* lpszKey - input
A long pointer to a string that will be used as the key in the Windows Registry
for the list. This name could be the name of the application.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_PROFILE_NAME
The profile name that is specified is not valid.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API.

954 Client Access Express Programming


CWBSO_SetListSortFields
Purpose: Sets the sort criteria for a list. The sort criteria determines the order
objects will appear in the list when the list is built by a call to CWBSO_OpenList.
This API is only valid for lists of jobs and lists of spooled files. This API is not
allowed for lists of messages and lists of printers.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetListSortFields(


CWBSO_LIST_HANDLE listHandle,
unsigned short far* lpusSortIDs,
unsigned short usCount);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned short far* lpusSortIDs - input
A long pointer to an array of sort column identifiers. The sort IDs specified
will replace the current sort criteria for the list. The valid values for this
parameter depend on the type of objects in the list. See the appropriate header
files for the valid values:
v cwbsojob.h
v cwbsosfl.h

Note: If multiple sort IDs are specified, the order in which they appear in the
array defines the order in which sorting will take place.
unsigned short usCount - input
The number of sort column identifiers specified.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_SORT_ID
A sort ID specified is not valid for the type of list.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_SORT_NOT_ALLOWED
Sorting is not allowed for this type of list.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. This API has no effect on a list that has been opened. In order for the sort
criteria to take effect, the list must be opened after calling this API. Caution should
be used when requesting complex sorts as list performance may be adversely
affected.

Chapter 3. Express C/C++ APIs 955


CWBSO_SetListTitle
Purpose: Sets the title for a list. The title is displayed in the title bar of the
window when the list is displayed by a call to CWBSO_DisplayList.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetListTitle(


CWBSO_LIST_HANDLE listHandle ,
char far* lpszTitle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
char far* lpszTitle - input
A long pointer to a string to be used for the list title. The length of the string
must be less than or equal to 79.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_TITLE
The title that is specified is not valid.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API.

956 Client Access Express Programming


CWBSO_SetObjAttr
Purpose: Sets the value of one or more attributes of an object.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetObjAttr(


CWBSO_OBJ_HANDLE objectHandle,
CWBSO_PARMOBJ_HANDLE parmObjHandle,
unsigned short far* lpusErrorIndex,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_OBJ_HANDLE objectHandle - input
A handle to an object that was returned by a previous call to
CWBSO_GetObjHandle or CWBSO_CopyObjHandle.
CWBSO_PARMOBJ_HANDLE parmObjHandle - input
A handle to a parameter object that was returned by a previous call to
CWBSO_CreateParmObjHandle. The parameter object contains the attributes
that are to be changed for the object.
unsigned short far* lpusErrorIndex - output
If an error occurred, this value will be set to the index of the parameter item
that caused the error. The first parameter item is 1. This value will be set to 0 if
none of the parameter items were in error.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_OBJECT_HANDLE
The object handle that is specified is not valid.
CWBSO_BAD_PARMOBJ_HANDLE
The parameter object handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_CANNOT_CHANGE_ATTRIBUTE
Attribute is not changeable at this time.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_GetObjHandle or CWBSO_CopyObjHandle must be called prior


to calling this API. The object handle that is returned by CWBSO_GetObjHandle or
CWBSO_CopyObjHandle must be passed as input to this API.
CWBSO_CreateErrorHandle must be called prior to calling this API. The error
handle that is returned by CWBSO_CreateErrorHandle must be passed as input to
this API.

Chapter 3. Express C/C++ APIs 957


CWBSO_SetParameter
Purpose: Sets the value of an attribute of an object. Multiple calls may be made to
this API prior to calling CWBSO_SetObjAttr. This allows you to change several
attributes for a specific object with one call to CWBSO_SetObjAttr.

Syntax:

unsigned int CWB_ENTRY CWBSO_SetParameter(


CWBSO_PARMOBJ_HANDLE parmObjHandle,
unsigned short usAttributeID,
char far* lpszValue,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_PARMOBJ_HANDLE parmObjHandle - input
A handle to a parameter object that was returned by a previous call to
CWBSO_CreateParmObjHandle.
unsigned short usAttributeID - input
The attribute ID for the parameter to be set. The valid values for this
parameter depend on the type of object. See the appropriate header files for
the valid values:
v cwbsojob.h
v cwbsomsg.h
v cwbsoprt.h
v cwbsosfl.h
char far* lpszValue - input
A long pointer to an attribute value. Note that only ASCIIZ strings are
accepted. Binary values must be converted to strings by using the appropriate
library function. See “SOA attribute special values” on page 962 for information
on the special values that may be supplied for each type of object.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_PARMOBJ_HANDLE
The parameter object handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_CreateParmObjHandle must be called prior to calling this API.


The parameter object handle that is returned by CWBSO_CreateParmObjHandle
must be passed as input to this API. CWBSO_CreateErrorHandle must be called
prior to calling this API. The error handle that is returned by
CWBSO_CreateErrorHandle must be passed as input to this API. Calling this API

958 Client Access Express Programming


does NOT update an object’s attributes on the AS/400. You must call
CWBSO_SetObjAttr to actually update the attribute value or values on the AS/400
for the specified object.

Chapter 3. Express C/C++ APIs 959


CWBSO_WaitForObj
Purpose: Waits until an object is available in a list that is being built
asynchronously.

Syntax:

unsigned int CWB_ENTRY CWBSO_WaitForObj(


CWBSO_LIST_HANDLE listHandle,
unsigned long ulPosition,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
unsigned long ulPosition - input
The position of the desired object within the list. NOTE: The first object in a
list is considered position 0.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object. If an error occurs that there is error text for, this
handle may be used to retreive the error message and message help.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_BAD_LIST_POSITION
The position in list that is specified does not exist.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use error handle for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The list
handle that is returned by CWBSO_CreateListHandle must be passed as input to
this API. CWBSO_CreateErrorHandle must be called prior to calling this API. The
error handle that is returned by CWBSO_CreateErrorHandle must be passed as
input to this API.

960 Client Access Express Programming


CWBSO_WriteListProfile
Purpose: Writes the filter information for the list to the specified key in the
Windows registry. The key name must previously have been set using the
CWBSO_SetListProfile API. This API should be called before deleting the list. This
will save any filter criteria that was changed by the user during the
CWBSO_DisplayList API. Filter information is saved in the registry by AS/400
system and by type of list. For example, if your application accesses objects from
two different AS/400 systems, and displays all four types of lists, you would have
eight different sections in the registry that specify filter information.

Syntax:

unsigned int CWB_ENTRY CWBSO_WriteListProfile(


CWBSO_LIST_HANDLE listHandle,
CWBSO_ERR_HANDLE errorHandle);

Parameters:
CWBSO_LIST_HANDLE listHandle - input
A handle to a list that was returned by a previous call to
CWBSO_CreateListHandle or CWBSO_CreateListHandleEx.
CWBSO_ERR_HANDLE errorHandle - input
A handle to an error object that was created by a previous call to
CWBSO_CreateErrorHandle. When the value that is returned by this API is
CWBSO_ERROR_OCCURRED, the error handle may be used to retrieve the
error message text or display the error to the user.

Return Codes: The following list shows common return values.


CWBSO_NO_ERROR
No error occurred.
CWBSO_BAD_LIST_HANDLE
The list handle that is specified is not valid.
CWBSO_BAD_ERR_HANDLE
The error handle that is specified is not valid.
CWBSO_SYSTEM_NAME_DEFAULTED
No system name was specified on the CWBSO_CreateListHandle call for
the list.
CWBSO_LOW_MEMORY
Not enough memory is available for the request.
CWBSO_ERROR_OCCURRED
An error occurred. Use the error for more information.

Usage: CWBSO_CreateListHandle must be called prior to calling this API. The


list handle that is returned by CWBSO_CreateListHandle must be passed as input
to this API. CWBSO_SetListProfile must be called prior to calling this API.

Chapter 3. Express C/C++ APIs 961


SOA attribute special values
The topics that are listed below provide:
v A description of the special values that may be returned by
CWBSO_GetObjAttr, and specified on CWBSO_SetObjAttr, for each type of
object
v Any special values that may be specified on CWBSO_SetListFilter for each type
of list object
Special considerations:
v For attributes that are numeric, it is common practice for AS/400 APIs to
return negative numeric values to indicate which special value (if any)
an object attribute contains. System Object Access automatically maps
these negative numbers to their corresponding special value string. For
example, the Retrieve Spooled File Attributes (QUSRSPLA) API returns
″-1″ for page rotation if output reduction is performed automatically.
CWBSO_GetObjAttr returns “*AUTO”.
v Some list filter criteria accept multiple values. For example, it is possible
to filter a list of printers on multiple printer names. In such cases,
commas should separate the supplied values.
Where to find additional information about attribute special values:
See the OS/400 APIs topic in the AS/400 Information Center.
SOA attribute special values:
v “Job attributes”
v “Message attributes” on page 963
v “Printer attributes” on page 963
v “Printer output attributes” on page 968
v “TCP/IP interfaces attributes” on page 968
v “Ethernet lines attributes” on page 970
v “Token-ring lines attributes” on page 970
v “Hardware resources attributes” on page 970
v “Software products attributes” on page 970
v “TCP/IP routes attributes” on page 970
v “Users and groups attributes” on page 971
v “Libraries in QSYS attributes” on page 975

Job attributes: System Object Access uses the List Job (QUSLJOB) and Retrieve
Job Information (QUSRJOBI) AS/400 APIs to retrieve attributes for jobs. The
possible special values are the same as those that are documented in the OS/400
APIs: Work Management APIs topic in the AS/400 Information Center. The
following special value mappings are not documented explicitly:
CWBSO_JOB_CpuTimeUsed
If the field is not large enough to hold the actual result, QUSRJOBI returns
-1. System Object Access returns “++++”.
CWBSO_JOB_MaxCpuTimeUsed,

CWBSO_JOB_MaxTemporaryStorage,

CWBSO_JOB_DefaultWaitTime
If the value is *NOMAX, QUSRJOBI returns -1. System Object Access returns
“*NOMAX”.

962 Client Access Express Programming


CWBSO_SetListFilter accepts all special values that are supported by the List Job
(QUSLJOB) API.

Message attributes: System Object Access uses the List Nonprogram Messages
(QMHLSTM) OS/400 API to retrieve attributes for messages. The possible special
values are the same as those that are documented in the OS/400 APIs: Message
Handling APIs topic in the AS/400 Information Center.

CWBSO_SetListFilter accepts the special values that are supported by the List
Nonprogram Messages (QMHLSTM) API for Severity Criteria. In addition, a
10-character user name may be supplied, by specifying the
CWBSO_MSGF_UserName filter ID. “*CURRENT” may be used to obtain a list of
messages for the current user.

Printer attributes: System Object Access uses undocumented AS/400 APIs to


retrieve attributes for printer objects. A printer is a “logical” object that is actually a
combination of a device description, a writer, and an output queue. The attributes
and their possible values are as follows.

CWBSO_PRT_AdvancedFunctionPrinting. Whether the printer device supports Advanced Function Printing (AFP).
*NO The printer device does not support Advanced Function Printing.
*YES The printer device supports Advanced Function Printing.

CWBSO_PRT_AllowDirectPrinting. Whether the printer writer allows the printer to be allocated to a job that prints
directly to a printer.
*NO Direct printing is not allowed
*YES Direct printing is allowed.

CWBSO_PRT_BetweenCopiesStatus. Whether the writer is between copies of a multiple copy spooled file. The
possible values are Y (yes) or N (no).

CWBSO_PRT_BetweenFilesStatus. Whether the writer is between spooled files. The possible values are Y (yes) or
N (no).

CWBSO_PRT_ChangesTakeEffect. The time at which the pending changes to the writer take effect. Possible values
are:
*NORDYF
When all the current eligible files are printed.
*FILEEND
When the current spooled file is done printing.
blank No pending changes to the writer.

CWBSO_PRT_CopiesLeftToProduce. The number of copies that are left to be printed. This field is set to 0 when no
file is printing.

CWBSO_PRT_CurrentPage. The page number in the spooled file that the writer is currently processing. The page
number shown may be lower or higher than the actual page number being printed because of buffering done by the
system. This field is set to 0 when no spooled file is printing.

CWBSO_PRT_Description. The text description of the printer device.

CWBSO_PRT_DeviceName. The name of the printer device.

CWBSO_PRT_DeviceStatus. The status of the printer device. Possible values are the same as the device status that
is returned by the Retrieve Configuration Status (QDCRCFGS) API.

CWBSO_PRT_EndAutomatically. When to end the writer if it is to end automatically.

Chapter 3. Express C/C++ APIs 963


*NORDYF
When no files are ready to print on the output queue from which the writer is selecting files to be printed.
*FILEEND
When the current spooled file has been printed.
*NO The writer will not end, but it will wait for more spooled files.

CWBSO_PRT_EndPendingStatus. Whether an End Writer (ENDWTR) command has been issued for this writer.
Possible values are:
N No ENDWTR command was issued.
I *IMMED: The writer ends as soon as its output buffers are empty.
C *CNTRLD: The writer ends after the current copy of the spooled file has been printed.
P *PAGEEND: The writer ends at the end of the page.

CWBSO_PRT_FileName. The name of the spooled file that the writer is currently processing. This field is blank
when no file is printing.

CWBSO_PRT_FileNumber. The number of the spooled file that the writer is currently processing. This field is set to
0 when no spooled file is printing.

CWBSO_PRT_FormsAlignment. The time at which the forms alignment message will be sent. Possible values are:
*WTR The writer determines when the message is sent.
*FILE Control of the page alignment is specified by each file.

CWBSO_PRT_FormType. The type of form that is being used to print the spooled file. Possible values are:
*ALL The writer is started with the option to print all spooled files of any form type.
*FORMS
The writer is started with the option to print all the spooled files with the same form type before using a
different form type.
*STD The writer is started with the option to print all the spooled files with a form type of *STD.
form type name
The writer is started with the option to print all the spooled files with the form type you specified.

CWBSO_PRT_FormTypeNotification. Message option for sending a message to the message queue when this form
is finished. Possible values are:
*MSG A message is sent to the message queue.
*NOMSG
No message is sent to the message queue.
*INFOMSG
An informational message is sent to the message queue.
*INQMSG
An inquiry message is sent to the message queue.

CWBSO_PRT_HeldStatus. Whether the writer is held. The possible values are Y (yes) or N (no).

CWBSO_PRT_HoldPendingStatus. Whether a Hold Writer (HLDWTR) command has been issued for this writer.
Possible values are:
N No HLDWTR command was issued.
I *IMMED: The writer is held as soon as its output buffers are empty.
C *CNTRLD: The writer is held after the current copy of the file has been printed.
P *PAGEEND: The writer is held at the end of the page.

964 Client Access Express Programming


CWBSO_PRT_JobName. The name of the job that created the spooled file which the writer is currently processing.
This field is blank when no spooled file is printing.

CWBSO_PRT_JobNumber. The number of the job that created the spooled file which the writer currently is
processing. This field is blank when no spooled file is printing.

CWBSO_PRT_MessageKey. The key to the message that the writer is waiting for a reply. This field will be blank
when the writer is not waiting for a reply to an inquiry message.

CWBSO_PRT_MessageQueueLibrary. The name of the library that contains the message queue.

CWBSO_PRT_MessageQueueName. The name of the message queue that this writer uses for operational messages.

CWBSO_PRT_MessageWaitingStatus. Whether the writer is waiting for a reply to an inquiry message. The possible
values are Y (yes) or N (no).

CWBSO_PRT_NextFormType. The name of the next form type to be printed. Possible values are:
*ALL The writer is changed with the option to print all spooled files of any form type.
*FORMS
The writer is changed with the option to print all the spooled files with the same form type before using a
different form type.
*STD The writer is changed with the option to print all the spooled files with a form type of *STD.
form type name
The writer is changed with the option to print all the spooled files with the form type name you specified.
blank No change has been made to this writer.

CWBSO_PRT_NextFormTypeNotification. The message option for sending a message to the message queue when
the next form type is finished. Possible values are:
*MSG A message is sent to the message queue.
*NOMSG
No message is sent to the message queue.
*INFOMSG
An informational message is sent to the message queue.
*INQMSG
An inquiry message is sent to the message queue.
blank No change is pending.

CWBSO_PRT_NextOutputQueueLibrary. The name of the library that contains the next output queue. This field is
blank if no changes have been made to the writer.

CWBSO_PRT_NextOutputQueueName. The name of the next output queue to be processed. This field is blank if
no changes have been made to the writer.

CWBSO_PRT_NextSeparatorDrawer. This value indicates the drawer from which to take the separator pages if
there is a change to the writer. Possible values are:
*FILE Separator pages print from the same drawer that the spooled file prints from. If you specify a drawer
different from the spooled file that contains colored or different type paper, the page separator is more
identifiable.
*DEVD
Separator pages print from the separator drawer that is specified in the printer device description.
empty string
No pending change to the writer.
1 The first drawer.
2 The second drawer.

Chapter 3. Express C/C++ APIs 965


3 The third drawer.

CWBSO_PRT_NextSeparators. The next number of separator pages to be printed when the change to the writer
takes place. Possible values are:
*FILE The number of separator pages is specified by each file.
empty string
No pending change to the writer.
number of separators
The number of separator pages to be printed.

CWBSO_PRT_NumberOfSeparators. The number of separator pages to be printed. Possible values are:


*FILE The number of separator pages is specified by each file.
Number of separators
The number of separator pages to be printed.

CWBSO_PRT_OnJobQueueStatus. Whether the writer is on a job queue and, therefore, is not currently running.
The possible values are Y (yes) or N (no).

CWBSO_PRT_OutputQueueLibrary. The name of the library that contains the output queue from which spooled
files are selected for printing.

CWBSO_PRT_OutputQueueName. The name of the output queue from which spooled files are being selected for
printing.

CWBSO_PRT_OutputQueueStatus. The status of the output queue from which spooled files are being selected for
printing. Possible values are:
H The output queue is held.
R The output queue is released.

CWBSO_PRT_PrinterDeviceType. The type of the printer that is being used to print the spooled file. Valid values
are:
*SCS SNA (Systems Network Architecture) character stream
*IPDS Intelligent Printer Data Stream

CWBSO_PRT_SeparatorDrawer. Identifies the drawer from which the job and file separator pages are to be taken.
Possible values are:
*FILE The separator page prints from the same drawer that the file is printed from. If you specify a drawer
different from the file that contains colored or different type paper, the page separator is more identifiable.
*DEVD
The separator pages will print from the separator drawer that is specified in the printer device description.
1 The first drawer.
2 The second drawer.
3 The third drawer.

CWBSO_PRT_StartedByUser. The name of the user that started the writer.

CWBSO_PRT_Status. The overall status of the logical printer. This field is derived from the printer device status
(from the Retrieve Configuration Status QDCRCFGS API), the output queue status (from the List Printer and Writer
Status, SPLSTPRT, XPF macro) and writer status (from the Retrieve Writer Information, QSPRWTRI, API). Possible
values are:
1 Unavailable
2 Powered off or not yet available
3 Stopped

966 Client Access Express Programming


4 Message waiting
5 Held
6 Stop (pending)
7 Hold (pending)
8 Waiting for printer
9 Waiting to start
10 Printing
11 Waiting for printer output
12 Connect pending
13 Powered off
14 Unusable
15 Being serviced
999 Unknown

CWBSO_PRT_TotalCopies. The total number of copies to be printed.

CWBSO_PRT_TotalPages. The total number of pages in the spooled file. Possible values are:
number
The number of pages in the spooled file.
0 No spooled file is printing.

CWBSO_PRT_User. The name of the user who created the spooled file that the writer is currently processing. This
field is blank when no file is printing.

CWBSO_PRT_UserSpecifiedData. The user-specified data that describe the file that the writer is currently
processing. This field is blank when no file is printing.

CWBSO_PRT_WaitingForDataStatus. Whether the writer has written all the data that is currently in the spooled
file and is waiting for more data. Possible values are:
N The writer is not waiting for more data.
Y The writer has written all the data currently in the spooled file and is waiting for more data. This condition
occurs when the writer is producing an open spooled file with SCHEDULE(*IMMED) that is specified.

CWBSO_PRT_WaitingForDeviceStatus. Whether the writer is waiting to get the device from a job that is printing
directly to the printer.
N The writer is not waiting for the device.
Y The writer is waiting for the device

CWBSO_PRT_WriterJobName. The job name of the printer writer.

CWBSO_PRT_WriterJobNumber. The job number of the printer writer.

CWBSO_PRT_WriterJobUser. The name of the system user.

CWBSO_PRT_WriterStarted. Indication of whether a writer is started for this printer. Possible values are:
0 No writer is started
1 Writer is started

CWBSO_PRT_WriterStatus. The status of the writer for this printer. Possible values are:
X’01’ Started
X’02’ Ended

Chapter 3. Express C/C++ APIs 967


X’03’ On job queue
X’04’ Held
X’05’ Waiting on message

CWBSO_PRT_WritingStatus. Whether the printer writer is in writing status. The possible values are:
Y The writer is in writing status.
N The writer is not in writing status.
S The writer is writing the file separators.

System Object Access accepts a comma-separated list of printer names. Up to 100 printer names may be
specified. A special value of “*ALL” may be supplied to request a list of all printers on the AS/400.

Printer output attributes: System Object Access uses the List Spooled Files
(QUSLSPL) and Retrieve Spooled File Attributes (QUSRSPLA) AS/400 APIs to
retrieve attributes for printer output. The possible special values are the same as
those that are documented in the OS/400 APIs: Spooled File APIs topic in the
AS/400 Information Center. The following special value mappings are not
explicitly documented:
CWBSO_SFL_StartingPage
If the ending page value is to be used, QUSRSPLA returns -1. System
Object Access returns “*ENDPAGE”.
CWBSO_SFL_EndingPage
If the last page is to be the ending page, QUSRSPLA returns 0 or
2147483647. System Object Access returns “*END”.
CWBSO_SFL_MaximumRecords
If there is no maximum, QUSRSPLA returns 0. System Object Access
returns “*NOMAX”.
CWBSO_SFL_PageRotation
If no rotation is done, QUSRSPLA returns 0. System Object Access returns
“*NONE”.

An undocumented API is used to retrieve the printer device name or names for a
spooled file. The attribute and its possible values are described below.

CWBSO_SFL_DeviceNames. The name of the printer device that will print the file. If the printer output is assigned
to more than one printer device, this field contains all of the printer names in the group of printers. Possible values
are:
printer name
The name of the printer to which the printer output is assigned.
list of printer names
The names of the printers in the group to which the printer output is assigned. Commas will separate the
printer names.
empty string
The printer output is not assigned to a printer or group of printers.

CWBSO_SetListFilter accepts all special values that are supported by the List Spooled Files (QUSLSPL)
API.

TCP/IP interfaces attributes: System Object Access uses the AS/400 API TCP/IP
interface (QTOCIFCU) to retrieve attributes for TCP/IP interfaces. The possible
special values are:
CWBSO_TIF_TCPIPNetworkName

968 Client Access Express Programming


CWBSO_TIF_InternetAddress
CWBSO_TIF_BinaryInternetAddress
*RTVIFCLST only - The list of interfaces returned immediately will follow
the I/O Variable header. The interface structure will repeat for each
interface returned.
CWBSO_TIF_SubnetMask
CWBSO_TIF_AssociatedLocalInterface
CWBSO_TIF_BinaryLocalIP
*RTVIFCLST only - The list of interfaces returned immediately will follow
the I/O Variable header. The interface structure will repeat for each
interface returned.
CWBSO_TIF_LineDescriptionName
CWBSO_TIF_TypeOfLine
v 1=Ethernet
v 2=Token ring
v 3=Frame relay
v 4=Asynchronous
v 5=PPP
v 6=Wireless
v 7=X.25
v 8=DDI
v 9=Twinaxial (TDLC)
v 15=None
v 16=Error
v 17=Not found
CWBSO_TIF_MaximumTransmissionUnit
v 0000000 = Determined by Maximum frame size in Line Description.
CWBSO_TIF_TypeOfService
v 1=Normal
v 2=Minimum delay
v 3=Maximum throughput
v 4=Maximum reliability
v 5=Minimum cost
CWBSO_TIF_AutomaticStart
v 1=Yes
v 2=No
CWBSO_TIF_TokenRingBitSequence
v 1=MSB
v 2=LSB
CWBSO_TIF_Status
*RTVIFCLST only - The list of interfaces returned immediately will follow
the I/O Variable header. The interface structure will repeat for each
interface returned.
v 0=Inactive

Chapter 3. Express C/C++ APIs 969


v 1=Active
v 2=Starting
v 3=Ending
v 4=Recovery pending
v 5=Recovery cancel
v 6=Failed
v 7=Failed (TCP)
CWBSO_TIF_InterfaceName
CWBSO_TIF_PPPProfile
*RTVIFCLST only - The list of interfaces returned immediately will follow
the I/O Variable header. The interface structure will repeat for each
interface returned.
CWBSO_TIF_PPPRemoteIP
*RTVIFCLST only - The list of interfaces returned immediately will follow
the I/O Variable header. The interface structure will repeat for each
interface returned.
CWBSO_TIF_ApplicationDefined

Ethernet lines attributes: See the OS/400 APIs: Configuration APIs topic in the
AS/400 Information Center.

Token-ring lines attributes: See the OS/400 APIs: Configuration APIs topic in the
AS/400 Information Center.

Hardware resources attributes: See the OS/400 APIs: Hardware Resource APIs
topic in the AS/400 Information Center.

Software products attributes: See the OS/400 APIs: Software Product APIs topic
in the AS/400 Information Center.

TCP/IP routes attributes: System Object Access uses the AS/400 API TCP/IP
route (QTOCRTEU) to retrieve attributes for TCP/IP routes. The possible special
values are:
CWBSO_RTE_TCPIPNetworkName
CWBSO_RTE_InternetAddress
CWBSO_RTE_BinaryInternetAddress
*RTVxxxLST only - The list of routes returned immediately will follow the
I/O Variable header. The interface structure will repeat for each route
returned.
CWBSO_RTE_SubnetMask
CWBSO_RTE_BinarySubnetMask
*RTVxxxLST only - The list of routes returned immediately will follow the
I/O Variable header. The interface structure will repeat for each route
returned.
CWBSO_RTE_NextHopAddress
CWBSO_RTE_BinaryNextHop
*RTVxxxLST only - The list of routes returned immediately will follow the
I/O Variable header. The interface structure will repeat for each route
returned.

970 Client Access Express Programming


CWBSO_RTE_BindingInterface
CWBSO_RTE_BinaryBindingIP
*RTVxxxLST only - The list of routes returned immediately will follow the
I/O Variable header. The interface structure will repeat for each route
returned.
CWBSO_RTE_MaximumTransmissionUnit
CWBSO_RTE_TypeOfService
v 1=Normal
v 2=Minmum delay
v 3=Maximum throughput
v 4=Maximum reliability
v 5=Minimum cost
CWBSO_RTE_RoutePrecedence
CWBSO_RTE_RIPMetric
CWBSO_RTE_RIPRedistribution
v 1=Yes
v 2=No
CWBSO_RTE_PPPProfile
Not valid for *xxxRTE
CWBSO_RTE_PPPCallerUserid
Not valid for *xxxRTE
CWBSO_RTE_PPPCallerIP
Not valid for *xxxRTE
CWBSO_RTE_ApplicationDefined

Users and groups attributes: The possible users and groups special values are
valid:
CWBSO_USR_ProfileName
CWBSO_USR_ProfileOrGroupIndicator
CWBSO_USR_GroupHasMembers
CWBSO_USR_TextDescription
CWBSO_USR_PreviousSignonDate
CWBSO_USR_PreviousSignonTime
CWBSO_USR_SignonAttemptsNotValid
CWBSO_USR_Status
CWBSO_USR_PasswordChangeDate
CWBSO_USR_NoPasswordIndicator
CWBSO_USR_PasswordExpirationInterval
CWBSO_USR_DatePasswordExpires
CWBSO_USR_DaysUntilPasswordExpires
CWBSO_USR_SetPasswordToExpire
CWBSO_USR_DisplaySignonInformation
CWBSO_USR_UserClassName
CWBSO_USR_AllObjectAccess
CWBSO_USR_SecurityAdministration

Chapter 3. Express C/C++ APIs 971


CWBSO_USR_JobControl
CWBSO_USR_SpoolControl
CWBSO_USR_SaveAndRestore
CWBSO_USR_SystemServiceAccess
CWBSO_USR_AuditingControl
CWBSO_USR_SystemConfiguration
CWBSO_USR_GroupProfileName
CWBSO_USR_Owner
CWBSO_USR_GroupAuthority
CWBSO_USR_LimitCapabilities
CWBSO_USR_GroupAuthorityType
CWBSO_USR_SupplementalGroups
CWBSO_USR_AssistanceLevel
CWBSO_USR_CurrentLibraryName
CWBSO_USR_InitialMenuName
CWBSO_USR_InitialMenuLibraryName
CWBSO_USR_InitialProgramName
CWBSO_USR_InitialProgramLibraryName
CWBSO_USR_LimitDeviceSessions
CWBSO_USR_KeyboardBuffering
CWBSO_USR_MaximumAllowedStorage
CWBSO_USR_StorageUsed
CWBSO_USR_HighestSchedulingPriority
CWBSO_USR_JobDescriptionName
CWBSO_USR_JobDescriptionNameLibrary
CWBSO_USR_AccountingCode
CWBSO_USR_MessageQueueName
CWBSO_USR_MessageQueueLibraryName
CWBSO_USR_MessageQueueDeliveryMethod
CWBSO_USR_MessageQueueSeverity
CWBSO_USR_OutputQueue
CWBSO_USR_OutputQueueLibrary
CWBSO_USR_PrintDevice
CWBSO_USR_SpecialEnvironment
CWBSO_USR_AttentionKeyHandlingProgramName
CWBSO_USR_AttentionKeyHandlingProgramLibrary
CWBSO_USR_LanguageID
CWBSO_USR_CountryID
CWBSO_USR_CharacterCodeSetID
CWBSO_USR_ShowParameterKeywords
CWBSO_USR_ShowAllDetails
CWBSO_USR_DisplayHelpOnFullScreen
CWBSO_USR_ShowStatusMessages
CWBSO_USR_DoNotShowStatusMessages
CWBSO_USR_ChangeDirectionOfRollkey

972 Client Access Express Programming


CWBSO_USR_SendMessageToSpoolFileOwner
CWBSO_USR_SortSequenceTableName
CWBSO_USR_SortSequenceTableLibraryName
CWBSO_USR_DigitalCertificateIndicator
CWBSO_USR_CharacterIDControl
CWBSO_USR_ObjectAuditValue
CWBSO_USR_CommandUsage
CWBSO_USR_ObjectCreation
CWBSO_USR_ObjectDeletion
CWBSO_USR_JobTasks
CWBSO_USR_ObjectManagement
CWBSO_USR_OfficeTasks
CWBSO_USR_ProgramAdoption
CWBSO_USR_SaveAndRestoreTasks
CWBSO_USR_SecurityTasks
CWBSO_USR_ServiceTasks
CWBSO_USR_SpoolManagement
CWBSO_USR_SystemManagement
CWBSO_USR_OpticalTasks
CWBSO_USR_UserIDNumber
CWBSO_USR_GroupIDNumber
CWBSO_USR_DoNotSetAnyJobAttributes
CWBSO_USR_UseSystemValue
CWBSO_USR_CodedCharacterSetID
CWBSO_USR_DateFormat
CWBSO_USR_DateSeparator
CWBSO_USR_SortSequenceTable
CWBSO_USR_TimeSeparator
CWBSO_USR_DecimalFormat
CWBSO_USR_HomeDirectoryDelimiter
CWBSO_USR_HomeDirectory
CWBSO_USR_Locale
CWBSO_USR_IndirectUser
CWBSO_USR_PrintCoverPage
CWBSO_USR_MailNotification
CWBSO_USR_UserID
CWBSO_USR_LocalDataIndicator
CWBSO_USR_UserAddress
CWBSO_USR_SystemName
CWBSO_USR_SystemGroup
CWBSO_USR_UserDescription
CWBSO_USR_FirstName
CWBSO_USR_PreferredName
CWBSO_USR_MiddleName
CWBSO_USR_LastName

Chapter 3. Express C/C++ APIs 973


CWBSO_USR_FullName
CWBSO_USR_JobTitle
CWBSO_USR_CompanyName
CWBSO_USR_DepartmentName
CWBSO_USR_NetworkUserID
CWBSO_USR_PrimaryTelephoneNumber
CWBSO_USR_SecondaryTelephoneNumber
CWBSO_USR_FaxNumber
CWBSO_USR_Location
CWBSO_USR_BuildingNumber
CWBSO_USR_OfficeNumber
CWBSO_USR_MailingAddress
CWBSO_USR_MailingAddress2
CWBSO_USR_MailingAddress3
CWBSO_USR_MailingAddress4
CWBSO_USR_CCMailAddress
CWBSO_USR_CCMailComment
CWBSO_USR_MailServerFrameworkServiceLevel
CWBSO_USR_PreferredAddressFieldName
CWBSO_USR_PreferredAddressProductID
CWBSO_USR_PreferredAddressTypeValue
CWBSO_USR_PreferredAddressTypeName
CWBSO_USR_PreferredAddress
CWBSO_USR_ManagerCode
CWBSO_USR_SMTPUserID
CWBSO_USR_SMTPDomain
CWBSO_USR_SMTPRoute
CWBSO_USR_GroupMemberIndicator

Note: In release/version V4R4 and later, the following attributes are meaningful
only when Lotus Notes is installed on the AS/400:
CWBSO_USR_NotesServerName
CWBSO_USR_NotesCertifierID
CWBSO_USR_MailType
CWBSO_USR_NotesMailFileName
CWBSO_USR_CreateMailFiles
CWBSO_USR_NotesForwardingAddress
CWBSO_USR_SecurityType
CWBSO_USR_LicenseType
CWBSO_USR_MinimumNotesPasswordLength
CWBSO_USR_UpdateExistingNotesUser
CWBSO_USR_NotesMailServer
CWBSO_USR_LocationWhereUserIDIsStored
CWBSO_USR_ReplaceExistingNotesID
CWBSO_USR_NotesComment

974 Client Access Express Programming


CWBSO_USR_NotesUserLocation
CWBSO_USR_UserPassword
CWBSO_USR_NotesUserPassword
CWBSO_USR_NotesCertifierPassword
CWBSO_USR_ShortName

Libraries in QSYS attributes: See the OS/400 APIs: Object APIs topic in the
AS/400 Information Center.

Chapter 3. Express C/C++ APIs 975


976 Client Access Express Programming
Chapter 4. Developing AS/400 Operations Navigator plug-ins
AS/400 Operations Navigator—an installable component of Client Access
Express—provides a powerful graphical interface for administering and managing
AS/400 resources.
General information resources for AS/400 Operations Navigator:
v AS/400 Operations Navigator topic in the AS/400 Information Center

v AS/400 Operations Navigator Web site

The topics that are listed below describe how to add your own C++, Java, or
Visual Basic applications to the Operations Navigator tree, by using the plug-in
feature. Once you have created your new plug-in, you can take advantage of the
support that is provided by the Client Access Selective Setup program to distribute
your plug-in within your organization or to outside users and customers. This
allows your users to consolidate all of their AS/400 administration tasks into a
single application environment.
Developing AS/400 Operations Navigator plug-ins topics:
v “Operations Navigator plug-ins overview”
v “C++ plug-ins” on page 1003
v “Java plug-ins” on page 1112
v “Visual Basic plug-ins” on page 1122

Operations Navigator plug-ins overview


The following topics provide Operations Navigator plug-ins overview information:
v “About Operations Navigator plug-ins”
v “Plug-in requirements” on page 980
v “Plug-ins samples in the Express Toolkit” on page 980
v “Displaying installed plug-ins with the Operations Navigator Plug-ins tab” on
page 981
v “Server entry point for Operations Navigator plug-ins” on page 982
v “The Windows registry for Operations Navigator plug-ins” on page 982
v “Express setup file” on page 990
v “Policy template file” on page 995
v “MRI setup file” on page 996
v “Application Administration support for your plug-in” on page 996

About Operations Navigator plug-ins


How plug-ins work:
Whether you write an Operations Navigator plug-in in C++, Java or Visual
Basic programming languages, the principle is the same: you implement a
set of predefined classes and methods, which are invoked by Operations
Navigator in response to a particular user action.
How you can use plug-ins:
You can develop plug-ins that perform one or more of the following
operations:

© Copyright IBM Corp. 1999, 2000 977


v Add new context menu items to existing folders and objects in the
Operations Navigator hierarchy. This allows you to provide additional
dialogs for an object, or to launch your own applications from a folder
in the Navigator hierarchy.
v Add property pages to the property sheet for a folder or object. You can
add property pages to any object for which a property sheet already is
defined.

Note: This capability is not yet supported for Java and Visual Basic
plug-ins.
v Add new containers and objects to the hierarchy at predefined locations.
This allows you to add your own containers of specialized objects, with
unique context menus and property sheets. You can define custom
toolbars for your new containers, and implement drag-and-drop
functionality for objects in your containers.
Plug-in illustration:
The following illustration demonstrates how a Java plug-in works:
Use the plug-in support to add a new container to the Operations
Navigator tree. When the user selects the container, the plug-in’s Java code
is called to obtain the container’s contents—in this case, a list of messages
on the user’s default message queue.
AS/400 Operations Navigator dialog — messages in the message queue

Operations Navigator communicates with the Java plug-in by invoking


methods defined on a special Java interface, known as the ListManager
interface. The plug-in support defines this interface specifically for the
purpose of letting Java applications supply list data to the Navigator’s tree
and list views. To integrate your application into Operations Navigator,

978 Client Access Express Programming


you create a new Java class that implements this interface. The methods on
the new class call into your existing Java application to obtain the list data,
as shown below.

How AS/400 Operations Navigator calls an application to obtain list data

What happens when the user wants to perform an action on one of your
objects? The illustration below shows what happens when the user
right-mouses on a message object to display its context menu.

AS/400 Operations Navigator object context menu

Operations Navigator calls a predefined method on another Java interface,


ActionsManager, to obtain the list of menu items supported for message
objects. Once again, you would create a new Java class that implements
this interface: this is how you make your application’s specialized
functions available to your users through Operations Navigator.

When the user selects the menu item, the Navigator calls another
ActionsManager method to perform the action. Your ActionsManager
implementation calls your existing Java application, which then can display
a confirmation dialog or some other more sophisticated user interface
panel that allows the user to perform a specialized task.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 979


The plug-in support allows you to define actions on any of the base objects
that are supplied with Operations Navigator, as well as on new object
types that your plug-in introduces into the hierarchy. Based on its current
status, you can ″gray out″ (disable) actions that aren’t appropriate for an
object, and you can supply status bar help for each action. You also can
refresh portions of the main Navigator window after an action is
performed.

The Operations Navigator user interface is designed to let users work with
lists of AS/400 resources and to perform actions on them. The architecture
of the plug-in feature reflects this user interface design, both by defining
interfaces for working with lists of objects in a hierarchy, and for defining
actions on those objects. A third interface, DropTargetManager, is defined
to handle drag-and-drop operations. For more information, see Operations
Navigator Java interfaces.

Plug-in requirements
Operations Navigator plug-in requirements differ according to the programming
language that you use:
C++ plug-ins:
Plug-ins that are developed by using Microsoft’s Visual C++ programming
language must be written to run on Version 4.2 or later.
Java plug-ins:
Java plug-ins run on the IBM Runtime Environment for Windows, Java
Technology Edition, Version 1.1.8, and on Sun’s Java Foundation (Swing)
Classes Release 1.1.1.
Visual Basic plug-ins:
Visual Basic plug-ins run on Version 5.0 of the Visual Basic runtime
environment.

Plug-ins samples in the Express Toolkit


To enhance the functional potential of the Operations Navigator, the Client Access
Express Toolkit provides Operations Navigator programming specifications,
interfaces, services and samples that enable third-party software vendors to
develop and deliver plug-ins.
How to access sample plug-ins:
1. Link to the Client Access Express Toolkit - Operations Navigator

Plug-ins Web page


2. Select the executable file for the appropriate programming language.
Follow the instructions to download and install the sample plug-ins.

For each of the plug-in samples, there is a registry (.reg) file. See the README.txt
files in the folder and in the plug-in samples folders for detailed information.
When you double-click on the registry file, the sample plug-in registry information
is entered into Operations Navigator. When you start Operations Navigator, it
detects the new registry entry, and prompts you to scan the system. The sample
plug-in calls the AS/400, and a new Message Queue Sample function folder
appears in the tree view in the left-hand panel. When you select this function, a list
of message queues appears in the list view in the right-hand panel of the

980 Client Access Express Programming


Navigator window. Both the sample folder and the objects have context menus
associated with them, and the toolbar buttons are enabled or grayed, depending on
which object currently is selected.

The sample plug-ins illustrate how to add a new folder to the Navigator hierarchy,
and how to implement context menu items, property pages, and drop actions on
items that are defined by the plug-in. The sample folder also will accept drops of
files from file systems. This illustrates the handling of drops by the plug-in of
existing Operations Navigator objects.

Note: The capability to add new property pages to existing objects in the
Operations Navigator hierarchy isn’t yet supported for Java or for Visual
Basic plug-ins.

Displaying installed plug-ins with the Operations Navigator


Plug-ins tab
A particular AS/400 may not support all of the plug-ins that are installed on a
user’s workstation. For this reason, it is important to be able to view a list of the
installed plug-ins. The Operations Navigator Plug-ins tab provides this ability.
How to display a list of installed plug-ins:
1. In the Operations Navigator window, right-click on an AS/400 and
select Properties.
2. In the Properties dialog, select the Plug-ins tab. The installed plug-ins
are listed.
Operations Navigator Plug-ins tab

3. Select the Rescan button to scan the system and update the listing of
plug-ins that are supported by the AS/400.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 981


Operations Navigator Scan dialog

Server entry point for Operations Navigator plug-ins


An Operations Navigator plug-in can register its implementation of a procedure to
be called during the scan operation. This allows the plug-in to participate in
determining whether the plug-in’s function is activated for a given AS/400.

This procedure is known as the server entry point. The OS/400 release that is
installed on the selected AS/400 is supplied to this procedure, along with a list of
all installed software products. The plug-in can perform additional checks on the
AS/400 and on the client for dependencies that affect its ability to support the
selected system. The plug-in returns an indication of whether its function should
be activated on the specified AS/400.

Note: Only C++ plug-ins support the server entry point function. Java and Visual
Basic plug-ins are not called with a server entry point.

The scan is performed once for each AS/400 in the Client Access configuration. See
“Displaying installed plug-ins with the Operations Navigator Plug-ins tab” on
page 981 for more information about the scan operation.

The Operations Navigator sample plug-ins provide an example that illustrates how
to implement a server entry point. See “Plug-ins samples in the Express Toolkit” on
page 980 for instructions on how to access the sample plug-ins.

The Windows registry for Operations Navigator plug-ins


The Windows registry is key to the operation of an Operations Navigator
component. There are several types of registry entries, each of which serves a
distinct purpose. Sample registry files are provided on the Client Access Express

Toolkit - Operations Navigator Plug-ins Web page

Operations Navigator uses the Windows ActiveX runtime support to load a


plug-in’s components, and to obtain a pointer to an instance of the plug-in’s
implementation of a particular interface. A CLSID (pronounced ″class ID″) in the
registry uniquely identifies a specific implementation class that resides in a specific

982 Client Access Express Programming


ActiveX server DLL. The first stage of this mapping, from the CLSID to the name
and location of the server DLL, is accomplished by means of a registry entry.
Therefore, an Operations Navigator plug-in must register a CLSID for each
implementation class that it provides.
Java and Visual Basic plug-ins:
Operations Navigator provides built-in ActiveX server DLLs that manage
plug-ins written in Java and in Visual Basic. Therefore, all Java plug-ins
register the same CLSID, and all and Visual Basic register the same CLSID.
The registry files that are provided with the programming samples already
contain these predefined CLSIDs. See “Plug-ins samples in the Express
Toolkit” on page 980 for instructions on how to access the plug-in samples.

Operations Navigator requires plug-ins to supply certain other types of registry


entries:
v A ″primary″ registry key that each plug-in must define. This key includes values
that provide global information about the plug-in.
v Registry keys that identify the object types in the Operations Navigator
hierarchy for which a plug-in intends to supply additional function.
v A separate registry key for the root of each subtree of objects that a plug-in adds
to the object hierarchy. This key contains information about the root folder of the
subtree.
Information on registry files, registry keys, and their associated fields and
values:
See “Registry files for Operations Navigator plug-ins”

Registry files for Operations Navigator plug-ins


Associated with each Operations Navigator plug-in is a Windows registry file. The
entries in this file are written to the Windows registry on the user’s workstation
when Client Access Selective Setup installs a plug-in.

The file contains registry keys that identify the location of the ActiveX server DLL
that is associated with the plug-in. There also are keys that specify information that
is used by Navigator to determine the following:
v The type of function that is supplied by the plug-in
v Where in the object hierarchy the function should be activated
An Auto Refresh registry key automatically creates for your plug-in a property
sheet that supports the auto-refresh function.
Where to find information on creating a new registry file:
v “Customizing C++ plug-ins” on page 1035
v “Customizing Java plug-ins” on page 1119
v “Customizing Visual Basic plug-ins” on page 1128
These topics explain how to create a new registry file for your plug-in by
using the files that the samples provide. The topics also explain how to
tailor the registry entries so that Windows registry correctly identifies the
function your plug-in provides.
Registry keys and their associated fields and values:
v “Programmatic identifier (ProgID)” on page 984
v “Globally unique identifiers (GUIDs)” on page 984
v “Primary registry key” on page 984
v “New folder registry key” on page 986
v “Secure Sockets Layer (SSL) registry entry” on page 987
v “Shell plug-ins” on page 988

Chapter 4. Developing AS/400 Operations Navigator plug-ins 983


Programmatic identifier (ProgID): Your plug-in is uniquely identified to the
Navigator by means of a text string of the form <vendor>.<component>, where
vendor identifies the name of the vendor who developed the plug-in, and
component describes the function being provided. In the sample plug-in, the string
″IBM.Sample″ identifies IBM as the vendor, and ″Sample″ as the description of the
function that is provided by the plug-in. This string is known as the programmatic
identifier, or ProgID. It will be used throughout the registry file, and it will also
name the directory where your plug-in will reside on both the AS/400 and the
workstation.

Globally unique identifiers (GUIDs): The Component Object Model from


Microsoft uses 16-byte hex integers to uniquely identify ActiveX implementation
classes and interfaces. These integers are known as GUIDs (Globally Unique
Identifiers). GUIDs that identify implementation classes are called CLSIDs
(pronounced ″class IDs″). How to replace the CLSIDs in the sample registry file
with new GUIDs that you generate is explained in “Customizing C++ plug-ins” on
page 1035.

For Operations Navigator components written in Java and in Visual Basic, you
do not create a unique GUID. All Java plug-ins use the standard GUID that
identifies the built in ActiveX server DLL that directly calls out to all registered
Java components.

Primary registry key: The primary registry key defines a set of fields that specify
global information for the plug-in. This information is required. Note that the
subkey name must match the ProgID for your plug-in.
v “Example: Primary registry key”
v “Primary registry key fields”

Example: Primary registry key:

;--------------------------------------------------------------------
; Define the primary registry key for the plugin
; NOTE: NLS and ServerEntryPoint DLL names must not contain qualified directory paths

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample]


"Type"="PLUGIN"
"NLS"="sampmri.dll"
"NameID"=dword:00000080
"DescriptionID"=dword:00000081
"MinimumIMPIRelease"="NONE"
"MinimumRISCRelease"="030701"
"ProductID"="NONE"
"ServerEntryPoint"="sampext.dll"

Primary registry key fields: The following are descriptions of each field in the
primary registry key:
Type If the plug-in adds new folders to the Operations Navigator
hierarchy, the value of this field should be PLUGIN. Otherwise, it
should be EXT.
NLS Identifies the name of the resource DLL that contains the
locale-dependent resources for the plug-in. In the development
version of the registry file, this may be a fully-qualified pathname.
NameID A double word containing the resource identifier of the text string
in the resource DLL which will be used to identify the plug-in in
the Operations Navigator user interface.

984 Client Access Express Programming


DescriptionID A double word that contains the resource identifier of the text
string in the resource DLL. This resource DLL is used to describe
the function of the plug-in in the Operations Navigator user
interface.
MinimumIMPIRelease
A 6-character string that identifies the minimum release of OS/400
that runs on the IMPI hardware that the plug-in requires. The
string should be of the form vvrrmm, where vv is the OS/400
Version, rr is the Release, and mm is the Modification Level. For
example, if the plug-in requires Version 3 Release 2 Modification
Level 0, the value of this field should be ″030200.″
If the plug-in does not support any OS/400 release that runs on
IMPI hardware (releases prior to Version 3 Release 6), the value of
this field should be ″NONE.″ If the plug-in can support any release
that runs on IMPI hardware, the value of this field should be
″ANY.″
MinimumRISCRelease
A 6-character string that identifies the minimum release of OS/400
that runs on RISC hardware that the plug-in requires. The string
should be of the form vvrrmm, where vv is the OS/400 Version, rr
is the Release, and mm is the Modification Level. For example, if
the plug-in requires Version 3 Release 7 Modification Level 1, the
value of this field should be ″030701.″
If the plug-in does not support any OS/400 release that runs on
RISC hardware (Version 3 Release 6 and above), the value of this
field should be ″NONE.″ If the plug-in can support any release
that runs on RISC hardware, the value of this field should be
″ANY.″
ProductID
A 7-character string that specifies the product ID of a prerequisite
AS/400 licensed program that is required by the plug-in. If the
plug-in does not require that a particular licensed program be
installed on the AS/400, the value of this field should be ″NONE.″
Multiple comma-separated product IDs may be specified if
multiple IDs exist for the same product.
ServerEntryPoint
The name of the code DLL that implements the server entry point.
This entry point is called by the Operations Navigator when it
needs to determine whether the plug-in is supported on a
particular AS/400. If the plug-in does not implement the entry
point, the value of this field should be ″NONE.″ In the
development version of the registry file, this may be a
fully-qualified pathname.
JavaPath The classpath string that identifies the location of your plug-in’s
Java classes. During development of your plug-in, this field might
contain the directory paths for the directories where your class files
reside. In the production version of the registry file, it should
identify your JAR file names relative to the Client Access install
path, each preceded by the Client Access substitution variable that
represents the install path.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 985


JavaMRI The base names of the JAR files that contain locale-dependent
resources for the plug-in. Operations Navigator will search for each
JAR file after first suffixing the name with the appropriate Java
language and country identifiers. If no MRI JAR files exist for a
given locale, Operations Navigator will expect the MRI for the base
locale (usually US English) to reside in the code JAR files.

New folder registry key: A separate registry key must be defined for the root of
each subtree of objects that a plug-in chooses to add to the object hierarchy. This
key contains information specific to the root folder of the subtree.

It is important that the registry key name should be a meaningful folder name, and
must be at least four characters in length.
New folder registry key topics:
v “New folder registry key fields”
v “Example: New folder registry key” on page 987

New folder registry key fields: Following are descriptions of each of the fields in the
new folder registry key:
Parent A three-character ID that identifies the parent of the folder to be
added. One of the following IDs may be specified:

ADF Application Development folder


AS4 AS/400 folder
BKF Backup folder
BOF Basic Operations folder
CFG Configuration and Service folder
DBF Database folder
FSF File Systems folder
JMF Job Management folder
MCN Management Central folder
MCS Management Central Configuration and Service folder
MDF Management Central Definitions folder
MMF Multimedia folder
NSR Network Servers folder
NWF Network folder
SCF Security folder
UGF Users and Groups folder

Attributes A 4-byte binary field that contains the attributes for the folder, with
the indicator bytes in reverse order. See the folder attribute flags
defined for the IShellFolder::GetAttributesOf method in the
Microsoft include file SHLOBJ.H.
CLSID The CLSID of the IA4HierarchyFolder implementation that should
be called by the Operations Navigator to obtain the contents of the
folder.
For Java plug-ins, the CLSID always should be:
1827A856-9C20-11d1-96C3-00062912C9B2.
For Visual Basic plug-ins, the CLSID should always be:
040606B1-1C19-11d2-AA12-08005AD17735}.
JavaClass The fully-qualified Java class name of the ListManager

986 Client Access Express Programming


implementation that should be called by the Operations Navigator
to obtain the contents of the folder. This field should be omitted if
the plug-in is not a Java plug-in.
VBClass The Program Identifier (ProgID) of the ListManager
implementation class that should be called by Operations
Navigator to obtain the contents of the folder.
VBInterface The GUID of the ListManager implementation class’ interface.
NameID A double word that contains the resource ID of the string that
should appear as the name of the folder in the Operations
Navigator hierarchy.
DescriptionID A double word that contains the resource ID of the string that
should appear as the description of the folder in the Operations
Navigator hierarchy.
DefaultIconIndex
A double word that contains the index into the NLS resource DLL
of the plug-in for the icon that should be displayed for the folder
in the Operations Navigator hierarchy. This is a zero-based index
into the resource DLL, not the resource ID of the icon. For indexing
to work properly, the icon resource IDs should be assigned
sequentially.
OpenIconIndex
A double word that contains the index into the NLS resource DLL
of the plug-in for the icon that should be displayed for the folder
in the Operations Navigator hierarchy whenever it is selected by
the user.
AdminItem A STRING that contains the Function ID of the Application
Administration function that controls access to the folder. If this
field is omitted, no Application Administration function controls
access to the folder. If specified, this must be the function ID of a
Group or Administrable function. It cannot be the function ID of a
Product Function.
For more information on Application Administration, see
“Application Administration functions overview” on page 997.
View an example of new folder registry key:
“Example: New folder registry key”

Example: New folder registry key: The following is an example of the new folder
registry key:

;--------------------------------------------------------------------
; Register a new folder

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\folders\Sample]


"Parent"="AS4"
"Attributes"=hex:00,01,00,20
"CLSID"="{D09970E1-9073-11d0-82BD-08005AA74F5C}"
"NameID"=dword:00000082
"DescriptionID"=dword:00000083
"DefaultIconIndex"=dword:00000000
"OpenIconIndex"=dword:00000001
"AdminItem"="QIBM_SAMPLE_SMPFLR"

Secure Sockets Layer (SSL) registry entry: Operations Navigator users can
request a secure connection to an AS/400 by selecting the Use Secure Sockets

Chapter 4. Developing AS/400 Operations Navigator plug-ins 987


Layer checkbox on the Connection tab of the property sheet for AS/400 objects.
When this is done, only Operations Navigator components that are capable of
supporting SSL communications are enabled for activation by the user.

If all of a plug-in’s communications with the AS/400 are managed by using the
Client Access system handle (enter cwbCO_SysHandle), or by using the class
com.ibm.as400.access.AS400 in the case of a Java plug-in, then it should indicate
that it supports secure connections to the AS/400. For C++ plug-ins, the
cwbCO_SysHandle is obtained by calling the cwbUN_GetSystemHandle API.
When the user requests a secure connection, the Navigator automatically will
enable SSL. In the case of Java plug-ins, the AS/400 object obtained by calling the
getSystemObject method on the class com.ibm.as400.opnav.ObjectName actually
will be an instance of com.ibm.as400.access.SecureAS400. See Operations
Navigator javadoc documentation for more information.

Note: If you are running Java over SSL, and creating your own CA certificate,
Client Access GA service pack is required.

If a plug-in’s communications with the AS/400 are performed by using the Sockets
API or some other low-level communications service, then it is the responsibility of
the plug-in to support SSL if it has been requested. If the plug-in doesn’t provide
this support, it should indicate that it doesn’t support SSL as described below.
When this is done, the plug-in’s function will be disabled if the user has requested
a secure connection.
Example: Adding a registry key to enable SSL
The key is SSL under [HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY
EXTENSIONS\IBM.Sample\SSL] "Support Level"=dword:00000001 where IBM.Sample is the plu

Note: "Support Level"=dword:00000001 = supports SSL, and


"Support Level"=dword:00000000 = does NOT support SSL.
;------------------------------------------------------------------------------
; Example registry key that
says this plug-in supports SSL
{HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.Sample\SSL}
"Support Level"=dword:00000001

Shell plug-ins: The final section of the registry file contains entries that specify
which objects in the Navigator hierarchy are affected by the implementation of the
plug-in.

The registry keys map a particular node or set of nodes in the hierarchy to the
type of function supplied by the plug-in, and to the CLSID of the implementation
class which implements the function.

Notice the subkeys \Sample\*\. A pair of object type identifiers is always expected
at this level in the subkey hierarchy. The first identifier in the pair specifies the
root folder for a Navigator component. For plug-ins that add new folders, this
identifier should always match the registry key name for a root folder specified the
previous section. For plug-ins which add behaviors to existing object types, this
subkey should generally be the object type of the first-level folder under an
AS/400 container object. These type strings are defined under
HKEY_CLASSES_ROOT\IBM.AS400.Network\TYPES in the registry.

The second identifier in the pair identifies the specific object type that the plug-in
wants to affect. If * is specified, the plug-in will be called the for the folder type
identified in the parent subkey, plus all folders and objects which appear in the

988 Client Access Express Programming


hierarchy under that folder. Otherwise, a specific type identifier must be specified,
and the plug-in will then only be called for that object type.

Remember that any number of shell plug-ins may register their intent to add
function to a given object type in the Navigator hierarchy. The plug-in should
never assume that it is the only server component which is providing function for
a given object type. This applies not only to existing object types, but also to any
new objects that a plug-in may choose to define. If your plug-in is widely used,
there is nothing to prevent another vendor from extending object types that are
defined by your plug-in.

The code file based on the sample file EXTINTFC.CPP contains the code that will
be called for context menus, property pages, and drop actions. The sample code
contains checks for the object types that the sample defines. You must edit this file
and either remove these tests or change them to check for the object types for
which you wish to provide new function.

When performing checks for existing object types, you should use the 3-character
type identifiers that are defined under the key
HKEY_CLASSES_ROOT\IBM.AS400.Network\TYPES in the registry. When
performing checks for new object types that are defined by your plug-in, use a
registry key. Use the registry key that identifies the folder that you specified as
your junction point, or whatever type you will return to the Navigator when
serving data for a folder that is defined by your plug-in.

Property pages for a property sheet handler: The Microsoft Foundation Class Library
classes cannot be used to construct property pages for a property sheet handler.
However, IBM provides CExtPropertyPage, which may be used in place of the
MFC class CPropertyPage. Property pages implemented by Operations Navigator
plug-ins should subclass CExtPropertyPage. The class declaration may be found in
the header file PROPEXT.H, and the implementation is contained in the file
PROPEXT.CPP. Both files are provided as part of the sample plug-in.

Note: It is necessary to include PROPEXT.CPP in the project workspace for your


plug-in.

If a plug-in requires that a property sheet is associated with one of its own object
types, the SFGAO_HASPROPSHEET flag must be returned as part of the attributes
of the object. When this flag is on, the Navigator automatically will add Properties
to the context menu for the object. Also, when this flag is on, Navigator will call
any registered property sheet handlers to add pages to the property sheet when
the context menu item is selected.

In certain cases a plug-in may desire to implement a Properties context menu item
that is defined for one of its own object types as a standard Windows dialog
instead of a property sheet. A flag is defined for this situation that may be
returned to the Navigator on calls to IContextMenu::QueryContextMenu. If the flag
is returned, no automatic processing for Properties is performed, and it is up to the
plug-in to add the context menu item and implement the associated dialog. This
flag is documented in “Description of QueryContextMenu flags” on page 1027.

If a plug-in intends to add property pages to one of the property sheets for an
AS/400 user, the key that specifies the CLSID of the property sheet handler must
specify a PropSheet field that identifies the property sheet to which the specified
handler will add pages. An example follows.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 989


;-------------------------------------------------------------------- ;
Register a property sheet handler for the Network property sheet for AS/400 users
[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\Users
and Groups\User\PropertySheetHandlers\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]
"PropSheet"="Networks"

Valid values for the PropSheet field are:

PropSheet field valid values


Groups Personal Security or Jobs Networks
Capabilities

Groups-Before- Personal- Capabilities- Jobs-Before-All Networks-


All Before-All Before-All Before-All
Jobs-After-
Groups-After- Personal-After- Capabilities- General Networks-
Info Name After-Privileges After-Servers
Jobs-After-
Personal-After- Capabilities- Startup Networks-
Location After-Auditing After-General
Jobs-After-
Personal-After- Capabilities- Display
Mail Before-Other
Jobs-After-
Capabilities- Output
After-Other
Jobs-After-
International

To add pages to a property sheet for an AS/400 user, the plug-in must implement
the IA4PropSheetNotify interface (see “IA4PropSheetNotify interface specifications
listing” on page 1023).
Restriction:
The following restriction currently applies to property sheets for AS/400
user objects:
Multiple property sheet handlers for the various property sheets that
are associated with an AS/400 user cannot be implemented on the same
implementation class. Each property sheet requires a separate CLSID.

Express setup file


The Express setup file provides the Client Access Express Selective Setup program
information necessary to install an Operations Navigator plug-in on a client
workstation. It also provides information that allows the Client Access Express
Login Service Check program to determine when the plug-in needs to be upgraded
or serviced.

The file must be named SETUP.INI, and it must reside in the primary
<VENDOR>.<COMPONENT> directory for the plug-in on the AS/400.

The format of the file conforms to that of a standard Windows configuration (.INI)
file. The file is divided into three parts:
v Plug-in information
v Service

990 Client Access Express Programming


v Sections to identify the files to install on the client workstation

Setup file plug-in Info


The first section of the Setup file (Plug-in Info) contains global information about
the plug-in:
[Plugin Info]
Name=Sample plug-in
NameDLL=sampmri.dll
NameResID=128
Description=Sample plug-in description
DescriptionDLL=sampmri.dll
DescriptionResID=129
Version=0
VendorID=IBM.Sample
SupportExpress=YES
JavaPlugin=YES

The list below contains information about each field:


Name English name of the plug-in. This name is displayed during
installation of the plug-in when the translated name cannot be
determined.
NameDLL Name of the resource DLL that contains the translated name of the
plug-in. This DLL is located in the MRI directories of the plug-in.
NameResID Resource ID of the translated name in the MRI DLL. This field
must contain the same value as the NameID field defined in the
primary registry key for the plug-in.
Description English description of the plug-in. This description is displayed
during installation of the plug-in when the translated description
cannot be determined.
DescriptionDLL
Name of the resource DLL that contains the translated description
of the plug-in. This DLL is located in the MRI directories of the
plug-in.
DescriptionResID
Resource ID of the translated description in the MRI DLL. This
field must contain the same value as the DescriptionID field that is
defined in the primary registry key for the plug-in.
Version A numeric value that indicates the release level of the plug-in. The
Client Access Login Service Check program uses this value to
determine whether the plug-in needs to be upgraded on the client
workstation. This value must be incremented by some amount for
each new release of the plug-in.
The Version value is compared to the current Version value of the
installed plug-in that is on the client workstation. When this
Version value is greater than the one already existing on the client
workstation, the Client Access Login Service Check program
upgrades the plug-in to the new Version.
VendorID The <VENDOR>.<COMPONENT> string that is used to identify
the plug-in. This string is used to create the registry key for the
plug-in in the Client Access registry tree. The VendorID must be
identical to the <VENDOR>.<COMPONENT> portion of the path
where the plug-in will be installed on the AS/400.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 991


SupportExpress
SupportExpress is optional. This indicates that the plug-in is
supported in Client Access Express, and that it will function
correctly. If SupportExpress is set to NO or doesn’t exist, and the
user selects to install this plug-in, a dialog box titled Operations
Navigator Plug-in Not Supported will appear. This notifies you
that you will be able to install the plug-in, but that it isn’t
supported in Client Access Express. If you don’t want this dialog
box to appear every time the plug-in is installed, and you know
that the plug-in works with Client Access Express, then add
SupportExpress and set it equal to YES.
JavaPlugin JavaPlugin is used to indicate whether this is a Java plug-in. The
install process needs to do some special processing if the plug-in is
a Java plug-in. All JAR files must be installed into the
\PLUGINS\<VENDOR>.<COMPONENT> directory, and this
value is used to determine whether the install process should do
this. If the plug-in is a Java plug-in and this value is set to NO or
doesn’t exist, the plug-in may not work after it is installed.

Setup file Service


The second section of the setup file (Service) provides the Client Access Login
Service Check program with the information it requires to determine if a new fix
level of the plug-in should be applied to the client workstation:
[Service]
FixLevel=0
AdditionalSize=0

Below is a listing of the meaning of each field:


FixLevel A numeric value that indicates the service level of the plug-in. The
Client Access Login Service Check program uses this value to
determine whether the plug-in requires servicing. This value must
be incremented by some amount with each service release for a
particular Version.
The FixLevel value is compared to the current FixLevel value of
the installed plug-in on the customer’s computer. When this
FixLevel value is greater than that of the plug-in that is installed
on the client workstation, the Client Access Login Service Check
program will Service the plug-in to the new FixLevel. The value
must be reset to zero when a plug-in is upgraded to a new Version
or release level.
AdditionalSize
The amount of DASD space that is required to store any new or
additional executable files that will be added to the plug-in during
servicing. Install uses this value to determine if the workstation has
adequate disk space for the plug-in.

Identify the files


The third and final portion of the setup file contains sections that identify the files
that are to be installed on the client workstation. The section in which a file
appears identifies the locations of the source and target for each file. These file
sections are used during initial install or during an upgrade to a new Version or
release level.
[Base Files] Files that are copied to \PLUGINS\<VENDOR>.<COMPONENT>

992 Client Access Express Programming


under the Client Access install directory. Normally, the ActiveX
server DLL (and associated code DLLs) for the plug-in reside here.
For C++ and Visual Basic, the ActiveX server DLL (and associated
code DLLs) for the plug-in reside here.
For Java, the Code JAR file name will reside here.
[Shared Files] Files that are copied to the Client Access Shared directory.
[System Files] Files that are copied to the \WINDOWS\SYSTEM or
\WINNT\SYSTEM32 directory.
[Core Files] Files that are copied to the \WINDOWS\SYSTEM or
\WINNT\SYSTEM32 directory that are use counted in the registry
and are never removed. These are typically redistributable files.
[MRI Files] Files that are copied from the MRI directories of the plug-in on the
AS/400 to the CLIENT
ACCESS\MRI29XX\<VENDOR>.<COMPONENT> directories on
the workstation. This typically is where the locale-dependent
resources for a plug-in reside. This will include your Resource MRI
DLL name.
[Java MRI29xx] (where 29xx is the NLV feature code for the files)
Java files that are copied from the MRI29xx directory of the plug-in
on the AS/400 to the same directory to which the [Base Files] are
installed. This typically is where the JAR MRI29xx resources for the
plug-in reside. For each MRI29xx directory supported by the Java
plug-in, there needs to be a [Java MRI29xx] section listing those
files. This only is used by Java plug-ins.
[Help files] The .HLP and .CNT files that are copied from the MRI directories
of the plug-in on the AS/400 to the CLIENT
ACCESS\MRI29XX\<VENDOR>.<COMPONENT> directories on
the workstation. The directory path to these files is written to
HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\HELP
in the Windows registry.
[Registry files]
The Windows registry file that is associated with the plug-in.
[Dependencies]
Defines the subcomponents that must be installed before the
plug-in can be installed. The values described below are optional.
They are only needed if the plug-in requires other subcomponents
to be installed besides the Operations Navigator base support
subcomponent.
Two values are supported:
AS400_Operations_Navigator
v This value is used for legacy purposes to identify the
subcomponents that must be installed if the plug-in is
installed on Client Access V3R2M0. If the plug-in does
not support running on Client Access V3R2M0, this
value should not be specified.
v The subcomponents are specified in a comma-delimited
list. A single subcomponent is specified as a single
number (AS400_Operations_Navigator=3). The
CWBUN.H header file contains a list of constants that
are prefixed with CWBUN_OPNAV_. These constants

Chapter 4. Developing AS/400 Operations Navigator plug-ins 993


provide the numeric values that are used in the
comma-delimited list for AS400_Operations_Navigator.
AS400_Client_Access_Express
v This value is used to identify the subcomponents that
must be installed if the plug-in is installed on Client
Access Express.
v The subcomponents are specified in a comma-delimited
list. A single subcomponent is specified as a single
number (AS400_Client_Access_Express=3). The
CWBAD.H header file contains a list of constants that
are prefixed with CWBAD_COMP_. These constants
provide the numeric values that are used in the
comma-delimited list for AS400_Client_Access_Express.
There are several CWBAD_COMP_ constants that
identify PC5250 font subcomponents. These constants
must not be used in the AS400_Client_Access_Express
value and are listed below:
//5250 Display and Printer Emulator subcomponents
#define CWBAD_COMP_PC5250_BASE_KOREAN (150)
#define CWBAD_COMP_PC5250_PDFPDT_KOREAN (151)
#define CWBAD_COMP_PC5250_BASE_SIMPCHIN (152)
#define CWBAD_COMP_PC5250_PDFPDT_SIMPCHIN (153)
#define CWBAD_COMP_PC5250_BASE_TRADCHIN (154)
#define CWBAD_COMP_PC5250_PDFPDT_TRADCHIN (155)
#define CWBAD_COMP_PC5250_BASE_STANDARD (156)
#define CWBAD_COMP_PC5250_PDFPDT_STANDARD (157)
#define CWBAD_COMP_PC5250_FONT_ARABIC (158)
#define CWBAD_COMP_PC5250_FONT_BALTIC (159)
#define CWBAD_COMP_PC5250_FONT_LATIN2 (160)
#define CWBAD_COMP_PC5250_FONT_CYRILLIC (161)
#define CWBAD_COMP_PC5250_FONT_GREEK (162)
#define CWBAD_COMP_PC5250_FONT_HEBREW (163)
#define CWBAD_COMP_PC5250_FONT_LAO (164)
#define CWBAD_COMP_PC5250_FONT_THAI (165)
#define CWBAD_COMP_PC5250_FONT_TURKISH (166)
#define CWBAD_COMP_PC5250_FONT_VIET (167)
v This value is ignored by Client Access V3R2M0.

Note: Client Access Express will use the


AS400_Client_Access_Express value if it exists. If it
does not exist, it will use the
AS400_Operations_Navigator value, if it exists. If
neither value exists, then this section is ignored.

Listed below are file sections that are used while servicing a plug-in when the
FixLevel value is incremented. Note that MRI and Help files cannot be serviced.
[Service Base Files]
Files that are copied to \PLUGINS\<VENDOR>.<COMPONENT>
under the Client Access install directory.
[Service Shared Files]
Files that are copied to the Client Access Shared directory.
[Service System Files]
Files that are copied to the \WINDOWS\SYSTEM or
\WINNT\SYSTEM32 directory.
[Service Core Files]
Files that are copied to the \WINDOWS\SYSTEM or
\WINNT\SYSTEM32 directory. These files are use counted in the
registry, are never removed, and are typically redistributable files.
[Service Registry Files]
The Windows registry file that is associated with the plug-in.

994 Client Access Express Programming


The format for file entries in each file section should be n=file.ext, where n is the
number of the file in that section. The numbering must start with one (1) and
increment by one (1) until all of the files are listed in the section. For example:
[Base Files]
1=file1.dll
2=file2.dll
3=file3.dll

In all cases, only the file name and plug-in should be specified. Do not specify
directory path names.

If a file section contains no entries, the section simply is ignored.

The Client Access Toolkit provides a sample setup file for three different sample
plug-ins: C++, Java, and Visual Basic.

Policy template file


Microsoft has defined Windows system policies, which allow an administrator to
enforce certain application-defined attributes on specific workstations and users on

a network. For information on system policies, see the Microsoft Web site . The
Microsoft Windows 95 Resource Kit manual is another source of information on
system policies.

Client Access Express allows plug-ins to provide a policy template file that
administrators can use to restrict specific users or specific workstations from
installing the plug-in. Client Access Express also provides a general policy that
allows administrators to restrict users from installing any plug-in that does not
provide a policy template file. By providing its own policy template file, a plug-in
allows administrators to define install restrictions that are used only for that
plug-in. The C++ sample plug-in contains a policy template that is named
sample.adm to use for this purpose.

Note: Visual Basic and the Java plug-in samples in the Client Access Express
Toolkit do not include a policy template. Use the sample.adm template that is
included in the C++ sample plug-in.

The sample.adm file is a standard windows policy template file. It has support for
preventing a user or a specific machine from installing the sample plug-in. To
build a windows policy template file for your plug-in, do the following:
1. Copy the ’sample.adm’ file to something appropriate for your plug-in (the copy
must retain the ’adm’ extension). This file will become the policy template file
for your plug-in.
2. Refer to the comments in the copied file for details on the changes that are
required to use this template file for your plug-in. There are two required
changes:
v You will need to replace both of the ’vendor.component’ fields in this file
with the correct values for your plug-in.
v Change the string that is labeled ’PluginName’ to contain the name of your
plug-in.
3. If your plug-in has defined its own policies, add these to the copied ’adm’ file.

A policy template file is optional and does not need to be provided by every
plug-in. It should be provided only if either of the following situations exist:

Chapter 4. Developing AS/400 Operations Navigator plug-ins 995


v The plug-in will allow administrators to restrict specific users from installing the
plug-in to their workstation.

Note: If the plug-in does not provide its own policy template file, admistrators
can restrict users from installing this plug-in only by using the general
Client Access Express policy for restricting the installation of plug-ins that
do not provide a policy template file.
v The plug-in defines additional policies.
Special Considerations for plug-ins that are compatible with Client Access
(V3R2M0):
The preceding steps list the requirements for building a policy template file
that can restrict the plug-in from being installed by Client Access Express.
If your plug-in is designed to run on both Client Access Express and Client
Access (V3R2M0), you will need to provide two separate policy template
files:
v A template file for workstations that are attempting to install your
plug-in by using Client Access Express. This is described above.
v A template file for workstations attempting to install your plug-in by
using Client Access (V3R2M0).
For directions on how to create this template file, see the sample plug-in
that was included in the V3R2M0 Client Access Toolkit.

MRI setup file


The MRI setup file provides the Client Access Selective Setup program with the
information it needs to install the locale-dependent resources that are associated
with an Operations Navigator plug-in on a client PC.

You must name the file MRISETUP.INI. A version of this file must reside in the
MRI29XX subdirectory on the AS/400 for each national language that the plug-in
supports.

The format of the file conforms to that of a standard Windows configuration (.INI)
file. The file contains a single section, MRI Info. The MRI Info section provides the
Version value for the MRI of the plug-in. The MRI for the plug-in includes all
resource DLLs, as well as Help files (.HLP and .CNT) for a particular language. For
example:

[MRI Info]
Version=0

The Client Access Selective Setup program checks the Version value of the MRI
during an initial install and during an upgrade of the plug-in when incrementing
the Version or release level of the plug-in. The MRI Version value in this file must
match the Version value in the SETUP.INI file of the plug-in during the install or
upgrade. When these values do not match, the MRI files will not be copied to the
client PC. The Client Access Toolkit provides a sample MRI setup file with the
sample plug-in.

Application Administration support for your plug-in


Operations Navigator’s Application Administration support allows administrators
to control the functions that users and groups can access. If you want Application
Administration to manage which users and groups can access your plug-in, you
must define a set of functions that can be used by Application Administration to
control access to parts of your application.

996 Client Access Express Programming


Where to find detailed Application Administration information:
For more information on how an administrator would use Operations
Navigator’s Application Administration support to manage access to
applications, link to the Application Administration topic in the
Information Center.
Application Administration Support topics:
v “Application Administration functions overview”
v “Defining a plug-in’s Application Administration functions” on page 999
v “Constructing the Application Administration function hierarchy” on
page 1001
v “Altering a plug-in’s Application Administration functions in a new
release” on page 1002

Application Administration functions overview


Application Administration can be used to manage access to any application that
provides a set of Application Administration functions. These functions are
arranged in a hierarchy that is defined by the application, and can be viewed or
managed through the Application Administration feature of Operations Navigator.

There are three types of Application Administration functions:


Product function:
This is used to define the product. Each application that provides a set of
Application Administration functions must provide one and only one
Product function. This is the topmost function in the application’s
hierarchy of Application Administration functions.
Administrable function:
This is used to define an item that can be managed through Application
Administration. Each application that provides a set of Application
Administration functions must provide at least one Administrable function.
Administrable functions are ’leaf’ nodes in the application’s hierarchy of
Application Administration functions.
Group function:
Group functions are used to group together multiple Administrable and
Group functions. Group functions are optional. They allow an application
to create multiple levels in the hierarchy of Application Administration
functions. Group functions obtain their access values (Deny or Allow)
based on the access values of the functions they contain. If users have
access to at least one contained function, then they have access to its
Group function. Because of this, if your application defines a group
function, it also must define at least one function that is a child of the
group.

The following figure displays the Application Administration dialog while viewing
the Operations Navigator functions. In this example, the function titled AS/400
Operations Navigator is the Product function. Basic Operations and Job
Management are examples of Group functions. Messages, Printer Output, and
Jobs are all examples of Administrable functions.

Application Administration dialog — Operations Navigator functions

Chapter 4. Developing AS/400 Operations Navigator plug-ins 997


Each function has several attributes that must be defined by the application:
Function ID:
This is a programmatic identifier that is used to uniquely identify the
function. All function IDs must be 1 - 30 characters in length. The only
valid characters are ’A’ - ’Z’ (uppercase only), ’0’ - ’9’, ’_’, and ’.’.
Function name:
The name of the function displayed on the Application Administration
dialogs. In the figure above, Basic Operations is the name of the second
function from the top.
Function type:
This indicates whether the function is a Group, Product, or Administrable
function.
Function description:
This is a one-sentence description of the Application Administration
function.
Bitmap:
Optional. This is the bitmap that is displayed with the function in the
Application Administration dialog. If this bitmap is not provided by the
Application, Operations Navigator will use its default bitmap(s).
Open bitmap:
Optional. Ignored for Administrable functions. Group and Product
functions can specify a second bitmap that is displayed when the Group or
Product function is open (displaying its child functions) in the Application
Administration dialog. If not specified, Bitmap will be used for both open
and closed states. This attribute is ignored if the Bitmap attribute is not
specified.

998 Client Access Express Programming


Container:
This is the Function ID of the parent (or containing) Group Function. It is
used to define the hierarchy that is used by the set of Application
Administration functions that is defined by an application. It only is
allowed for Group and Administrable functions. If a function does not
indicate its Container, then it is treated as a child of its Product Function.
For example, in the figure above, if QIBM_OPNAV_BASICOPS is the
function ID of the function named Basic Operations, then the container of
the function named Messages would be QIBM_OPNAV_BASICOPS.
Sequence number:
This indicates the relative position of the function within its Container.

Defining a plug-in’s Application Administration functions


Application Administration functions are intended to be used to control access to
the main end-user interfaces of an application. For example, Operations Navigator
uses them to control the top-level folders of its hierarchy. It is expected that most
plug-ins will use Application Administration to control access to their topmost
folders in the Operations Navigator hierarchy.

The first steps to enable your plug-in to be managed by Application


Administration are:
1. Determine the interfaces to your application that you want controlled by
Application Administration functions.
2. Identify the hierarchy structure that should be used by Application
Administration to display and group the functions.

Once this is done, you will need to modify your plug-in’s registry file with the
information that defines the Application Administration functions and their
hierarchy. You either can add this registry information to your plug-in’s existing
registry file, or add it to a separate registry file that is installed with your plug-in
(The C++ sample plug-in has placed its Application Administration information in
a separate registry file for simplification purposes).

Example: Sample plug-in’s registry file for Application Administration


functions:
HKEY_CLASSES_ROOT\IBM.AS400.Network\Application_Administration\Client_Defined_Functions\Plugins\IBM.Sample]
"AIMRIDLL"="sampmri.dll"
[HKEY_CLASSES_ROOT\IBM.AS400.Network\Application_Administration\Client_Defined_Functions\Plugins\IBM.Sample\QIBM_SAMPLE_PRDFUNC]
"FuncDescID"=dword:00000129
"FuncNameID"=dword:00000080
"FunctionType"=dword:00000002

[HKEY_CLASSES_ROOT\IBM.AS400.Network\Application_Administration\Client_Defined_Functions\Plugins\IBM.Sample\QIBM_SAMPLE_SMPFLR]
"SeqNum"=dword:00000001
"Container"=""
"FunctionType"=dword:00000000
"FuncDescID"=dword:000000a5
"FuncNameID"=dword:00000082

This registry file must create a key with the following name:
HKEY_CLASSES_ROOT\IBM.AS400.Network\Application_Administration\Client_Defined_Functions\Plugins\<vendor>.<component>

where <vendor>.<component> is replaced with the value (ProgID) of your plug-in.


This key will have the following registry value:
AIMRIDLL
This value is of type STRING. It contains the name of the DLL that
contains the resources (strings and bitmaps) for the plug-in’s Application
Administration functions. The name should not be fully qualified, and
should have an extension of .dll (sampmri.dll for example).

Chapter 4. Developing AS/400 Operations Navigator plug-ins 999


If this value is not provided, then the resource DLL that is specified by the
’NLS’ value in the plug-in’s primary registry key will be used. (See
“Primary registry key fields” on page 984 for more information on the NLS
value).

The<vendor>.<component> key described above will contain a subkey for each


Application Administration function defined by the plug-in. The Function ID of the
corresponding Application Administration function will be used for this subkey’s
name.

The following registry values may exist for each of the subkeys that define
Application Administration functions. All of the resources identified below are
retrieved from the DLL that is specified by the AIMRIDLL registry value:
FuncDescID
(Required - DWORD) Resource ID of the string used as a one-sentence
description for the function.
FuncNameID
(Required - DWORD) Resource ID of the string that is used as a name for
the function.
FunctionType
(Optional - DWORD) Identifies the type of Administrable function:
0 = Administrable Function. (Default if 'FunctionType is not specified)
1 = Group Function.
2 = Product Function.

FuncBmpID
(Optional - DWORD) Resource ID of the bitmap used for the function. If
not specified, Application Administration will use a default bitmap.
OpenBmpID
(Optional - DWORD) Ignored for Administrable Functions. Resource ID of
the bitmap used when the function is open. If not provided for Group and
Product functions, the bitmap that is defined by FuncBmpID will be used
for both the open and closed states. This value is ignored if the
FuncBmpID value is not specified.
Container
(Optional - STRING) Function ID of the Group Function that is the parent
or container of the function that is being defined. If Container is not
specified or blank, then the Product Function for the application is
assumed to be the parent of the function. Product functions do not have a
Container value.
SeqNum
(Optional - DWORD) Indicates the default sort order of the function. If not
specified, it is assumed that the sequence number (SeqNum) is the
maximum value. All immediate child functions of a Group or Product
function are sorted by SeqNum value in ascending order before being
displayed in the Application Administration screens. If multiple functions
have the same SeqNum value, then those functions are sorted in ascending
order based on their function name.

Each function must have a unique Function ID. Each Function ID must adhere to
the following rules:
v It must be 1 to 30 characters in length. Valid characters are ’A’ - ’Z’ (uppercase
only), ’0’ - ’9’, ’_’, and ’.’.

1000 Client Access Express Programming


v Each Function ID must be unique. Application Administration may register the
Function ID on an AS/400. Because of this, each application should use the
following naming convention for its Function IDs:
<Company><Product><name unique within product>

All IBM products that define Application Administration functions will use
’QIBM’ as the prefix for their Function IDs.
v Once a specific Function ID is shipped with an application, that Function ID
never should be reused to control access to a different interface, even if future
versions of the application no longer use the interface that originally was
controlled by the Function ID.

Constructing the Application Administration function hierarchy


The Application Administration function hierarchy is constructed based on the
Container values that are specified in the registry entries that define the
Application Administration functions.

The Container registry field for the plug-in’s functions should be set to the
Function ID of the Group function that will contain the plug-in’s function. All of
the function IDs for the Operations Navigator Application Administration
functions are contained within the cwbunpla.h header file that is installed with the
Client Access Express Toolkit. For example:
v If your Application Administration function is to control access to a folder that
will have the AS/400 as its parent (as is done in the C++ sample plug-in), then
the Container field should be omitted or left blank.
v If your Application Administration function is to control access to a folder that
will reside within Management Central’s Central system, then it should set the
Container field to QIBM_XE1_OPNAV_MC, which is the function ID of the
application administration function that controls access to the management
central’s root folder.
v If your Application Administration function is to control access to a folder that
will reside within an Operations Navigator folder, you will need to determine
the function ID that controls access to the parent Operations Navigator folder
(all function IDs for Operations Navigator folders are listed in the
CWBUNPLA.H header). You will need to specify the function ID of the
Operations Navigator folder as the Container field value of your Application
Administration function. For example, if your plug-in has a folder that will
reside within the Operations Navigator Database folder, and access to this folder
will be controlled through Application Administration, then the application
administration function that is defined by your plug-in to control access to its
folder should set its Container value to the function ID of the Database folder
(QIBM_XD1_OPNAV_DATABASE).

If your plug-in provides a new folder, and will use Application Administration to
control access to this folder, then you will need to modify the primary registry key
that defines your new folder. The new folder’s primary registry key will need the
AdminItem value set to the function ID of the Application Administration function
that controls access to the new folder. See the “New folder registry key fields” on
page 986 for more information on folder registry key fields. Once the AdminItem
registry value is set to your new function ID, Operations Navigator will display
your folder only if the current user (AS/400 user) has access to its controlling
Application Administration function.

If your plug-in is using Application Administration functions to control access to


items other than a folder in the Operations Navigator hierarchy, your plug-in will

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1001


need to query the value of the corresponding application administration function
to determine if the user is denied or allowed access. If the user is denied access to
the application administration function, then your application should hide or
disable the item being controlled. To query the value of an application
administration function, use the cwbUN_GetAdminValue API.

Altering a plug-in’s Application Administration functions in a new


release
If an updated version of a plug-in alters the set of Application Administration
functions that a prior version of the plug-in used, additional issues must be
addressed by the updated version of the plug-in.

Application Administration stores the access settings for a plug-in’s functions on a


host AS/400. Multiple win32 clients can access this host. These clients may use
different versions of the plug-in. Therefore, plug-ins must ensure that if they
change their Application Administration functions in a later release, that they do
not make changes that are incompatible with prior releases.

The following types of changes can be made to an application’s function set across
version boundaries:
v Altering the Function Name or Function Description of a function.
v Adding a new Administrable or Group function.
v Altering a function’s bitmap(s) or its sequence number.
v ″Obsoleting″ a function (This occurs when the newer version of the application
no longer uses an Application Administration function that it shipped in a prior
release).

The following types of changes can be made to an application’s function set across
version boundaries only if the newer version contains more functions in its
Application Administration function set than the prior version contained:
v Altering the Group function of a function (altering a function’s container).
If the new version of an application does not contain more functions in its
Application Administration function set, then the Application Administration
support in Operations Navigator will not be able to determine that the newer
version’s set of functions are an Upgrade to a previous version.

The following types of changes require an application to use a completely new set
of Application Administration functions in the newer version of the application:
v Altering the type of a function (Changing a Group function to an Administrable
function, or conversely).
v Deleting a function defined in a previous release.

Note: If the newer version of the application stops by using the deleted
function, but still contains it in its set of Application Administration
functions, then this type of change is considered ″obsoleting″ a function,
and does not require the newer version of the application to use a new set
of functions.
v Altering a function’s Function ID.

This new set of Application Administration functions has no restriction on the type
of changes that can be made across version boundaries of the application (all
function IDs must be unique and can’t be reused from functions defined in prior
versions of the application). Providing a completely new set of functions should be

1002 Client Access Express Programming


avoided, since this requires an administrator to manually copy the access settings
from a prior version of the application’s functions to the newer version’s functions.

C++ plug-ins
To develop an Operations Navigator C++ plug-in, you must create an ActiveX
server DLL, which contains the plug-in’s implementation. You must provide
certain predefined information about the plug-in in the form of a Windows
registry file. This information is written to the user’s registry when the plug-in is
installed. The registry information allows Operations Navigator to identify the new
plug-in, and to call its implementation in response to appropriate user actions.
AS/400 Operations Navigator APIs required files:

Header file Import library Dynamic Link Library


cwbun.h cwbun.lib cwbun.dll
cwbunpla.h cwbapi.lib cwbunpla.dll
(Application
administration APIs)

Express Toolkit:
The Client Access Express Toolkit provides access to AS/400 Operations
Navigator header files, and links to sample programs. To access this
information, open the Express Toolkit and select AS/400 Operations —>
Operations Navigator —> C/C++.
C++ plug-ins overview topics:
v “Product architecture for Operations Navigator C++ plug-ins”
v “Operations Navigator structure and flow of control for C++ plug-ins”
Developing C++ plug-ins topics:
v “Developing Operations Navigator C++ plug-ins” on page 1030
v “Installing Operations Navigator C++ plug-ins” on page 1042
v “Identifying C++ plug-ins to Operations Navigator” on page 1042
v Operations Navigator API listing
v “Return codes unique to Operations Navigator APIs” on page 1111
Related topics:
v “AS/400 system name formats for APIs” on page 10

Product architecture for Operations Navigator C++ plug-ins


The internal architecture of the Operations Navigator product reflects that it is
intended to serve as an integration point for an extensible, broad-based operations
interface for the AS/400. Each functional component of the interface is packaged as
an ActiveX server. The Navigator learns about the existence of a particular server
component by means of entries in the Windows registry. Multiple servers may
register their request to add menu items and dialogs to a given object type in the
Navigator hierarchy. For information about the Microsoft Component Object Model

(COM) and ActiveX servers, see the Microsoft Web site .

Operations Navigator structure and flow of control for C++


plug-ins
Operations Navigator quickly is becoming the AS/400’s primary user interface.
From a programming standpoint, you should avoid building into the Navigator
any architectural limits that prevent developers from continually being able to add

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1003


new function. For this reason, Operations Navigator components are packaged as
ActiveX server DLLs. The Navigator uses Microsoft’s Component Object Model
(COM) technology to activate only the component implementations that currently
are needed to service a user request. This avoids the problem of having to load the
entire product at start up, thereby consuming the majority of Windows resources,
and impacting performance of the entire system.

For more information on COM, consult the Visual C++ online documentation or

access the Microsoft Web site .

Plug-ins work by responding to method calls from Operations Navigator that are
generated in response to user actions. For example, when a user right-clicks on an
object in the Navigator hierarchy, the Navigator constructs a context menu for the
object, and displays the menu on the screen. The Navigator obtains the menu items
by calling each plug-in that has registered its intention to supply context menu
items for the selected object type.

The functions that are implemented by a plug-in logically are grouped into
″interfaces.″ An interface is a set of logically related methods on a class that
Operations Navigator can call to perform a specific function. The Component
Object Model supports the definition of interfaces in C++ through the declaration
of an abstract class that defines a set of pure virtual functions. Classes that call the
interface are known as implementation classes. Implementation classes subclass the
abstract class definition and provide C++ code for each of the functions defined on
the interface.

A given implementation class may implement as many interfaces as the developer


chooses. When creating a new project workspace for an ActiveX server DLL in the
Developer Studio, the AppWizard generates macros that facilitate interface
implementation. Each interface is declared as a nested class on a containing
implementation class. The nested class has no member data and does not use any
functions other than those that are defined on its interface. Its methods typically
call functions on the implementation class to get and set state data, and to perform
the actual work that is defined by the interface specification.
Operations Navigator structure and flow of control for C++ plug-ins topics:
v “Operations Navigator COM interfaces for C++”
v “Operations Navigator data for C++ plug-ins” on page 1030
v “Operations Navigator services from a C++ plug-in” on page 1030

Operations Navigator COM interfaces for C++


The functions implemented by a plug-in logically are grouped into Component
Object Model (COM) interfaces. An interface is a set of logically related methods
on a class that Operations Navigator can call to perform a specific function. A
plug-in may implement one or more COM interfaces, depending on the type of
function that the developer intends to provide to the Operations Navigator. For
example, when a user right-clicks an object in the Navigator hierarchy, the
Navigator constructs a context menu for the object and displays the menu on the
screen. The Navigator obtains the menu items by calling each plug-in that has
registered its desire to supply context menu items for the selected object type. The
plug-ins pass their menu items to the Navigator when it calls their implementation
of the QueryContextMenu method on the IContextMenu interface.

IContextMenu interface defines QueryContextMenu, GetCommandString and


InvokeCommand. QueryContextMenu supplies context menu items when a user
right-clicks on an object. GetCommandString supplies help text for context menu

1004 Client Access Express Programming


items and, based on the state of the object, also indicates whether the item should
be enabled or grayed. InvokeCommand, which is called when the user clicks on a
given menu item, displays the appropriate dialog and performs the requested
action. An implementation of the IContextMenu interface is known as a ″context
menu handler.″ The Express sample plug-ins provide an illustration of how to
implement a context menu handler.

For more information on the IContextMenu interface, see the Visual C++ online
help documentation.

To add property pages to the property sheet for an object in the Navigator
hierarchy, your plug-in implements the IPropSheetExt interface. The single method
of interest on this interface is AddPages. The Navigator calls AddPages when
construction of the property sheet for an object is in progress. The method creates
the property page or pages it intends to add by using standard Windows APIs. It
then adds the pages by calling a function that was passed to it as a parameter.

An implementation of the IPropSheetExt interface is known as a ″property sheet


handler.″ The sample plug-in provides an illustration of how to use a property
sheet handler. For more information on the IPropSheetExt interface, see the Visual
C++ online help documentation.

Two interfaces, IDropTarget and IPersistFile, can be used to add drag-and-drop


support to your plug-in. The Navigator automatically allows the user to drag any
object, but your plug-in must implement these two interfaces to accept the drop. A
folder that can accept a drop is called a Drop Handler. The Load method of
IPersistFile is passed the current drop handler folder name. The IDropTarget
interface defines four methods. The DragEnter and DragLeave methods are called
when the user drag enters and leaves the drop handler. While the user is over the
handler, the DragOver method is called. The Drop method is called when the user
completes the drag by dropping the object on the drop handler.

The sample plug-in provides an illustration of how to use the IDropTarget and
IPersistFile interfaces. The sample implements the drag and drop of Operations
Navigator file and sample objects to the sample folder. For more information on
these interfaces, see the Visual C++ online help documentation.

The ″Users and Groups″ component of the Operations Navigator is a unique case
where property pages are concerned. Selecting Properties for an AS/400 user
displays a dialog that has a group of several buttons at the bottom. Selecting each

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1005


button calls a separate property sheet.

When making changes in an Operations Navigator property dialog, the user


expects that clicking OK in the main dialog will close the dialog and make the
changes permanent. Alternatively, the user expects that clicking Cancel in the main
dialog will make no permanent changes.

An additional interface, IA4PropSheetNotify, notifies third-party property pages


when the main dialog closes. IA4PropSheetNotify defines methods that
communicate information to the plug-in, for example whether the AS/400 user
whose properties are being displayed already exists or is being defined, and
whether changes should be saved or discarded. IA4PropSheetNotify is an IBM
interface. See “Description of IA4PropSheetNotify interface” on page 1023 for more
information.

For a plug-in to add new folders to the Operations Navigator hierarchy, it must
use the IA4HierarchyFolder interface. The purpose of this interface is to supply
the data used to populate the contents of a new folder that your plug-in added to
the Navigator hierarchy. It also defines methods for specifying list view columns
and their headings, and for defining a custom toolbar that is associated with a
folder. IA4HierarchyFolder is an IBM interface.

See the following topics for more information:


v “Description of IA4HierarchyFolder Interface”
v “IA4HierarchyFolder interface specifications listing” on page 1007
v “Description of IA4PropSheetNotify interface” on page 1023
v “IA4PropSheetNotify interface specifications listing” on page 1023
v “Description of QueryContextMenu flags” on page 1027
v “Description of server entry point” on page 1028
v “IA4CheckIfSupported server entry point interface specification listing” on
page 1028

Description of IA4HierarchyFolder Interface: The IA4HierarchyFolder interface


describes a set of functions that the independent software vendor will implement.
IA4HierarchyFolder is a component object model (COM) interface that IBM

1006 Client Access Express Programming


defined for the purpose of allowing third parties to add new folders and objects to
the Operations Navigator hierarchy. For a description of the Microsoft COM, see

the Microsoft Web site .

The Operations Navigator program calls the methods on the IA4HierarchyFolder


interface whenever it needs to communicate with the third-party plug-in. The
primary purpose of the interface is to supply the Navigator with list data that will
be used when displaying the contents of a folder defined by the plug-in. The
methods on the interface allow the Navigator to bind to a particular third-party
folder and enumerate its contents. There are methods for returning the number of
columns in the details view and their associated headings. Additional methods
exist that supply the specifications for a custom toolbar to be associated with the
folder.

The interface implementation is typically compiled and linked into an ActiveX


server Dynamic Link Library (DLL). The Navigator learns about the existence of
the new DLL by means of entries in the Windows registry. These entries specify
the location of the DLL on the user’s personal computer and the ″junction point″ in
the object hierarchy where the new folder or folders are to be inserted. The
Navigator the loads the DLL at the appropriate time and calls methods on the
IA4HierarchyFolder interface as needed.

The header file CWBA4HYF.H contains declarations of the interface prototype and
associated data structures and return codes.

IA4HierarchyFolder interface specifications listing: A data entity (or ″item


identifier″) identifies all folders and objects in the Windows namespace. Item
identifiers are like filenames in a hierarchical file system. The Windows namespace
is, in fact, a hierarchical namespace with its root at the Desktop.

An item identifier consists of a two-byte count field that is followed by a binary


data structure of variable length (see the SHITEMID structure in the Microsoft
header file SHLOBJ.H). This item identifier uniquely describes an object relative to
the parent folder of the object.

The Operations Navigator uses item identifiers that adhere to the following given
structure that must be returned by IA4HierarchyFolder::ItemAt.
<cb><item name>\x01<item type>\x02<item index>

where
<cb> is the size in bytes of the item identifier, including the count field itself
<item name> is the translated name of the object, suitable for displaying to the
user
<item type> is a unique language-independent string that identifies the object
type. It must be at least four characters in length.
<item index> is the zero-based index that identifies the position of the object
within the list of parent folder objects.

Link to any of the following IA4HierarchyFolder specifications:


“IA4HierarchyFolder::Activate” on page 1009
“IA4HierarchyFolder::BindToList” on page 1010
“IA4HierarchyFolder::Deactivate” on page 1011
“IA4HierarchyFolder::DisplayErrorMessage” on page 1012

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1007


“IA4HierarchyFolder::GetAttributesOf” on page 1013
“IA4HierarchyFolder::GetColumnDataItem” on page 1014
“IA4HierarchyFolder::GetColumnInfo” on page 1015
“IA4HierarchyFolder::GetIconIndexOf” on page 1016
“IA4HierarchyFolder::GetItemCount” on page 1017
“IA4HierarchyFolder::GetToolBarInfo” on page 1018
“IA4HierarchyFolder::GetListObject” on page 1019
“IA4HierarchyFolder::ItemAt” on page 1020
“IA4HierarchyFolder::ProcessTerminating” on page 1021
“IA4HierarchyFolder::Refresh” on page 1022

1008 Client Access Express Programming


IA4HierarchyFolder::Activate:

Purpose: Places the IA4HierarchyFolder instance in an activated state. This


function also performs any processing that is needed to prepare a folder for
enumeration, including calling the AS/400 to prime the cache of folder objects on
the client. The function is called from a data thread so that long running
operations will not degrade the performance of the user interface. This is a
required member function.

Syntax:

HRESULT STDMETHODCALLTYPE Activate();

Return Codes: Returns NOERROR if successful or E_FAIL if unable to obtain the


contents of the folder.

Comments: The Operations Navigator calls this function the first time a user
selects or expands a folder. It is called again, after a call to Close, when the user
has requested a refresh of the folder contents.

The function may be called at other times whenever a pointer to the folder
interface needs to be reestablished. An example would be when the user selects a
folder a second time, after having selected another folder. The function should
simply return TRUE if the associated processing has already been performed.

For extremely large lists, you may choose to return from Activate before the list is
completely constructed, after having first created a worker thread to continue
building the list. If this is the case, make sure that your implementation of
GetListSize returns the correct indication of whether the list is completely
constructed.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1009


IA4HierarchyFolder::BindToList:

Purpose: Returns an instance of IA4HierarchyFolder that corresponds to a


particular folder in the Operations Navigator hierarchy. This is a required member
function.

Syntax:

HRESULT STDMETHODCALLTYPE BindToList(


HWND hwnd,
LPCITEMIDLIST pidl,
REFIID riid,
LPVOID* ppvOut
);

Parameters:
hwnd
Handle of the view window which will display the list (may be either a tree or
list control). A component should use this handle to determine if a list of
objects for this view is already cached on the client.
pidl
Pointer to an ITEMIDLIST (item identifier list) structure that uniquely
identifies the folder to be enumerated.
riid
Identifier of the interface to return. This parameter points to the
IID_IA4HierarchyFolder interface identifier.
ppvOut
Address that receives the interface pointer. If an error occurs, a NULL pointer
should be returned at this address.

Return Codes: Returns NOERROR if successful or E_FAIL if a general error


occurred.

Comments: If an instance of IA4HierarchyFolder already exists for the specified


folder, then this member function should return the cached instance instead of
instantiating and initializing a separate instance. However, if the window handle
associated with the cached object is not the same as the value specified on the
hwnd parameter, then a new instance should be created.

The function should initialize implementation class member variables from the
parameters supplied.

1010 Client Access Express Programming


IA4HierarchyFolder::Deactivate:

Purpose: Places the IA4HierarchyFolder instance in a deactivated state. This is a


required member function.

Syntax:

HRESULT STDMETHODCALLTYPE Deactivate();

Return Codes: Returns NOERROR if successful or E_FAIL if a general error


occurred.

Comments: This function is called when the user has requested a refresh of the
contents of an Operations Navigator folder. The function should destroy cached
folder objects and set any state variables required to force a rebuild of the cache on
the next call to Activate.

The function may be called multiple times in succession. It should simply return
TRUE if the associated processing has already been performed.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1011


IA4HierarchyFolder::DisplayErrorMessage:

Purpose: Called to display an error message to the end user whenever Activate
returns an error. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE DisplayErrorMessage();

Return Codes: Returns NOERROR if successful or an E_FAIL if there is no message


to display.

Comments: None

1012 Client Access Express Programming


IA4HierarchyFolder::GetAttributesOf:

Purpose: Returns the attributes of a particular folder in the Operations Navigator


hierarchy. The attribute indicators are the same as those defined for the Microsoft
interface method IShellFolder::GetAttributesOf. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetAttributesOf(


LPCITEMIDLIST pidl,
ULONG* ulfInOut
);

Parameters:
pidl
Pointer to an ITEMIDLIST (item identifier list) structure that uniquely
identifies the object whose attributes are to be retrieved.
ulfInOut
The returned object attributes. On input, this parameter will be set to indicate
which object attributes to retrieve.

Return Codes: Returns NOERROR if successful or E_FAIL if unable to locate the


object attributes.

Comments: Refer to the Windows include file shlobj.h for constants that define the
bit flags.

This function is called repeatedly by the Operations Navigator when populating a


tree or list view. Long running operations should therefore be avoided.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1013


IA4HierarchyFolder::GetColumnDataItem:

Purpose: Returns a data field for a folder or object to be displayed in a column in


the list view of the Operations Navigator. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetColumnDataItem(


LPCITEMIDLIST pidl,
LPARAM lParam,
char * lpszColumnData,
UINT cchMax
);

Parameters:
pidl
Pointer to an ITEMIDLIST (item identifier list) structure that uniquely
identifies the object whose column data is to be obtained.
lParam
The value that was previously associated with the column for which data is
requested by the component (see GetColumnInfo).
lpszColumnData
Address of the buffer that will receive the null-terminated data string.
cchMax
Size of the buffer that will receive the null-terminated data string.

Return Codes: Returns NOERROR if successful or an E_FAIL if unable to retrieve


the column data.

Comments: This function is called repeatedly by the Operations Navigator when


populating a list view. Long running operations should therefore be avoided.

1014 Client Access Express Programming


IA4HierarchyFolder::GetColumnInfo:

Purpose: Returns a data structure that describes the columns needed to display the
contents of a particular folder in a details view. This is an optional member
function.

Syntax:

HRESULT STDMETHODCALLTYPE GetColumnInfo(


LPVOID* ppvInfo
);

Parameters:
ppvInfo

The returned data structure. The returned structure should consist of an


instance of the A4hyfColumnInfo structure. This structure contains an array of
A4hyfColumnItem structures, one for each column in the list view.

Each column item structure supplies the translated string for the column
heading, the default width of the column, and an integer value that uniquely
identifies the data field that supplies data for the column. Refer to
CWBA4HYF.H.

Return Codes: Returns NOERROR if successful or E_NOTIMPL if unable to


implement the function.

Comments: The Operations Navigator calls this function after the call to Open has
returned, to create the column headings for a details view.

If this function is not implemented, the Navigator will insert two columns: Name
and Description. GetColumnDataItem must be capable of returning data for these
two fields, which are identified with integer values of 0 and 1, respectively.

Use the Windows IMalloc interface to allocate memory for the returned structures.
The Navigator will be responsible for deleting this memory.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1015


IA4HierarchyFolder::GetIconIndexOf:

Purpose: Returns the index into the component resource DLL that may be used to
load the icon for the hierarchy folder. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetIconIndexOf(


LPCITEMIDLIST pidl,
UINT uFlags,
int* piIndex
);

Parameters:
pidl
Pointer to an ITEMIDLIST (item identifier list) structure that uniquely
identifies the object whose icon index is to be retrieved.
uFlags
This parameter may be zero, or it may contain the value GIL_OPENICON,
indicating that the icon which should be supplied is an open folder.
GIL_OPENICON is defined in the Windows include file SHLOBJ.H.
piIndex
Pointer to an integer that receives the icon index.

Return Codes: Returns NOERROR if successful or E_FAIL if unable to determine


the index.

Comments: Operations Navigator repeatedly calls this function when populating a


tree or list view. Long running operations should therefore be avoided.

1016 Client Access Express Programming


IA4HierarchyFolder::GetItemCount:

Purpose: Returns the total count of objects contained in a particular folder in the
Operations Navigator hierarchy. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetItemCount(


ULONG* pCount
);

Parameters:
pCount
Pointer to a long integer that will receive the count of items in the list.

Return Codes: Returns A4HYF_OK_LISTCOMPLETE if the list is completely built


and the total count of items is known. Returns A4HYF_OK_LISTNOTCOMPLETE
if the list is still being constructed; in this situation the item count represents the
count of items in the partially constructed list. Returns
A4HYF_E_LISTDATAERROR if an error is encountered while constructing the list;
in this situation the item count represents only the items that are already cached
on the client.

Comments: Following a successful return from Activate, Navigator calls this


function to obtain the count of objects for the folder that is about to be populated.
Following the call to this function, Navigator repeatedly calls ItemAt to obtain the
item identifiers for the objects in the folder.

For extremely large lists, you may choose to return from Activate before the entire
list has been cached on the client. If this is the case, you should return
A4HYF_OK_LISTNOTCOMPLETE from GetItemCount. From that point on,
GetItemCount will be called by the Operations Navigator every 10 seconds until
A4HYF_OK_LISTCOMPLETE or A4HYF_E_LISTDATAERROR is returned.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1017


IA4HierarchyFolder::GetToolBarInfo:

Purpose: Returns a structure that describes the custom tool bar that is associated
with the specified folder in the Operations Navigator hierarchy. This is a required
member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetToolBarInfo(


LPCITEMIDLIST pidl,
LPVOID* ppvInfo
);

Parameters:
pidl
Pointer to an ITEMIDLIST (item identifier list) structure that uniquely
identifies the object for which tool bar information is to be retrieved.
ppvInfo
The returned data structure. An instance of A4hyfToolBarInfo should be
returned in this pointer. This structure supplies the count of toolbar buttons for
the object, the address of an array of TBBUTTON structures containing the
attributes for each button, and the instance handle of the plug-in. Refer to
CWBA4HYF.H.

Return Codes: Returns NOERROR if successful or E_NOTIMPL if you choose not


to implement the function.

Comments: This function is called each time a user selects a folder or object that
belongs to an Operations Navigator plug-in.

Use the Windows IMalloc interface to allocate memory for the returned structure.
The Navigator will be responsible for deleting this memory.

If this member function is not implemented, the default Operations Navigator tool
bar will be used. This toolbar contains Copy, Paste, Delete, Properties, buttons for
the four list views, and Refresh. The Operations Navigator calls the
implementation of IContextMenu::GetCommandString (with the GCS_VALIDATE
flag set) that is in your product to discover which of the toolbar buttons should be
enabled for your objects.

1018 Client Access Express Programming


IA4HierarchyFolder::GetListObject:

Purpose: Given a fully-qualified object name, this function returns a pointer to a


cached proxy object created by the plug-in. This is an optional member function.

Syntax:

HRESULT STDMETHODCALLTYPE GetListObject(


const char * lpszObjectName,
LPVOID* ppvObj
);

Parameters:
lpszObjectName
The fully-qualified object name for which a list object will be returned.
ppvObj
The returned pointer to an implementation-defined object. The calling routine
should cast this pointer to an appropriate object type.

Return Codes: Returns NOERROR if successful or E_NOTIMPL if you choose not


to implement the function.

Comments: Calls to this function occur whenever your plug-in code calls
cwbUN_GetListObjectFromName or cwbUN_GetListObjectFromPidl to obtain a
″proxy″ object that was instantiated by the Activate method. The plug-in uses this
proxy object to access data on the AS/400, or to perform actions on the AS/400.
Because IA4HierarchyFolder implementation maintains the cache of proxy objects,
the calling program should not attempt to delete the object.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1019


IA4HierarchyFolder::ItemAt:

Purpose: Returns as SHITEMID (item identifier) structure for the folder object at
the specified position in the list of folder contents. This is a required member
function.

Syntax:

HRESULT STDMETHODCALLTYPE ItemAt(


ULONG ulIndex,
LPITEMIDLIST* ppidl
);

Parameters:
ulIndex
The zero-based index of the item for which an item identifier is requested.
ppidl
Address of the pointer that will receive the requested item identifier.

Return Codes: Returns NOERROR if successful or E_FAIL if the item is not


available. Returns E_OUTOFMEMORY if insufficient memory was available for the
item identifier.

Comments: The Operations Navigator repeatedly calls this function to populate a


folder in realtime. Long running operations should therefore be avoided. Refer to
CWBA4HYF.H for the format of Operations Navigator item identifiers. Use the
Windows IMalloc interface to allocate memory for the item identifier.

1020 Client Access Express Programming


IA4HierarchyFolder::ProcessTerminating:

Purpose: Call to this function occur when the user closes the Operations Navigator
window to provide the plug-in with an opportunity to save persistent data. This is
an optional member function.

Syntax:

HRESULT STDMETHODCALLTYPE ProcessTerminating();

Return Codes: Returns NOERROR if successful or E_NOTIMPL if you choose not


to implement the function. Error returns are ignored.

Comments: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1021


IA4HierarchyFolder::Refresh:

Purpose: Destroys any cached folder objects and rebuilds the cache using new data
obtained from the AS/400. This is a required member function.

Syntax:

HRESULT STDMETHODCALLTYPE Refresh();

Return Codes: Returns NOERROR if successful or A4HYF_E_LISTDATAERROR if


an error occurred when accessing the objects in the folder.

Comments: Operations Navigator calls this function is called whenever a


performing a global refresh of the main Operations Navigator window.

1022 Client Access Express Programming


Description of IA4PropSheetNotify interface: Like the IA4HierarchyFolder
interface, the IA4PropSheetNotify interface describes a set of functions that the
independent software vendor will implement. IA4PropSheetNotify is a COM
interface IBM defined to allow third parties to add new property pages to any
property sheet that the Operations Navigator defines for an AS/400 user.

The Operations Navigator program calls the methods on the IA4PropSheetNotify


interface whenever it needs to communicate with the third-party plug-in. The
purpose of the interface is to provide notification when the main Properties dialog
for an AS/400 user is closing. The notification indicates whether any changes that
are made by the user should be saved or discarded. The intention is that the
interface be added to the same implementation class that is used for IPropSheetExt.

The interface implementation is compiled and linked into the ActiveX server DLL
for the plug-in. The Navigator learns of the existence of the new DLL by means of
entries in the Windows registry. These entries specify the location of the DLL on
the user’s personal computer. The Navigator then loads the DLL at the appropriate
time, calling methods on the IA4PropSheetNotify interface as needed.

CWBA4HYF.H contains declarations of the interface prototype and associated data


structures and return codes.

IA4PropSheetNotify interface specifications listing: The IA4PropSheetNotify


interface supplies notifications to the implementation of IShellPropSheetExt that are
needed when adding additional property pages to one of the Users and Groups
property sheets. These notifications are necessary because creating and destroying
Users and Groups property sheets may occur many times before the user clicks
OK on the main Properties dialog. IA4PropSheetNotify informs the
IShellPropSheetExt implementation when changes that are made by the user
should be saved.

The Operations Navigator learns about an IA4PropSheetNotify implementation by


means of the normal registry entries that are defined for Operations Navigator
plug-ins. In addition, when a property sheet handler for the Users and Groups
component is registered, a special registry value is supported that allows the
plug-in to specify to which property sheet it desires to add pages. For more
information, see “Product architecture for Operations Navigator C++ plug-ins” on
page 1003.

Link to any of the following IA4PropSheetNotify interface specifications:


v “IA4PropSheetNotify::InformUserState” on page 1024
v “IA4PropSheetNotify::ApplyChanges” on page 1025
v “IA4PropSheetNotify::GetErrorMessage” on page 1026

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1023


IA4PropSheetNotify::InformUserState:

Purpose: Called immediately following creation of the IShellPropSheetExt instance


to inform the implementation whether this user already exists on the AS/400 or is
being created for the first time.

Syntax:

HRESULT STDMETHODCALLTYPE InformUserState(


UINT wUserState
);

Parameters:
wUserState

The current state of the AS/400 user. Supplies one of three mutually exclusive
values:
IUS_NEWUSER
Creating a user based on attributes that are supplied by the Operations
Navigator user.
IUS_NEWUSERBASEDON
Creating a user based on the attributes of an existing AS/400 user.
IUS_USEREXISTS
The user already exists on the AS/400.

Return Codes: Returns NOERROR if successful or E_FAIL if a general error


occurred.

Comments: None

1024 Client Access Express Programming


IA4PropSheetNotify::ApplyChanges:

Purpose: Called to inform the implementation that data that belongs to the user
should now be saved.

Syntax:

HRESULT STDMETHODCALLTYPE ApplyChanges(


const char * pszNewUserName
);

Parameters:
pszNewUserName
Supplies the name of the new AS/400 user if creating the user for the first
time, for example, if InformUserState specifies a value other than
IUS_USEREXISTS.

Return Codes: Returns NOERROR if successful or E_FAIL if a general error


occurred.

Comments: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1025


IA4PropSheetNotify::GetErrorMessage:

Purpose: Called when errors are returned on ApplyChanges to retrieve the


implementation’s error message text.

Syntax:

HRESULT STDMETHODCALLTYPE GetErrorMessage(


char * pszErrMsg,
UINT cchMax
);

Parameters:
pszErrMsg
Address of the buffer that will receive the null-terminated error message.
cchMax
Size of the buffer that will receive the null-terminated error message.

Return Codes: Returns NOERROR if successful or E_FAIL if unable to retrieve the


message text or if message text was too large to fit in the buffer.

Comments: None

1026 Client Access Express Programming


Description of QueryContextMenu flags: Operations Navigator supports the
following enhancements to the IContextMenu interface:
Ordering of context menu items
The Operations Navigator has extended the IContextMenu interface to
obtain more precise control over the order in which menu items are added
to the menu for a particular folder or object. The Navigator structures its
context menus in three sections. This structure ensures that when more
than one component adds items to the context menu for an object, the
items will still appear in the correct order that is defined for the Windows
user interface.
The first section contains actions which are specific to the object type, such
as Reorganize for a database table. The second section contains ″object
creation″ items; these items are object types which cascade off of a New
menu item. Lastly there are the so-called ″standard″ Windows menu items,
such as Delete or Properties. You may choose to add menu items to any
section of the context menu.
The Operations Navigator calls the QueryContextMenu method for a
component three times in succession, once for each section of the menu.
The following additional flags are defined in the uFlags parameter to allow
you to determine which section of the context menu is currently being
serviced.
UNITY_CMF_CUSTOM
This flag indicates that you should add object-specific actions to the
menu.
UNITY_CMF_NEW
This flag indicates that you should add object creation items to the
menu.
UNITY_CMF_STANDARD
This flag indicates that you should add standard actions to the menu.
UNITY_CMF_FILEMENU

This flag changes UNITY_CMF_STANDARD. It indicates construction


of the File menu pulldown for your object, as opposed to the menu
that is displayed when the user clicks on an object with mouse button
2.

Items on the File pulldown are arranged slightly differently. If you add
Properties to the menu, you should avoid inserting a separator as is
normally done before this item. Also, edit actions such as Copy or
Paste should not be added to the File menu, because they appear on
the Edit pulldown instead. (The Operations Navigator calls your shell
plug-in at the appropriate time to obtain the items for the Edit menu,
and does not set UNITY_CMF_FILEMENU).
Unique property dialogs
In certain cases, a plug-in may desire to implement a Properties context
menu item that is defined for one of its own object types as a standard
Windows dialog instead of a property sheet. A flag that is defined for this
situation may be returned to the Navigator on calls to
IContextMenu::QueryContextMenu when the UNITY_CMF_STANDARD
flag is set. This flag, A4HYF_INFO_PROPERTIESADDED, should be OR’d
with the HRESULT value that is returned by QueryContextMenu.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1027


Returning this flag means that automatic processing for Properties is not
performed. In this case, the plug-in must add the context menu item and
construct the associated dialog.

Description of server entry point: A server entry point allows the plug-in to help
determine whether the function supplied by the plug-in should be activated for a
particular AS/400 that appears in the Operations Navigator hierarchy. The
Navigator calls the server entry point whenever a ″scan″ function is performed.
Normally the scan is performed the first time a user selects an AS/400 after the
client workstation has one or more plug-ins installed or upgraded. The user also
can start a manual rescan from the Plug-ins tab on the Property sheet for an
AS/400.

Note: Only C++ plug-ins support the server entry point function. Java and Visual
Basic plug-ins will not be called with a Server entry point.

See “IA4CheckIfSupported server entry point interface specification listing” for


programming specifications. See “Server entry point for Operations Navigator
plug-ins” on page 982 for an overview and description.

IA4CheckIfSupported server entry point interface specification listing:

1028 Client Access Express Programming


IA4CheckIfSupported:

Purpose: Called during the scan operation that is performed by Operations


Navigator. This API allows the plug-in to provide an indication of whether its
function should be surfaced for the specified AS/400 system.

Syntax:

extern "C" __declspec(dllexport)


BOOL CALLBACK IA4CheckIfSupported(
const char * lpszAS400Name,
const char * lpszVRM,
const char * lpszInstalledProducts
);

Parameters:
lpszAS400Name
The name of the AS/400 for which the function is to be surfaced.
lpszVRM
The Version/Release/Modification level of the specified AS/400, expressed as a
string of the form vvrrmm. For example, OS/400 Version 4 Release 2 would be
″040200.″
lpszInstalledProducts
A large string that contains the product IDs of every product installed on the
specified AS/400. The character ″/x01″ precedes each product ID in the string.

Return Codes: The function should return TRUE if the plug-in will surface its
function for this AS/400, and FALSE if the plug-in will not display the function.

Comments: Activation of this function occurs only when the ServerEntryPoint field
in the primary registry key for the plug-in contains the name of the DLL in which
the function resides. During development, a fully-qualified pathname may be
specified. When the plug-in is in production, only the name of the DLL should be
specified in the registry. The DLL will be loaded from the
<VENDOR>.<COMPONENT> subdirectory of the CLIENT ACCESS/PLUGINS.
IA4CheckIfSupported is called on a data thread, not the main UI thread. No user
interface tasks should be attempted.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1029


Operations Navigator data for C++ plug-ins
When the Navigator calls a function implemented by a plug-in, the request
typically involves an object or objects that the user selected in the main Navigator
window. The plug-in must determine which objects have been selected.

The plug-in receives this information as a list of fully qualified object names. For
C++ plug-ins, a call to IShellExtInit::Initialize passes this list to the plug-in.
Microsoft defined the IShellExtInit interface for the purpose of initializing the
implementation class for shell plug-ins. A call to its only method, Initialize, occurs
before the creation of an instance of IContextMenu or IPropSheetExt. For more
information about the format of Operations Navigator object names, see
“IA4HierarchyFolder interface specifications listing” on page 1007. For Java and
Visual Basic plug-ins, an ObjectName class is defined that provides information
about the selected objects.

Plug-ins that add folders to the object hierarchy must return items in the folder to
Operations Navigator in the form of ″item identifiers.″ For more information about
item identifiers in C++, see “IA4HierarchyFolder interface specifications listing” on
page 1007. For Java and Visual Basic plug-ins, an ItemIdentifier class is defined
and is used by the plug-in to return the requested information.

Operations Navigator services from a C++ plug-in


Operations Navigator provides a set of services for use by plug-in
implementations. There are APIs for managing object names and item identifier
lists. User other APIs to obtain global information about the AS/400, such as the
release of OS/400 that is installed. Some APIs provide services that allow plug-ins
to validate user input before transmitting data to the AS/400. After completion of
an operation, an API is provided that allows the plug-in to refresh the main
Navigator window or to insert a status message into the status area.

Developing Operations Navigator C++ plug-ins


One of the best ways to learn about Operations Navigator plug-ins is to build one.
This section provides step-by-step instructions for creating a new Operations
Navigator plug-in. The instructions use the sample C++ plug-in that is available by
linking to the Client Access Express Toolkit - Operations Navigator Plug-ins Web

page. . Select the cppsmppg.exe executable file to download the sample.


Details:
1. The sample plug-in was created using Microsoft Visual C++ Version 4.2, and
was generated from the Microsoft Developer Studio by using the MFC
AppWizard. A working knowledge of these tools, as well as C++, is needed to
understand the code in detail.
2. The Toolkit component of Client Access Express for Windows is not included in
a Typical program install. If the Toolkit subdirectory does not exist on your
personal computer, use the Client Access Selective Setup program to set up the
Toolkit.
3. The sample plug-in code is not included with the toolkit. You must download
the sample plug-in source code from the Client Access Express Toolkit -

Operations Navigator Plug-ins Web page. .


How to develop a C++ plug-in:
To develop an Operations Navigator C++ plug-in, complete the following
tasks:
1. Build, register and run the sample C++ plug-in.

1030 Client Access Express Programming


2. Create a new project workspace.
3. Customize the C++ plug-in.
4. Diagnose any C++ plug-ins errors.
5. Prepare your new C++ plug-in for final delivery and installation.
Related topic:
“Special rules and restrictions for developing Operations Navigator C++
plug-ins” on page 1040

Building, registering, and running the sample C++ plug-in


This task involves building and running the sample ActiveX server DLL. The
sample provides a functioning Developer Studio workspace that you can use to set
breakpoints and to observe the behavior of a typical Operations Navigator plug-in.
It also allows you to verify that your Developer Studio environment is set up
correctly for compiling and linking plug-in code.

Follow these steps:


1. Prepare to build an ActiveX server DLL
2. Build the ActiveX server DLL
3. Build the resource library
4. Register the ActiveX server DLL
5. Run Operations Navigator in the debugger

Preparing to build an ActiveX server DLL for C/C++ plug-ins:


1. Create a new directory that is named ″MyProject″ on your local hard drive.
This example assumes that the local drive is the C: drive.

Detail: If the new directory is not c:\MyProject, you will need to change the
registry file. See “Registering the ActiveX server DLL for C/C++
plug-ins” on page 1032 for more information.
2. Copy all of the sample files into this directory. You can download the samples
from the Client Access Express Toolkit - Operations Navigator Plug-ins Web

page.
3. In the Developer Studio, open the File menu and select Open Workspace.
4. In the Open Project Workspace dialog, switch to the MyProject directory and in
Files of Type: select Makefiles (*.mak).
5. Select sampext.mak and click Open.
6. Open the Tools menu and select Options...
7. In the Directories tab, make sure that the Client Access Include directory
appears at the top of your Include files search path.
8. In Show directories for:, select Library files. Make sure that the Client Access
Lib directory appears at the top of your Library files search path.
9. Click OK to save the changes, then close and reopen Developer Studio. This is
the only known way to force Developer Studio to save the search path changes
to your hard disk.
What to do next:
Build the ActiveX server DLL

Building the ActiveX server DLL for C/C++ plug-ins: To build the ActiveX
server DLL, complete the following steps.
1. In the Developer Studio, open the Build menu and select Set Default
Configuration...
2. In the Default Project Configuration dialog, select samptext Win32 Debug
Configuration.
3. Open the Build menu and select Rebuild All to compile and link the DLL.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1031


Detail: If the DLL does not compile and link cleanly, double-click the error
messages in the Build window to locate and fix the errors. Then open
the Build menu and select sampext.dll to restart the build.
What to do next:
Build the resource library

Building the resource library for C/C++ plug-ins: The resource DLL that contains
the translatable text strings and other locale-dependent resources for the plug-in is
included with the sample. This means that you do not have to create this DLL on
your own. Even if your plug-in supports only one language, your plug-in code
must load its text strings and locale-specific resources from this resource library.

To build the resource DLL, complete the following steps:


1. In Developer Studio, open the File menu and select Open Workspace... and
select the MyProject directory.
2. Specify Makefiles (*.mak) in Files of Type:.
3. Select sampmri.mak and click Open.
4. Open the Build menu and select Rebuild All to compile and link the DLL.
What to do next:
Register the ActiveX server DLL

Registering the ActiveX server DLL for C/C++ plug-ins: The SAMPDBG.REG file
in the MyProject directory contains registry keys that communicate the location of
the sample plug-in on your workstation to the Operations Navigator. If you
specified a directory other than c:\MyProject in “Preparing to build an ActiveX
server DLL for C/C++ plug-ins” on page 1031, complete the following steps.
1. Open the SAMPDBG.REG file in the Developer Studio (or use your chosen text
editor).
2. Replace all occurrences of ″c:\\MyProject\\″ with ″x:\\<dir>\\,″ where x is
the drive letter where your directory resides and <dir> is the name of the
directory.
3. Save the file.
4. In Windows Explorer, double-click the SAMPDBG.REG file. This will write the
entries in the registry file to the Windows registry on your machine.

Detail: In Windows NT, you must login with administrative privileges on your
workstation to write to the Windows registry.
What to do next:
Run Operations Navigator in the debugger

Running Operations Navigator in the debugger: To run Operations Navigator


and observe the sample plug-in in action, complete the following steps.
1. In Developer Studio, open the Build menu and select Debug ---> Go.
2. At the prompt, type the fully-qualified path to the Operations Navigator
executable in the Client Access Install directory on your workstation. The path
will be C:\PROGRAM FILES\IBM\CLIENT ACCESS\CWBUNNAV.EXE or
something similar.
3. Click OK. The main window of the Operations Navigator will open.

1032 Client Access Express Programming


4. Because you have just registered a new Navigator plug-in, a dialog similar to
the one that is pictured above appears. Click Scan Now.
5. After the progress indicator finishes, click OK in the resulting dialog.
6. After the Navigator window refreshes, a new folder (3rd Party Sample Folder)
appears in the hierarchy under the AS/400 that was initially selected. For more
information about this folder, see “Plug-ins samples in the Express Toolkit” on
page 980.
What to do next:
Create a new project workspace

Creating a new project workspace for C++ plug-ins


To develop C/C++ plug-ins for Operations Navigator, you need to know how to
create a new project workspace that you can use to generate the retail version of
your plug-in. You can create a new workspace that will incorporate source code
from the sample, which may then be changed.

To create the new Developer Studio workspace, complete the following steps.
1. Create a new ActiveX server DLL
2. Add files to the project workspace
3. Create a new resource DLL
4. Create help files

Creating a new ActiveX server DLL:


1. In the Developer Studio, open the File menu and select New... and Project
Workspace.
2. Click OK.
3. On the New Project Workspace dialog, select MFC AppWizard (DLL), type a
project name that you choose yourself, and then click Create.
4. On the MFC AppWizard dialog, make sure that OLE Automation is checked.
5. Continue to create the project workspace as you normally would for any other
Visual C++ project.
6. Once the project workspace is created, open the Build menu and select
Settings...
7. On the Link tab, in the Object/library modules field, type the list of import
libraries that are used in the sample plug-in. Change the name of the output
filename, if you want. Click OK.
8. Edit the primary source file (.CPP) for the new DLL and add the setup code
from SAMPEXT.CPP to the InitInstance and ExitInstance functions in the
primary source file.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1033


Details:
a. For this code to compile properly, you must include the header file
CWBUN.H in the primary source file.
b. Use the Class Wizard to add the code for ExitInstance.
9. Replace the file STDAFX.H that was generated for you when the project
workspace was created with the version from the sample plug-in. The new
version includes additional header files that are needed in order to build your
new plug-in.
Next, add files to the project workspace.

Adding files to the project workspace: The source files from the sample plug-in
can be used as a base for the code in your new server DLL. Make sure that the
names of the copied files conform to the naming convention for files in your new
project.

You will copy certain source files and header files from the sample, based on the
type of function that you plan on providing in your new plug-in. To add files to
your workspace, complete the following steps.
1. Open the Insert menu and select Files Into Project...
2. Make a new copy of the files EXTINTFC.CPP and EXTINTFC.H and add them
to your new project workspace.
3. Edit the copy of EXTINTFC files. Replace all occurrences of the class name
CSampleExtInterfaces with a class name that incorporates the <component>
string you defined for your plug-in.
4. If your plug-in will add new folders to the Operations Navigator hierarchy,
make a new copy of the files SAMPDATA.CPP, SAMPLIB.CPP, SAMPLIB.H,
TBARINFO.CPP and TBARINFO.H. Add these files to your new project
workspace.
5. Edit the SAMPDATA files. Replace all occurrence of the class name
CSampleData with a class name that incorporates the name of one of your new
folders.

Detail: If your plug-in will not implement a custom toolbar, change the code in
the GetToolbarInfo method to return E_NOTIMPL.
6. If your plug-in will add property pages to a property sheet for a folder or
object, make a new copy of the files PAGEADV.CPP and PAGEGEN.CPP. Then,
add these files to your new project workspace.
7. Make a copy of the file PROPEXT.CPP and add it to your new project
workspace.
8. If your plug-in adds additional context menu items to the context menu for a
folder or object, make a new copy of the file DLGDLT.CPP and DLGDLT.H.
Then, add these files to your new workspace.
9. Open the File menu and select SaveAll to save the changes to the Developer
Studio project file.
Now you’re ready to create a new resource DLL.

Creating a new resource DLL: Associated with the server DLL for an Operations
Navigator plug-in is a resource DLL that contains translatable text strings and
locale-dependent resources for the plug-in. To create this DLL, complete the
following steps.
1. Follow the instructions in the Visual C++ online help for creating a new
resource DLL.
2. Edit the primary source file for your ActiveX server DLL. Change the name of
the resource DLL specified in the InitInstance method to match the name of
your new resource DLL.

1034 Client Access Express Programming


3. Use a text editor to edit the two resource files (.RC), and copy the unique
resources that are defined for the sample into your new resource file. Also copy
the corresponding resource IDs into your new resource header file.

Detail: This will temporarily carry forward the resources that are defined in
the resource DLL for the sample plug-in into your new resource DLL.
This ensures that the sample code that you are using as a base for your
plug-in will still work properly.
Finally, create the help files that will be associated with your new C++ plug-in.

Creating help files for C++ plug-ins: Help files that are associated with your
plug-in are built and tested using the support that is provided by Visual C++. No
special considerations apply, except to ensure that the name of your help file is
correctly specified in the InitInstance method for your ActiveX server DLL.
What to do next:
Customize the C++ plug-in

Customizing C++ plug-ins


Customizing your new C++ plug-in will incorporate the unique function that you
intend to make available to Operations Navigator users. This involves creating
Windows registry files for the plug-in, and making changes to the source code.

To customize your new C++ plug-in, complete the following tasks:


1. Create a new registry file with a new ProgID for your C++ plug-in.
2. Generate a new GUID.
3. Register a data server implementation.
4. Register the shell plug-in implementation.
5. Specify C++ plug-in information.
6. Register new folder information.
7. Register shell plug-ins.
8. Construct property pages for a property sheet handler.
9. Test the new C++ plug-in.
10. Consider the rules and restrictions for C++ plug-ins.

For more information specific to working with registry files in this context, see
“Registry files for Operations Navigator plug-ins” on page 983.

Creating a new registry file with a new ProgID for your C++ plug-in: The
registry file contains important information about your plug-in, including the
programmatic identifier (ProgID). For more information about registry files, see
“Registry files for Operations Navigator plug-ins” on page 983. For more
information about ProgID, “Programmatic identifier (ProgID)” on page 984.

To create a new registry file for your plug-in, complete the following steps.
1. Copy the SAMPRLS.REG, one of the sample registry files that is included with
the sample.

Detail: You need to copy and edit both registry files that are included in the
sample, SAMPDBG.REG and SAMPRLS.REG. Use SAMPDBG.REG as
you develop your plug-in. Use. SAMPRLS.REG for the retail version of
your plug-in.
2. Rename the SAMPRLS.REG file. Use the naming convention that you have
defined for your new plug-in.
3. Begin editing the registry file with your preferred utility. Change all instances
of ″IBM.Sample″ with your new <vendor>.<component> string (ProgID).

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1035


What to do next:
Generate a new GUID

Generating a new GUID: For your Operations Navigator C++ plug-in to work
properly, you must replace specific CLSIDs in your new registry file with GUIDs
that you generate. See “Globally unique identifiers (GUIDs)” on page 984 for more
information about GUIDs, CLSIDs, and the registry file.

To generate a new GUID, complete the following steps.


1. From the Taskbar, select Start and then Run. Type ″GUIDGEN″ and click OK.
2. Make sure that Registry Format is selected
3. To generate a new GUID value, select New GUID.
4. To copy the new GUID value to the clipboard, select Copy.
What to do next:
Register a data server implementation

Registering a data server implementation: If your C++ plug-in adds a new folder
to the Operations Navigator hierarchy, edit the first section of the registry file. If
your plug-in does not add any new folders to the Operations Navigator hierarchy,
delete this section and proceed to the next task. You will see code similar to that in
the following example:

--------------------------------------------------------------------
; This section will register an IA4HierarchyFolder implementation for
; each new folder added to the Operations Navigator hierarchy. This
; section is not needed if your plug-in does not add any folders.

[HKEY_CLASSES_ROOT\CLSID\{D09970E1-9073-11d0-82BD-08005AA74F5C}]
@="AS/400 Data Server - Sample Data"

[HKEY_CLASSES_ROOT\CLSID\{D09970E1-9073-11d0-82BD-08005AA74F5C}\InprocServer32]
@="%CLIENTACCESS%\Plugins\IBM.Sample\sampext.dll"
"ThreadingModel"="Apartment"
1. Change the name of the DLL to match the name of the DLL that is generated
by your new project workspace.
2. Generate and copy a new GUID (see “Generating a new GUID”).
3. Replace both occurrences of the CLSID in this section of the registry with the
new GUID string you just generated.

Detail: If your plug-in will add more than one new folder to the hierarchy, you
must duplicate this section of the registry file for each additional folder.
Follow steps 1-3 for each separate section. Make sure to generate a
separate GUID for each folder.
4. Search for the string ″IMPLEMENT_OLECREATE″ in the file that you created
that was based on SAMPDATA.CPP (see “Adding files to the project
workspace” on page 1034). You will see code similar to that in the following
example:

/////////////////////////////////////////////////////////////////////////////
// Declare the CLSID for this data server subclass

// {D09970E1-9073-11d0-82BD-08005AA74F5C}
IMPLEMENT_OLECREATE(CSampleData, _T("AS/400 Data Server - Sample Data"),
0xd09970e1, 0x9073, 0x11d0, 0x82, 0xbd, 0x8, 0x0, 0x5a, 0xa7, 0x4f, 0x5c);
5. Paste the new GUID over the existing CLSID in the comment line, then change
the CLSID in the IMPLEMENT_OLECREATE macro call to match the hex
values in your new GUID. Replace the word ″Sample″ with the name of your
new folder.

1036 Client Access Express Programming


6. Create two new source files for each new GUID, using a renamed copy of
SAMPDATA.H and SAMPDATA.CPP as a base.

Detail: The header file (.H) contains the class declaration for the new
implementation class. The implementation file (.CPP) contains the code
that obtains the data for the new folder.
7. Replace all occurrences of the class name ″CSampleData″ in the two source files
with a class name that is meaningful in the context of your plug-in.
8. To add the new implementation files to the project workspace, open the Insert
menu and select Files Into Project....

Detail: Because you are duplicating SAMPDATA.CPP in this way, all your new
folders will initially contain library objects.
What to do next:
Register the shell plug-in implementation

Registering the shell plug-in implementation: The next two sections of the
registry file that register the shell plug-in implementation must always be present.

To edit these sections, complete the following steps. You will see code similar to
that in the following example:

;--------------------------------------------------------------------
; This section will register the shell plug-in implementation class.
; A shell plug-in adds context menu items and/or property pages
; for new or existing objects in the hierarchy.

[HKEY_CLASSES_ROOT\CLSID\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]
@="AS/400 Shell plug-ins - Sample"

[HKEY_CLASSES_ROOT\CLSID\{3D7907A1-9080-11d0-82BD-08005AA74F5C}\InprocServer32]
@="%CLIENTACCESS%\Plugins\IBM.Sample\sampext.dll"
"ThreadingModel"="Apartment"

;--------------------------------------------------------------------
; Approve shell plug-in (required under Windows NT)

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell plug-ins\Approved]
"{3D7907A1-9080-11d0-82BD-08005AA74F5C}"="AS/400 Shell plug-ins - Sample"
1. Change the DLL name to match the name of the DLL that was generated by
your new project workspace.
2. Generate and copy a new GUID (see “Generating a new GUID” on page 1036).
3. Replace all occurrences of the CLSID in the entries that are shown in the
example above with the new GUID you just generated.
4. Search for the string ″IMPLEMENT_OLECREATE″ in the file that you created
that was based on EXTINTFC.CPP (see “Adding files to the project workspace”
on page 1034). You will see code similar to that in the following example:

/////////////////////////////////////////////////////////////////////////////
// Declare the CLSID for the implementation class

// {3D7907A1-9080-11d0-82BD-08005AA74F5C}
IMPLEMENT_OLECREATE(CSampleExtInterfaces, _T("AS/400 Shell plug-ins - Sample"),
0x3d7907a1, 0x9080, 0x11d0, 0x82, 0xbd, 0x8, 0x0, 0x5a, 0xa7, 0x4f, 0x5c);
5. Paste the new GUID over the existing CLSID in the comment line, then change
the CLSID in the IMPLEMENT_OLECREATE macro call to match the hex
values in your new GUID.
What to do next:
Specify C++ plug-in information

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1037


Specifying C++ plug-in information: The next section of the registry is the
primary registry key for your plug-in. The information is required. Edit this section
of the registry by using the information in “Primary registry key” on page 984.
What to do next:
Register the new folder information

Registering new folder information: This section of the registry is necessary


when your plug-in adds new folder to the Operations Navigator hierarchy. Edit
this section of the registry by using the information in “New folder registry key”
on page 986. If your plug-in does not add a new folder to the Operations
Navigator hierarchy, delete the section entirely.
What to do next:
Register the shell plug-ins for objects

Registering shell plug-ins for objects: The final section of the registry specifies
which objects in the Navigator hierarchy are affected by implementation of the
plug-in. To edit this section of the registry, complete the steps that follow. You will
see code that is similar to the following example:

;--------------------------------------------------------------------
; Register a context menu handler for the new folder and its objects

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\Sample\*


\ContextMenuHandlers\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]

;--------------------------------------------------------------------
; Register a property sheet handler for the new folder and its objects

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.Sample\shellex\Sample\*


\PropertySheetHandlers\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]

;--------------------------------------------------------------------
; Register the Auto Refresh property sheet handler for the new folder and its objects
; (this will allow your folder to take advantage of the Operations Navigator
; Auto Refresh function)

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\Sample\*


\PropertySheetHandlers\{5E44E520-2F69-11d1-9318-0004AC946C18}]

;------------------------------------------------------------------------------
; Register drag and drop context menu handlers

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\Sample\*


\DragDropHandlers\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\File Systems\*


\DragDropHandlers\{3D7907A1-9080-11d0-82BD-08005AA74F5C}]

;------------------------------------------------------------------------------
; Register Drop Handler to accept drops of objects

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY plug-inS\IBM.Sample\shellex\Sample\*\DropHandler]


@="{3D7907A1-9080-11d0-82BD-08005AA74F5C}"

;------------------------------------------------------------------------------
; Register that this plug-in supports Secure Socket Layer (SSL) Connection
; Note: "Support Level"=dword:00000001 says the plugin supports SSL
; Note: "Support Level"=dword:00000000 says the plugin does not support SSL

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.Sample\SSL]


"Support Level"=dword:00000001

1038 Client Access Express Programming


1. Replace the CLSID in the entries above with the new GUID that you generated
in “Registering the shell plug-in implementation” on page 1037.
2. If your plug-in will not add additional property pages to a property sheet for a
folder or object, then remove the registry entry for the property sheet handler.
3. If your plug-in will not be a drop handler for objects, remove the drag and
drop context menu handler and drop handler registry entries.
4. Edit the subkeys \Sample\*\ by using the information in “Shell plug-ins” on
page 988.
5. In the file that you created that was based on EXTINTFC.CPP (“Adding files to
the project workspace” on page 1034), either edit or remove the code that
checks for the object types defined by the sample. You will see code that is
similar to the following example:

if (strObject == SMPTYPE_SAMPLELIBRARY)
{
(perform some action)
}
Details:
a. You should see the folders, context menu items, property pages, and drop
actions from the sample, depending on how much function from the sample
you decided to retain.
What to do next:
Construct property pages for a property sheet handler

Constructing property pages for a property sheet handler: Property pages


implemented by Operations Navigator plug-ins should subclass CExtPropertyPage.
You cannot use the Microsoft Foundation Class Library classes to construct
property pages for a property sheet handler. However, IBM provides
CExtPropertyPage, which may be used in place of the MFC class CPropertyPage.
For more information, see “Property pages for a property sheet handler” on
page 989.
What to do next:
Test the new C++ plug-in

Testing the C++ new plug-in: After finishing the previous tasks, you have
created project workspaces for your new ActiveX server DLL and an associated
resource DLL. You have also created a registry file that you can use to try out the
new plug-in.

To build the server DLL and resource DLL, complete the following steps.
1. In Developer Studio, open the Build menu and select Rebuild All fore each
DLL.

Detail: If a project does not rebuild cleanly, press F4 to display errors, then
make appropriate changes to the code. You may have to remove
INCLUDE statements for header files that you are not using.
2. In Windows Explorer, double-click your new registry file (the development
version) to register your new plug-in.
3. Run Operations Navigator.
4. If you do not see evidence of your new plug-in, check the Client Access
History Log for error messages. The online help for the messages will explain
how to correct any problems.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1039


Detail: You should see the folders, context menu items, and property pages
from the sample, depending on how much function from the sample
you decided to retain.
What to do next:
Consider the special rules and restrictions for developing Operations
Navigator C++ plug-ins

Special rules and restrictions apply to Operations Navigator C++ plug-ins.

Special rules and restrictions for developing Operations Navigator C++


plug-ins: With all the necessary packaging now in place, you are free to
concentrate on implementing the unique function of the new C++ plug-in. What
special rules and restrictions apply when developing a plug-in?

In general, the code that is packaged in a plug-in DLL is able to use any of the
services normally available to a Windows DLL. It may call any of the Windows
APIs. It may subclass the MFC library to implement any panels and dialogs
associated with the plug-in (subject to the restriction for property pages noted
above). It may call any of the Client Access APIs, including the special service APIs
that are implemented for use by Operations Navigator plug-ins. The comments in
the sample code provide additional information for use when you are developing
plug-ins.

You may wish to create functions and procedures that reside in one or more
additional code DLLs. These DLLs may be designated for installation on the client
workstation in any of several locations (refer the next section). Your plug-in DLL
may then call these functions as needed.

When creating additional code DLLs, you may experience difficulty the first time
you attempt to link to a new DLL from your plug-in DLL. When your new DLL is
not in the current directory or in a directory in the Windows search path, your
plug-in DLL will not be loaded, and the function of your plug-in will not appear
in the Navigator. This also occurs if your plug-in is attempting to link to an entry
point in the new DLL that is obsolete, or whose parameters have changed. In these
situations the History Log will contain an error message that includes a return
code from the LoadLibrary API in the form of an HRESULT. The online help lists
the common codes and their meaning, but the codes are not always reliable,
particularly on Windows NT. Therefore, before attempting to link to a new DLL,
make sure that the DLL is in the correct directory. Also make sure that you have
recompiled and relinked your plug-in DLL to minimize the likelihood of problems.

Note that ActiveX server DLLs are not automatically unloaded from memory when
the Operations Navigator window is closed. Instead, they are unloaded by the
operating system on a time-initiated basis. This creates a problem if you want to
rebuild your server DLL right away - the link step will fail because the previous
version of the DLL will be locked. To avoid this problem, you need to either restart
your workstation, or shut down the Windows shell.

If your plug-in implements a custom toolbar, then you must create a toolbar
resource in your resource DLL, and update the code file that you created based on
the sample file TBARINFO.CPP to correctly specify the toolbar buttons in the array
of Windows TBBUTTON structures.

Diagnosing C++ plug-ins errors


For some plug-ins errors, including:
v Incorrect registry-entry specifications

1040 Client Access Express Programming


v Windows unable to load server DLL
the only visible symptom in the main Operations Navigator dialog is the absence
of the plug-in function. To help you determine the source of errors, Operations
Navigator writes error messages to the Client Access History Log.
To access the History Log:
Select IBM AS400 Client Access Express, --> Service --> History Log.

Note: By default, the History Log is not active. To ensure that error messages are
written to this file, History logging must be started. See the Express User’s
Guide, which is shipped with Client Access Express, for information on
starting the History Log.

The entries in the History Log consist of messages with and without message IDs.
Messages with message IDs have online help available. Messages without message
IDs do not have online help available.
Displaying recovery information for error messages with IDs:
To display the cause and recovery information associated with a message
that has a message ID, double-click on it. View any message that has a
message ID by selecting the Message topic in the online Express User’s
Guide.

Client Access Express also has associated messages that are logged on the AS/400
system. These messages begin with PWS or IWS.
To display messages that are logged on the AS/400 system:
Type the appropriate command (displayed below) at the AS/400
command-line prompt, where xxxx is the number of the message:
DSPMSGD RANGE(IWSxxxx) MSGF(QIWS/QIWSMSG)

DSPMSGD RANGE(PWSxxxx) MSGF(QIWS/QIWSMSG)


For error-handling information that is specific to Express C/C++ APIs:
See “Express return codes and error messages” on page 15
What to do next:
Prepare your C++ plug-in for final delivery and installation.

Preparing your C++ plug-in for final delivery and installation


When you are satisfied with the function that you have developed to extend the
AS/400 Operations Navigator, it is time to prepare the plug-in for final delivery to
customers as part of an OS/400 licensed program. For your plug-in files to be
available for installation on client PCs, they must reside in one of two specific
AS/400 directories:
/QIBM/USERDATA/GUIPLUGIN
This directory should be used for plug-ins that are compatible with Client
Access and Client Access Express.
/QIBM/USERDATA/OpNavPlugin
This directory should be used for plug-ins that are compatible with Client
Access Express, but are incompatible with Client Access. Plug-ins in this
directory are not visible in the Client Access install dialogs.

Each OS/400 licensed program that has an associated Operations Navigator


plug-in should create its own subdirectory at this location as part of its normal
install processing. The name of this subdirectory must match the
<vendor>.<component> string that is defined for the plug-in in the registry file.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1041


For Operations Navigator C++ plug-ins, the subdirectory should contain:
v The registry file for the plug-in.
v The Express setup file for the plug-in.
v The ActiveX server DLL for the plug-in, and any associated code DLLs. See
“Building, registering, and running the sample C++ plug-in” on page 1031 for
more information.

If the plug-in supports Windows policies, include the .adm policy template file for
the plug-in in the MRI29xx directory.

The plug-in must create at least one directory below the


<VENDOR>.<COMPONENT> subdirectory that is named MRI29XX, where XX
identifies a supported language. For more information about MRI codes, see the
following IBM publication: AS/400 International Application Development: SC41–5603.
This directory contains the correct national language version of the following
items:
v The resource DLL for the plug-in
v The help files for the plug-in
v The “MRI setup file” on page 996 for the plug-in.
Related topic:
“Application Administration support for your plug-in” on page 996

Installing Operations Navigator C++ plug-ins


You can deliver your plug-in code to Operations Navigator users by including it
with your OS/400 applications. The install program for the application writes the
plug-in’s code binaries, registry file, and translatable resources to the
/QIBM/UserData/OpNavPlugins folder in the AS/400 Integrated File System
(AS/400 IFS). Once this process is completed, users can obtain the plug-in from the
AS/400 IFS (with the help of an AS/400 NetServer mapped network drive) by
invoking the Client Access Selective Setup program. The setup program copies
your plug-in code to the user’s machine, downloads the appropriate translatable
resources based on the language settings on the user’s PC, and runs the registry
file to write your plug-in’s registry information to the Windows registry. All you
need is a setup file, which identifies the files to be installed. If you provide a
Windows policy template with your plug-in, you also can take advantage of
Windows system policies to control which network users can install your plug-in.
You also can use the AS/400-based Application Administrationsupport of
Operations Navigator to control which users and groups have access to your
plug-in.

After the users have installed your new plug-in, you may choose either to upgrade
it at a later date, or to ship code problem fixes. When the code is upgraded on the
AS/400, the Client Access Check Version program will detect that this process has
occurred, and automatically download the updates to the users’ PCs. Client Access
also provides uninstall support, which allows users to completely remove the
plug-in from their PCs.

Users can display the plug-ins that are installed on their PCs by selecting the
Plug-ins tab on the Operations Navigator Properties for a particular AS/400.

Identifying C++ plug-ins to Operations Navigator


C++ plug-ins identify themselves to Operations Navigator by supplying
information in the Windows registry (see “The Windows registry for Operations
Navigator plug-ins” on page 982 for more information). This information is

1042 Client Access Express Programming


supplied when the plug-in software is installed on a user’s PC. The registry entries
specify the location of the plug-in code, and identify the classes that implement the
special plug-in interfaces. You can supply additional registry information that
instructs Operations Navigator whether to activate the plug-in’s function for a
particular AS/400 system. For example, a plug-in may require a certain minimum
release of OS/400, or it may specify that a certain product must be installed on the
AS/400 in order for it to function.

When a user makes a selection on an AS/400 in the Operations Navigator tree


after installing a plug-in, the AS/400 is examined to determine whether it is
capable of supporting the new plug-in. The software prerequisites (specified in the
plug-in’s registry entries) are compared against the software that is installed on the
AS/400. If the plug-in’s requirements are satisfied, the new function is displayed in
the Navigator tree. If the requirements are not met, the plug-in’s function does not
appear in the Navigator tree hierarchy for that AS/400. However, the plug-in may
participate in the determination of whether to be included in the hierarchy, by
implementing a special callback function that can be called by Operations
Navigator during this scanning process.

Operations Navigator API listing


Operations Navigator APIs help plug-in developers obtain and manage certain
types of global information. The following Operations Navigator APIs are listed
alphabetically, and are grouped by function:

Function Operations Navigator APIs


System values: This API allows the plug-in cwbUN_GetSystemValue
developer to obtain the current value of an
AS/400 system value.
System handles: These APIs allow the cwbUN_GetSystemHandle
plug-in developer to obtain and to release
cwbUN_ReleaseSystemHandle
the current value of an AS/400 system object
handle that contains connection properties
including the secure sockets layer (SSL)
settings to be used for the specified AS/400
system.
User input validation: These APIs allow the cwbUN_CheckObjectAuthority
plug-in developer to check whether the
cwbUN_CheckSpecialAuthority
current user has authority to a particular
AS/400 object. The APIs also allow the
developer to determine if the user has one
or more special authorities.
User authority checking: This API allows cwbUN_CheckAS400Name
the plug-in developer to check whether
certain types of user-supplied strings are
valid before transmitting them to the
AS/400.
User profile attributes: This API allows the cwbUN_GetUserAttribute
plug-in developer to obtain the value of any
of the user profile attributes for the current
Operations Navigator user.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1043


Function Operations Navigator APIs
Data management: Objects that the user has cwbUN_ConvertPidlToString
selected are identified to the third-party
cwbUN_GetDisplayNameFromItemId
plug-in by two data entities, the item
identifier list, and the object name. Data cwbUN_GetDisplayNameFromName
management APIs provide the plug-in cwbUN_GetDisplayPathFromName
developer with a means of extracting cwbUN_GetIndexFromItemId
information from these structures.
cwbUN_GetIndexFromName
cwbUN_GetIndexFromPidl
cwbUN_GetListObject

cwbUN_GetParentFolderNameFromName
cwbUN_GetParentFolderPathFromName
cwbUN_GetParentFolderPidl
cwbUN_GetSystemNameFromName
cwbUN_GetSystemNameFromPidl
cwbUN_GetTypeFromItemId
cwbUN_GetTypeFromName
cwbUN_GetTypeFromPidl
Refresh the Operations Navigator window: cwbUN_RefreshAll
Following the completion of an operation on
cwbUN_RefreshList
behalf of the user, these APIs enable
execution of a request by the plug-in to cwbUN_RefreshListItems
refresh the tree and list views or to place a cwbUN_UpdateStatusBar
message in the Navigator status bar.
ODBC connections: These APIs allow the cwbUN_GetODBCConnection
plug-in developer to reuse and end the
cwbUN_EndODBCConnections
handle for an ODBC connection that already
has been obtained by the Database
component of the Operations Navigator.
Access Operations Navigator icons: These cwbUN_GetIconIndex
APIs allow the plug-in developer to access
cwbUN_GetSharedImageList
the icon image lists for objects that appear in
the Navigator object hierarchy.
Application Administration: These APIs cwbUN_GetAdminValue
allow the plug-in developer to
cwbUN_GetAdminValueEx
programmatically determine whether a user
is denied or allowed use of an cwbUN_GetAdminCacheState
Administrable function. An Administrable cwbUN_GetAdminCacheStateEx
function is any function whose use can be
controlled through the Application
Administration subcomponent of Operations
Navigator.
Install: This API allows the plug-in cwbUN_IsSubcomponentInstalled
developer to determine if an Operations
Navigator subcomponent is installed.

1044 Client Access Express Programming


Function Operations Navigator APIs
Directory Services: These APIs provide cwbUN_OpenLocalLdapServer
information about the Directory Services
cwbUN_FreeLocalLdapServer
(LDAP) server on an AS/400, and functions
to connect to the server. The connection cwbUN_GetLdapSvrPort
functions enable you to connect to a server cwbUN_GetLdapSvrSuffixCount
using information (distinguished names, cwbUN_GetLdapSvrSuffixName
password, etc.) cached by the AS/400 Client
Access. The connection functions use the cwbUN_OpenLdapPublishing
LDAP client shipped with Client Access cwbUN_FreeLdapPublishing
(LDAP.LIB and LDAP.DLL) and therefore cwbUN_GetLdapPublishCount
require that your application use that client.
cwbUN_GetLdapPublishType
Functions that use strings are available in cwbUN_GetLdapPublishServer
ANSI and Unicode versions. cwbUN_GetLdapPublishPort
Functions that return distinguished names cwbUN_GetLdapPublishParentDn
and other strings for use with LDAP client cwbUN_OpenLdapBindInfo
APIs also are provided in a UTF-8 version cwbUN_FreeLdapBindInfo
for use with LDAP version 3 servers.
cwbUN_GetLdapServerBindDn
See “IBM Lightweight Directory Access cwbUN_BindToLdapServerOnAs400
Protocol (LDAP) APIs” on page 615 for more cwbUN_BindToLdapServer
information.
cwbUN_NullBindToLdapServerOnAs400
cwbUN_NullBindToLdapServer

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1045


cwbUN_BindToLdapServer
Purpose: Binds to the specified server using information cached by Client Access
including:
v Distinguished name
v Password
v SSL configuration
If any required information is not available, a dialog is displayed to collect the
data. If an error occurs, a message is displayed to the user.

The connection is established through the Client Access LDAP client (LDAP.LIB
and LDAP.DLL), and only can be used with that client.

This API will attempt to establish bind using LDAP version 3, and then LDAP
version 2. Use the ldap_get_option LDAP client API to determine what version the
bind used if you need to use LDAP version 3 client APIs with the connection.

Syntax:

int cwbUN_BindToLdapServerA
( LPCSTR server,
int port,
int sslPort,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

int cwbUN_BindToLdapServerW
( LPCWSTR server,
int port,
int sslPort,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

Parameters:
LPCSTR system - input
NULL-terminated AS/400 system name or dotted IP address.
int port - input
The port to be used for standard connections. Specify 0 to force an SSL
connection.
int sslPort - input
The port to be used for SSL connections. Specify 0 if SSL connections are not
supported by the server.
cwbUN_LdapBindOption options - input
Specifies options controlling the display of error messages and the ″Connect to
Directory Server″ dialog. Possible values are:
CWBUN_LDAP_BINDOPT_NO_DLG
Do not show the ″Connect To Directory Server″ dialog and do not
display any error messages.

1046 Client Access Express Programming


CWBUN_LDAP_BINDOPT_DLG_ON_ERR
Show the ″Connect To Directory Server″ dialog and error messages.
The user has the opportunity to change bind information if an error
occurs.
CWBUN_LDAP_BINDOPT_SHOW_DLG
Show the ″Connect to Directory Server″ dialog before attempting to
connect to the server. The user has the opportunity to change bind
information before connecting to the server.
int version - input
Specifies the LDAP API version to use for binding to the server. Possible
values are:
LDAP_VERSION2 (from ldap.h)
Bind as a LDAP version 2 client.
LDAP_VERSION3 (from ldap.h)
Bind as a LDAP version 3 client. If the server does not support version
3, the bind will fail with a protocol error.
CWBUN_LDAP_VERSION_LATEST
Bind as a LDAP version 3 client if supported by the server. Otherwise,
bind as a LDAP version 2 client.
LDAP **LPldap - output
On return, *LPldap points to the LDAP* returned by the LDAP bind APIs.
HWND hwnd - input
Window handle to be used for messages. This handle also will be used as the
parent window of the ″Connect to Directory server″ dialog. NULL can be
specified.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_BIND_FAILED
A connection could not be established to the server.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1047


cwbUN_BindToLdapServerOnAs400
Purpose: Binds to the specified server using information cached by Client Access
including:
v Distinguished name
v Password
v SSL configuration
If any required information is not available, a dialog is displayed to collect the
data. If an error occurs, a message is displayed to the user.

The connection is established through the Client Access LDAP client (LDAP.LIB
and LDAP.DLL), and only can be used with that client.

This API will attempt to establish bind using LDAP version 3, and then LDAP
version 2. Use the ldap_get_option LDAP client API to determine what version the
bind used if you need to use LDAP version 3 client APIs with the connection.

Syntax:

int cwbUN_BindToLdapServerOnAs400A
( LPCSTR system,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

int cwbUN_BindToLdapServerOnAs400W
( LPCWSTR system,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

Parameters:
LPCSTR system - input
NULL terminated AS/400 system name.
cwbUN_LdapBindOption options - input
Specifies options controlling the display of error messages and the ″Connect to
Directory Server″ dialog. Possible values are:
CWBUN_LDAP_BINDOPT_NO_DLG
Do not show the ″Connect To Directory Server″ dialog and do not
display any error messages.
CWBUN_LDAP_BINDOPT_DLG_ON_ERR
Show the ″Connect To Directory Server″ dialog and error messages.
The user has the opportunity to change bind information if an error
occurs.
CWBUN_LDAP_BINDOPT_SHOW_DLG
Show the ″Connect to Directory Server″ dialog before attempting to
connect to the server. The user has the opportunity to change bind
information before connecting to the server.
int version - input
Specifies the LDAP API version to use for binding to the server. Possible
values are:

1048 Client Access Express Programming


LDAP_VERSION2 (from ldap.h)
Bind as a LDAP version 2 client.
LDAP_VERSION3 (from ldap.h)
Bind as a LDAP version 3 client. If the server does not support version
3, the bind will fail with a protocol error.
CWBUN_LDAP_VERSION_LATEST
Bind as a LDAP version 3 client if supported by the server. Otherwise,
bind as a LDAP version 2 client.
LDAP **LPldap - output
On return, *LPldap points to the LDAP* returned by the LDAP bind APIs.
HWND hwnd - input
Window handle to be used for messages. This handle also will be used as the
parent window of the ″Connect to Directory server″ dialog. NULL can be
specified.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_NOT_AVAIL
Directory services is not installed or the server has not been configured.
CWBUN_LDAP_BIND_FAILED
A connection could not be established to the server.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1049


cwbUN_CheckAS400Name
Purpose: Returns an indication of whether a specified string is a valid name
parameter on the AS/400.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_CheckAS400Name(


const char * szAS400Name,
const char * szSystemName,
USHORT usTypeId
);

Parameters:
const char * szAS400Name - input
The AS/400 name whose validity is to be checked.
const char * szSystemName - input
The name of the AS/400 system on which to perform the check.
USHORT usTypeId - input
A numeric value that indicates how the input string should be interpreted: as a
long object name, a short object name, a communications name, or a string
(type constants are defined above).

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_NAME_TOO_LONG
Name is too long.
CWBUN_NAME_NULLSTRING
String is empty - no characters at all.
CWBUN_NAME_INVALIDCHAR
Character not valid.
CWBUN_NAME_STRINGTOOLONG
String is too long.
CWBUN_NAME_MISSINGENDQUOTE
End quote is missing.
CWBUN_NAME_INVALIDQUOTECHAR
Character not valid for quote string.
CWBUN_NAME_ONLYBLANKS
Found a string of only blanks.
CWBUN_NAME_STRINGTOOSHORT
String is too short.
CWBUN_NAME_TOOLONGFORIBM
String is OK, but too long for IBM command.
CWBUN_NAME_INVALIDFIRSTCHAR
The first character is not valid.

Usage: None

1050 Client Access Express Programming


cwbUN_CheckObjectAuthority
Purpose: Returns an indication of whether the Operations Navigator user has
authority to a particular object on the AS/400.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_CheckObjectAuthority(


const char * szObjectPath,
const char * szObjectType,
const char * szAuthorityType,
const char * szSystemName
);

Parameters:
const char * szObjectPath - input
The AS/400 object path for which authority is to be checked.
const char * szObjectType - input
The AS/400 object type for the object for which authority is to be checked, for
example *DTAQ.
const char * szAuthorityType - input
The AS/400 object authority to be checked. Possible values are:
EXCLUDE
CHANGE
USE
AUTLMGT
OBJALTER
OBJOPR
OBJMGT
OBJEXIST
OBJREF
READ
ADD
UPD
DLT
EXECUTE
If more than one authority is to be checked, the authorities should be
concatenated (for example, *OBJMGT*OBJEXIST). Up to eleven authority types
may be specified on a single call. The function will return CWB_OK only if the
user has all of the specified authorities to the object.
const char * szSystemName - input
The name of the AS/400 system on which to perform the check.

Return Codes: The following list shows common return values:


CWB_OK
The user has the specified authority to the object.
CWBUN_USER_NOT_AUTHORIZED
The user does not have the specified authority.
CWBUN_OBJECT_NOT_FOUND
The specified object could not be checked.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1051


CWBUN_INTERNAL_ERROR
Object authority could not be checked.

Usage: If *EXCLUDE is specified as an authority, no other authority types may be


specified. *AUTLMGT is valid only if ’szObjectType’ is *AUTL.

1052 Client Access Express Programming


cwbUN_CheckSpecialAuthority
Purpose: Returns an indication of whether the Operations Navigator user has a
particular special authority on the AS/400.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_CheckSpecialAuthority(


const char * szSpecialAuthority,
const char * szSystemName
);

Parameters:
const char * szSpecialAuthority - input
The AS/400 special authority to be checked. Possible values are:
*ALLOBJ
*AUDIT
*IOSYSCFG
*JOBCTL
*SAVSYS
*SECADM
*SERVICE
*SPLCTL
const char * szSystemName - input
The name of the AS/400 system on which to perform the check.

Return Codes: The following list shows common return values:


CWB_OK
The user has the specified special authority.
CWBUN_USER_NOT_AUTHORIZED
The user does not have the specified authority.
CWBUN_INTERNAL_ERROR
Special authority could not be checked.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1053


cwbUN_ConvertPidlToString
Purpose: Converts an Operations Navigator item identifier list to a fully-qualified
object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_ConvertPidlToString(


LPCITEMIDLIST pidl,
char * szObjectName,
UINT cchMax
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to the ITEMIDLIST (item identifier list) structure that is to be
converted.
char * szObjectName - output
Address of the buffer that will receive the null-terminated object name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated object name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
The specified item identifier list is not valid.
WB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1054 Client Access Express Programming


cwbUN_EndODBCConnections
Purpose: Ends all ODBC connections previously opened by
cwbUN_GetODBCConnection.

Syntax:
CWBAPI unsigned int WINAPI cwbUN_EndODBCConnections(
);

Parameters: None

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Handle was not created by cwbUN_OpenLdapBindInfo().

Usage: It is important to remember that the EndODBCConnections function only


closes connections that were opened using the GetODBCConnection function. The
EndODBCConnections function is unaware of ODBC connections opened directly
or by using other interfaces.

Also ensure that the destructor for the folder of your application extension invokes
the EndODBCConnections if any code in your extension uses
GetODBCConnection.

See also cwbUN_GetODBCConnection.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1055


cwbUN_FreeLdapBindInfo
Purpose: Frees resources associated with the input handle.

Syntax:

int cwbUN_FreeLdapBindInfo
( cwbUN_ldapBindInfoHandle handle
);

Parameters:
cwbUN_ldapBindInfoHandle handle - input
The handle for which resources should be freed.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Handle was not created by cwbUN_OpenLdapBindInfo().

Usage: The handle is obtained by a call to cwbUN_OpenLdapBindInfoW().

1056 Client Access Express Programming


cwbUN_FreeLdapPublishing
Purpose: Frees resources associated with the input handle.

Syntax:

int cwbUN_FreeLdapPublishing
( cwbUN_ldapPubHandle handle
);

Parameters:
cwbUN_ldapPubHandle handle - input
The handle for which resources should be freed.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Handle was not created by cwbUN_OpenLdapPublishing().

Usage: The handle is obtained by a call to cwbUN_OpenLdapPublishing().

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1057


cwbUN_FreeLocalLdapServer
Purpose: Frees resources associated with the input handle.

Syntax:

int cwbUN_FreeLocalLdapServer
( cwbUN_ldapSvrHandle handle
);

Parameters:
cwbUN_ldapSvrHandle handle - input
The handle for which resources should be freed.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
handle was not created by cwbUN_OpenLocalLdapServer()

Usage: The handle is obtained by a call to cwbUN_OpenLocalLdapServer.

1058 Client Access Express Programming


cwbUN_GetAdminCacheState
Purpose: This API indicates whether the next invocation of the
cwbUN_GetAdminValue API will be long running. The cwbUN_GetAdminValue
API caches data on the PC. If the cache is not current, cwbUN_GetAdminValue
may present a sign-on prompt, or perform other processing, in order to update its
cache.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetAdminCacheState(


const char * szSystemName,
cwbUN_State& adminState);

Parameters:
const char * szSystemName
The name of the AS/400 system on which to perform the check.
cwbUN_State& adminState
Indicates if the next invocation of the cwbUN_GetAdminValue API will be
long running or if it will use its internal cache to return without accessing the
host AS/400.

One of three values will be returned:


cwbUN_logon
There is no current user for the specified AS/400. The
cwbUN_GetAdminValue API may present a sign-on prompt.
cwbUN_refresh
cwbUN_GetAdminValue will access the AS/400 to update its internal
cache.
cwbUN_cache
cwbUN_GetAdminValue has a current cache and should not be long
running.

Return Codes: The following list shows common return values:


CWB_OK
The API was successful.

Usage: This API can be used by users of cwbUN_GetAdminValue to determine if


the next invocation of cwbUN_GetAdminValue will be long running.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1059


cwbUN_GetAdminCacheStateEx
Purpose: This API indicates whether the next invocation of the
cwbUN_GetAdminValueEx API will be long running. The
cwbUN_GetAdminValueEx API caches data on the PC. If the cache is not current,
the cwbUN_GetAdminValueEx API may present a sign-on prompt, or perform
other processing, in order to update its cache.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetAdminCacheStateEx(


cwbCO_SysHandle* pSysHandle,
cwbUN_State& adminState);

Parameters:
cwbCO_SysHandle* pSysHandle - input
A pointer to a system object handle. The system name must be specified in the
system object prior to calling this API.
cwbUN_State& adminState
Indicates if the next invocation of the cwbUN_GetAdminValue API will be
long running or if it will use its internal cache to return without accessing the
host AS/400.

One of three values will be returned:


cwbUN_logon
There is no current user for the specified AS/400. The
cwbUN_GetAdminValue API may present a sign-on prompt.
cwbUN_refresh
cwbUN_GetAdminValue will access the AS/400 to update its internal
cache.
cwbUN_cache
cwbUN_GetAdminValue has a current cache and should not be long
running.

Return Codes: The following list shows common return values:


CWB_OK
The API was successful.

Usage: This API can be used by users of cwbUN_GetAdminValueEx to determine


if the next invocation of cwbUN_GetAdminValueEx will be long running.

1060 Client Access Express Programming


cwbUN_GetAdminValue
Purpose: This API returns an indication of whether the current Operations
Navigator user on the specified AS/400 is allowed or denied use of a specific
administrable function. An Administrable function is any function whose use can
be controlled through the Application Administration subcomponent of Operations
Navigator.

For example, the Application Administration subcomponent allows an


administrator to control whether a user can access several functions in Operations
Navigator. One of these functions is Job Management. The
cwbUN_GetAdminValue API can be used to programmatically determine if the
current Operations Navigator user can use the Job Management function by
specifying the name of the Administrable function that corresponds to Job
Management. See the cwbunpla.h header file for a list of Administrable function
names that are supported in Operations Navigator.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetAdminValue(


const char * szSystemName,
char* adminFunction,
cwbUN_Usage& usageValue);

Parameters:
const char * szSystemName
The name of the AS/400 system on which to perform the check.
char* adminFunction
A pointer to an ASCII string that contains the name of the Administrable
function. The string must be null terminated and has a maximum length of 30
bytes + 1 byte for the NULL terminator. See cwbunpla.h for a list of supported
input values.
cwbUN_Usage & usageValue
This value is only valid if the return code of CWB_OK is returned. One of two
values will be returned:
v cwbUN_granted — User is allowed use of the function.
v cwbUN_denied — user is denied use of the function.

Return Codes: The following list shows common return values:


CWB_OK
The API was successful.
CWBSY_USER_CANCELLED
The user cancelled the user ID and password prompt presented by the
API.

Usage: This API determines if the current Operations Navigator user for the
specified AS/400 is allowed to use the specified function. If no user is currently
signed on to the specified AS/400, the API will sign the user on, possibly
displaying a user ID and password prompt.

This API can only be used to check Administrable functions that are in the AS/400
Operations Navigator or the Client Applications function category.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1061


cwbUN_GetAdminValueEx
Purpose: This API returns an indication of whether the current user on the
specified AS/400 is allowed or denied use of a specific administrable function. An
Administrable function is any function whose use can be controlled through the
Application Administration subcomponent of Operations Navigator.

Note: Operations Navigator plug-ins should use the cwbUN_GetAdminValue API


instead of cwbUN_GetAdminValueEx.

For example, the Application Administration subcomponent allows an


administrator to control whether a user can access several functions in Operations
Navigator. One of these functions is ’Job Management’. The
cwbUN_GetAdminValueEx API can be used to programmatically determine if the
current user can use the Job Management function by specifying the name of the
Administrable function that corresponds to Job Management. See the
CWBUNPLA.H header file for a list of Administrable function names that are
supported in Operations Navigator.

This API provides the same function as cwbUN_GetAdminValue, except that it is


designed to accept a system object handle instead of a system name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetAdminValueEx(


cwbCO_SysHandle* pSysHandle,
char* adminFunction,
cwbUN_Usage& usageValue);

Parameters:
cwbCO_SysHandle* pSysHandle
A pointer to a system object handle. The system name must be specified in the
system object prior to calling this API. The cwbUN_GetAdminValueEx API’s
behavior is based on whether the system object has obtained a signon to the
AS/400:
Not Signed On->
cwbUN_GetAdminValueEx will signon to the AS/400. The latest
Application Administration settings for the user will be downloaded
from the AS/400 if they are not already cached on the client PC.
Signed On->
If the system object was signed on to the AS/400 specifying that the
AS/400 userID and password should be validated (Validate Mode),
then the cwbUN_GetAdminValueEx API will be using a snapshot of
AS/400’s Application Administration settings that were accurate at the
time the signon was completed. If the signon was done without
validating the userID and password, then it is possible that
cwbUN_GetAdminValueEx will use a copy of the AS/400’s Application
Administration settings that may be as much as 24 hours old.
char* adminFunction
A pointer to an ASCII string that contains the name of the Administrable
function. The string must be null terminated and has a maximum length of 30
bytes + 1 byte for the NULL terminator. See CWBUNPLA.H for a list of
supported input values.

1062 Client Access Express Programming


cwbUN_Usage& usageValue
This value is only valid if the return code of CWB_OK is returned. One of two
values will be returned:
cwbUN_granted
User is allowed use of the function.
cwbUN_denied
User is denied use of the function.

Return Codes: The following list shows common return values:


CWB_OK
The API was successful.
CWBSY_USER_CANCELLED
The user cancelled the user ID and password prompt presented by the
API.

Usage: This API determines if the current AS/400 user (as defined by the input
system object) is allowed to use the specified function. If no user is currently
signed on to the specified AS/400, the API will sign the user on, possibly
displaying a user ID and password prompt.

This API can only be used to check Administrable functions that are in the AS/400
Operations Navigator or the Client Applications function category.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1063


cwbUN_GetDisplayNameFromItemId
Purpose: Extracts the item name field from a Unity item identifier.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetDisplayNameFromItemId(


const char * szItemId,
char * szItemName,
UINT cchMax
);

Parameters:
const char * szItemId - input
The Unity item identifier from which the item name will be extracted.
char * szItemName - output
Address of the buffer that will receive the null-terminated item name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated item name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified item identifier not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1064 Client Access Express Programming


cwbUN_GetDisplayNameFromName
Purpose: Extracts the item name field from a fully-qualified Unity object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetDisplayNameFromName(


const char * szObjectName,
char * szItemName,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the item name will be extracted.
char * szItemName - output
Address of the buffer that will receive the null-terminated item name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated item name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1065


cwbUN_GetDisplayPathFromName
Purpose: Converts a fully-qualified Unity object name to a fully-qualified
pathname suitable for displaying to the user.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetDisplayPathFromName(


const char * szObjectName,
char * szPathName,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the pathname will be derived.
char * szPathName - output
Address of the buffer that will receive the null-terminated pathname.
UINT cchMax - input
Size of the buffer that will receive the null-terminated pathname.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1066 Client Access Express Programming


cwbUN_GetIconIndex
Purpose: Get the index in the image list of the specified icon.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetIconIndex(


LPCITEMIDLIST pidl,
UINT uFlags,
int* piIndex
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to the ITEMIDLIST (item identifier list) structure that is used to
identify the icon to be referenced.
UINT uFlags - input
Specification of the type of icon index to retrieve (defined above). The
following flag types are allowed:
GII_ICON
GII_SMALLICON
GII_OPENICON
int * piIndex - output
Address of the integer that will receive the icon index.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_INVALID_FLAG_VALUE
Not a valid supported flag value.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1067


cwbUN_GetIndexFromItemId
Purpose: Extracts the item index field from a Unity item identifier.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetIndexFromItemId(


const char * szItemId,
ULONG* piIndex
);

Parameters:
const char * szItemId - input
The Unity item identifier from which the item index will be extracted.
ULONG* piIndex - output
Address of an unsigned long integer that will receive the item index.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified item identifier not valid.

Usage: None

1068 Client Access Express Programming


cwbUN_GetIndexFromName
Purpose: Extracts the item index field from a fully-qualified Unity object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetIndexFromName(


const char * szObjectName,
ULONG* piIndex
);

Parameters:
const char * szObjectName - input
The Unity object name from which the item index will be extracted.
ULONG* piIndex - output
Address of an unsigned long integer that will receive the item index.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1069


cwbUN_GetIndexFromPidl
Purpose: Extracts the item index field from a fully-qualified Unity item identifier
list.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetIndexFromPidl(


LPCITEMIDLIST pidl,
ULONG* piIndex
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to an ITEMIDLIST (item identifier list) structure from which the item
index will be extracted.
ULONG* piIndex - output
Address of an unsigned long integer that will receive the item index.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
The specified item identifier list is not valid.

Usage: None

1070 Client Access Express Programming


cwbUN_GetLdapPublishCount
Purpose: Returns the number of publishing records configured for this AS/400. A
publish record identifies a category of information to be published, and how and
where it is to be published.

Syntax:

int cwbUN_GetLdapPublishCount
( cwbUN_ldapPubHandle handle,
int *count
);

Parameters:
cwbUN_ldapPubHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapPublishing().
int * count - output
The number of publish records configured on the AS/400.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1071


cwbUN_GetLdapPublishParentDn
Purpose: Returns the parent distinguished name of the published objects. For
example, if the parentDN for publishing users was cn=users,o=ace industry,c=us,
and user information was published for John Smith, the dn of the published object
could be cn=john smith,cn=users,ou=ace industry,c=us.

Syntax:

int cwbUN_GetLdapPublishParentDnW
( cwbUN_ldapPubHandle handle,
int index,
LPWSTR parentDn,
int *length
);

int cwbUN_GetLdapPublishParentDnA
( cwbUN_ldapPubHandle handle,
int index,
LPSTR parentDn,
int *length
);

int cwbUN_GetLdapPublishParentDn8 /* return parentDn in UTF-8 */


( cwbUN_ldapPubHandle handle,
int index,
LPSTR parentDn,
int *length
);

Parameters:
cwbUN_ldapPubHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapPublishing().
int index - input
Zero-based index of the publish record. This value must be less than the count
returned by cwbUN_GetLdapPublishCount().
LPSTR parentDn - output
Pointer to the buffer that will contain the name of the parentDn.
int * length - input/output
Pointer to the length of the parentDn buffer. If the buffer is too small to hold
the string, including space for the terminating NULL, the size of the buffer
needed will be filled into this parameter.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_API_PARAMETER
Invalid index.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWB_BUFFER_OVERFLOW
The suffix buffer is not large enough to hold the entire result.

1072 Client Access Express Programming


Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1073


cwbUN_GetLdapPublishPort
Purpose: Returns the port number of the server used to publish this information.

Syntax:

int cwbUN_GetLdapPublishPort
( cwbUN_ldapPubHandle handle,
int index,
int *port,
cwbUN_LdapCnnSecurity *connectionSecurity
);

Parameters:
cwbUN_ldapPubHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapPublishing().
int index - input
Zero-based index of the publish record. This value must be less than the count
returned by cwbUN_GetLdapPublishCount().
int * port - output
The port number used to connect to the server.
cwbUN_LdapCnnSecurity * connectionSecurity - output
The type of connection used to connect to the server. This indicates the type of
connection that can be established over the associated port. Possible values
include:
CWBUN_LDAPCNN_NORMAL
A normal connection is used.
CWBUN_LDAPCNN_SSL
An SSL connection is used.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_API_PARAMETER
Invalid index.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

1074 Client Access Express Programming


cwbUN_GetLdapPublishServer
Purpose: Returns the name of the server to which this information is published.

Syntax:

int cwbUN_GetLdapPublishServerW
( cwbUN_ldapPubHandle handle,
int index,
LPWSTR server,
int *length
);

int cwbUN_GetLdapPublishServerA
( cwbUN_ldapPubHandle handle,
int index,
LPSTR server,
int *length
);

Parameters:
cwbUN_ldapPubHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapPublishing().
int index - input
Zero-based index of the publish record. This value must be less than the count
returned by cwbUN_GetLdapPublishCount().
LPSTR server - output
Pointer to the buffer that will contain the name of the server.
int * length - input/output
Pointer to the length of the server buffer. If the buffer is too small to hold the
string, including space for the terminating NULL, the size of the buffer needed
will be filled into this parameter.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_API_PARAMETER
Invalid index.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWB_BUFFER_OVERFLOW
The suffix buffer is not large enough to hold the entire result.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1075


cwbUN_GetLdapPublishType
Purpose: Returns the type of information for which this publish record is.

Syntax:

int cwbUN_GetLdapPublishType
( cwbUN_ldapPubHandle handle,
int index,
cwbUN_LdapPubCategories *information
);

Parameters:
cwbUN_ldapPubHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapPublishing().
int index - input
Zero-based index of the publish record. This value must be less than the count
returned by cwbUN_GetLdapPublishCount().
cwbUN_LdapPubCategories * information - output
The type of information for which this publish record is. Possible values
include:
CWBUN_LDAP_PUBLISH_USERS
User information
CWBUN_LDAP_PUBLISH_COMPUTERS
AS/400 systems
CWBUN_LDAP_PUBLISH_NETWORK_INVENTORY
NetFinity
CWBUN_LDAP_PUBLISH_PRINTERS
AS/400 printers

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_API_PARAMETER
Invalid index.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

1076 Client Access Express Programming


cwbUN_GetLdapServerBindDn
Purpose: Returns the distinguished name used by Operations Navigator to bind
to the server. If no name is configured, an empty string will be returned.

Syntax:

int cwbUN_GetLdapServerBindDnA
( cwbUN_ldapBindInfoHandle handle,
LPSTR bindDn,
int *length
);

int cwbUN_GetLdapServerBindDnW
( cwbUN_ldapBindInfoHandle handle,
LPWSTR bindDn,
int *length
);

int cwbUN_GetLdapServerBindDn8 /* returns bindDn in UTF-8 */


( cwbUN_ldapBindInfoHandle handle,
LPSTR bindDn,
int *length
);

Parameters:
cwbUN_ldapBindInfoHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLdapBindInfo().
LPSTR bindDn - output
Pointer to the buffer that will contain the distinguished name used by
Operations Navigator to bind to the server.
int * length - input/output
Pointer to the length of the bindDn buffer. If the buffer is too small to hold the
string, including space for the terminating NULL, the size of the buffer needed
will be filled into this parameter.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_POINTER
NULL pointer was specified.
CWB_BUFFER_OVERFLOW
The suffix buffer is not large enough to hold the entire result.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1077


cwbUN_GetLdapSvrPort
Purpose: Returns the port number that is used by the LDAP server.

Syntax:

int cwbUN_GetLdapSvrPort
( cwbUN_ldapSvrHandle handle,
int *port,
int *sslPort
);

Parameters:
cwbUN_ldapSvrHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLocalLdapServer().
int * port - output
The port number used for LDAP connections.
int * sslPort - output
The port number used for SSL connections.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

1078 Client Access Express Programming


cwbUN_GetLdapSvrSuffixCount
Purpose: Returns the number of suffixes configured for this server. A suffix is the
distinguished name (DN) of a starting point in the directory tree.

Syntax:

int cwbUN_GetLdapSvrSuffixCount
( cwbUN_ldapSvrHandle handle,
int *count
);

Parameters:
cwbUN_ldapSvrHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLocalLdapServer().
int * count - output
The number of suffixes present on the server.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1079


cwbUN_GetLdapSvrSuffixName
Purpose: Returns the distinguished name of the suffix.

Syntax:

int cwbUN_GetLdapSuffixNameA
( cwbUN_ldapSvrHandle handle,
int index,
LPSTR suffix,
int *length
);

int cwbUN_GetLdapSuffixNameW
( cwbUN_ldapSvrHandle handle,
int index,
LPWSTR suffix,
int *length
);

int cwbUN_GetLdapSuffixName8 /* returns suffix in UTF-8 */


( cwbUN_ldapSvrHandle handle,
int index,
LPSTR suffix,
int *length
);

Parameters:
cwbUN_ldapSuffixHandle handle - input
A handle previously obtained by a call to cwbUN_OpenLocalLdapServer().
int index - input
Zero-based index of the suffix. This value must be less than the count returned
by cwbUN_GetLdapSvrSuffixCount().
LPSTR suffix - output
Pointer to the buffer that will contain the distinguished name of the suffix.
int * length - input/output
Pointer to the length of the suffix buffer. If the buffer is too small to hold the
string, including space for the terminating NULL, the size of the buffer needed
will be filled into this parameter.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_API_PARAMETER
Invalid index.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWB_BUFFER_OVERFLOW
The suffix buffer is not large enough to hold the entire result.

Usage: None

1080 Client Access Express Programming


cwbUN_GetListObject
Purpose: Get a pointer to the object associated with the specified list object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetListObject(


const char * szFileName,
LPVOID *pListObject
);

Parameters:
const char * szFileName - input
The Unity object name from which the object pointer will be found and
returned.
LPVOID pListObject - output
Address of a pointer to the request Unity object.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1081


cwbUN_GetODBCConnection
Purpose: Return the handle to an ODBC connection on the specified AS/400
server system. If no connection exists to the specified AS/400, the API obtains a
new handle.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetODBCConnection(


const char * szSystemName,
HDBC *phDBC
);

Parameters:
const char * szSystemName - input
The name of the AS/400 system on which to retrieve an ODBC connection.
HDBC *phDBC - output
Address to return the ODBC connection handle.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.

Usage: None

1082 Client Access Express Programming


cwbUN_GetParentFolderNameFromName
Purpose: Extracts the name of an object’s parent folder from a fully-qualified
Unity object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetParentFolderNameFromName(


const char * szObjectName,
char * szParentFolderName,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the parent folder name will be extracted.
char * szParentFolderPath - output
Address of the buffer that will receive the null-terminated parent folder name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated parent folder name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1083


cwbUN_GetParentFolderPathFromName
Purpose: Given a fully-qualified Unity object name, returns the fully-qualified
object name of the object’s parent folder.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetParentFolderPathFromName(


const char * szObjectName,
char * szParentFolderPath,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the parent folder object name will be
extracted.
char * szParentFolderPath - output
Address of the buffer that will receive the null-terminated parent folder object
name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated parent folder object
name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1084 Client Access Express Programming


cwbUN_GetParentFolderPidl
Purpose: Given a fully-qualified Unity item identifier list, returns the
fully-qualified item identifier list of the object’s parent folder.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetParentFolderPidl(


LPCITEMIDLIST pidl,
LPITEMIDLIST *ppidl
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to an ITEMIDLIST (item identifier list) structure from which the parent
folder item identifier list will be extracted.
LPITEMIDLIST* ppidl - output
Address of an item identifier list pointer that will receive the parent folder
item identifier list.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
The specified item identifier list is not valid.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1085


cwbUN_GetResourceLibraryPath
Purpose: Determines which of the installed languages is supported by the
specified Operations Navigator plug-in, and returns the directory pathname of the
subdirectory that contains the plug-in’s NLS resources for the currently active
language. If the plug-in does not support the active language, the pathname for a
related language that is supported will be returned, if one can be found. Plug-in
developers should use this API to determine from which directory they need to
load their NLS resources.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetResourceLibraryPath(


const char * pszProgID,
char * pszLibraryPath,
UINT cchMax
);

Parameters:
const char * pszProgID - input
The programmatic identifier which uniquely identifies an Operations
Navigator plug-in. It should be of the form <vendor><component>.
char * pszLibraryPath - output
Address of the buffer that will receive the fully-qualified pathname of the NLS
directory.
UINT cchMax - input
Size of the buffer that will receive the fully-qualified pathname of the NLS
directory.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified ProgID is not valid.
CWBUN_RTN_STR_TOO_LONG
The buffer is too small to contain the returned string.
CWBUN_LANG_NOT_FOUND
The specified plug-in does not support any of the languages that are
currently installed on the client.

Usage: None

1086 Client Access Express Programming


cwbUN_GetSharedImageList
Purpose: Retrieve the icon image list associated with Operations Navigator.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetSharedImageList(


UINT uFlags,
HIMAGELIST *phImageList
);

Parameters:
UINT uFlags - input
Specification of the type of image list to retrieve (defined above) The following
flag types are allowed:
GSIL_ICON
GSIL_SMALLICON
HIMAGELIST* phImageList -
Address of the variable that will receive the image list handle.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_INVALID_FLAG_VALUE
Not a valid supported flag value.
CWBUN_CANT_GET_IMAGELIST
A failure occurred while attempting to get the icon image list.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1087


cwbUN_GetSystemHandle
Purpose: Returns a system handle that contains the security (SSL), userID, and
password settings that are used for this AS/400 system. The system handle will
have the settings that were configured in Operations Navigator for the input
AS/400 system name.

If the application name is set to NULL, the returned system handle will be unique.
If the application name is set, the same system handle that matches the application
name will be returned.

If an application requires a unique AS/400 job for a system, then NULL or a


unique name should be passed in for the application name.

If an application requires to share an AS/400 job, then all callers of this function
should pass in the same application name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetSystemHandle(


char * szSystemName,
char * szAppName,
cwbCO_SysHandle * systemHandle
);

Parameters:
char * szSystemName - input
Pointer to an ASCIIZ string that contains the name of the system for which
you want a system handle to be created.
char * szAppName - input
Pointer to an ASCIIZ string of no more than 12 characters. This uniquely
identifies the application that will share a single system handle.
cwbCO_SysHandle * systemHandle - output
Pointer to the handle of the system for this system name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_NULL_PARM
System name was NULL.
CWBUN_INVALID_NAME_PARM
The system name is not valid.
CWB_NON_REPRESENTABLE_UNICODE_CHAR
One or more input UNICODE characters have no representation in the
code page that is being used.
CWB_API_ERROR
The system handle could not be returned.

Usage: This function must be used by all third-party applications that want to
support SSL using the Client Access APIs. For example, all Client Access
communications APIs require a system handle to support SSL.

1088 Client Access Express Programming


When the caller of this function no longer needs the system handle for
communications, the handle can be released by calling function
cwbUN_ReleaseSystemHandle.

All handles will be released when the Operations Navigator application


(cwbunnav.exe) terminates.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1089


cwbUN_GetSystemNameFromName
Purpose: Extracts the AS/400 system name from a fully-qualified Unity object
name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetSystemNameFromName(


const char * szObjectName,
char * szSystemName,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the system name will be extracted.
char * szSystemName - output
Address of the buffer that will receive the null-terminated system name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated system name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1090 Client Access Express Programming


cwbUN_GetSystemNameFromPidl
Purpose: Extracts the AS/400 system name from a fully-qualified Unity item
identifier list.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetSystemNameFromPidl(


LPCITEMIDLIST pidl,
char * szSystemName,
UINT cchMax
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to an ITEMIDLIST (item identifier list) structure from which the system
name will be extracted.
char * szSystemName - output
Address of the buffer that will receive the null-terminated system name.
UINT cchMax - input
Size of the buffer that will receive the null-terminated system name.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
The specified item identifier list is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1091


cwbUN_GetSystemValue
Purpose: Returns a string that contains the value of an AS/400 system value.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetSystemValue(


USHORT usSystemValueId,
const char * szSystemName,
char * szSystemValue,
UINT cchMax
);

Parameters:
const char * szSystemValueId - input
A numeric value that identifies the AS/400 system value to be retrieved.
Definitions for the system value constants are in the header file
’CWBA4SVL.H’
char * szSystemValue - output
Address of the buffer that will receive the null-terminated system value string.
UINT cchMax - input
Size of the buffer that will receive the null-terminated value string.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_INTERNAL_ERROR
Could not retrieve the system value.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: The value that is returned by this API is not a National Language Support
(NLS) string and is not translated. For example, ’*NONE’ will be returned instead
of ’None.’

1092 Client Access Express Programming


cwbUN_GetTypeFromItemId
Purpose: Extracts the item type field from a Unity item identifier.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetTypeFromItemId(


const char * szItemId,
char * szType,
UINT cchMax
);

Parameters:
const char * szItemId - input
The Unity item identifier from which the item type will be extracted.
char * szType - output
Address of the buffer that will receive the null-terminated item type.
UINT cchMax - input
Size of the buffer that will receive the null-terminated item type.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified item identifier not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1093


cwbUN_GetTypeFromName
Purpose: Extracts the item type field from a fully-qualified Unity object name.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetTypeFromName(


const char * szObjectName,
char * szType,
UINT cchMax
);

Parameters:
const char * szObjectName - input
The Unity object name from which the item index will be extracted.
char * szType - output
Address of the buffer that will receive the null-terminated item type.
UINT cchMax - input
Size of the buffer that will receive the null-terminated item type.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
Specified object name is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

1094 Client Access Express Programming


cwbUN_GetTypeFromPidl
Purpose: Extracts the item index field from a fully-qualified Unity item identifier
list.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetTypeFromPidl(


LPCITEMIDLIST pidl,
char * szType,
UINT cchMax
);

Parameters:
LPCITEMIDLIST pidl - input
Pointer to an ITEMIDLIST (item identifier list) structure from which the item
index will be extracted.
char * szType - output
Address of the buffer that will receive the null-terminated item type.
UINT cchMax - input
Size of the buffer that will receive the null-terminated item type.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_FORMAT_NOT_VALID
The specified item identifier list is not valid.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1095


cwbUN_GetUserAttribute
Purpose: Returns a string that contains the value of a user profile attribute for the
current Operations Navigator user.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_GetUserAttribute(


USHORT usAttributeId,
const char * szSystemName,
char * szValue,
UINT cchMax
);

Parameters:
USHORT usAttributeId - input
A numeric value which identifies the user attribute value to be retrieved.
Definitions for the user attribute constants are in the header file
’CWBA4USR.H.’
const char * szSystemName - input
The name of the AS/400 system from which to retrieve the user attribute.
char * szValue - output
Address of the buffer that will receive the null-terminated attribute value
string.
UINT cchMax - input
Size of the buffer that will receive the null-terminated value string.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_INTERNAL_ERROR
Could not retrieve attribute value.
CWB_BUFFER_OVERFLOW
The buffer is too small to contain the returned string.

Usage: The value that is returned by this API is not an NLS string and is not
translated. For example, ’*NONE’ will be returned instead of ’None.’

1096 Client Access Express Programming


cwbUN_IsConnectionTypeTCPIP
Purpose: Determine if the system connection is using TCP/IP for
communications.

Syntax:

CWBAPI BOOL WINAPI cwbUN_IsConnectionTypeTCPIP(


const char * szSystemName
);

Parameters:
const char * szSystemName - input
The name of the AS/400 system which will be checked to determine if a
TCP/IP connection is being used.

Return Codes: The following list shows common return values:


CWB_TRUE
The connection is TCP/IP.
CWB_FALSE
The connection is not TCP/IP.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1097


cwbUN_IsSubcomponentInstalled
Purpose: Determines if an Operations Navigator subcomponent is installed on the
PC.

Syntax:

CWBAPI BOOL WINAPI cwbUN_IsSubcomponentInstalled(


UNIT uOption);

Parameters:
UNIT uOption
Specifies the Operations Navigator subcomponent to check. See the API’s
prolog in cwbun.h for a list of supported values.

Return Codes: Returns a boolean value.


TRUE If the subcomponent is installed.
FALSE
If the subcomponent is not installed

Usage: None.

1098 Client Access Express Programming


cwbUN_NullBindToLdapServer
Purpose: Performs an unauthenticated bind to the server. If an SSL port is
provided, it will use cached SSL configuration (key ring file and password). If any
required information is not available, a dialog is displayed to collect the data. If an
error occurs, a message is displayed to the user.

The connection is established through the Client Access LDAP client (LDAP.LIB
and LDAP.DLL), and only can be used with that client.

This API will attempt to establish bind using LDAP version 3, and then LDAP
version 2. Use the ldap_get_option LDAP client API to determine what version the
bind used if you need to use LDAP version 3 client APIs with the connection.

Syntax:

int cwbUN_NullBindToLdapServerA
( LPCSTR server,
int port,
int sslPort,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

int cwbUN_NullBindToLdapServerW
( LPCWSTR server,
int port,
int sslPort,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

Parameters:
LPCSTR server - input
NULL terminated name of directory server or dotted IP address.
int port - input
The port to be used for standard connections. Specify 0 to force an SSL
connection.
int sslPort - input
The port to be used for SSL connections. Specify 0 if SSL connections are not
supported by the server.
cwbUN_LdapBindOption options - input
Specifies options controlling the display of error messages and the ″Connect to
Directory Server″ dialog. Possible values are:
CWBUN_LDAP_BINDOPT_NO_DLG
Do not show the ″Connect To Directory Server″ dialog and do not
display any error messages.
CWBUN_LDAP_BINDOPT_DLG_ON_ERR
Show the ″Connect To Directory Server″ dialog and error messages.
The user has the opportunity to change bind information if an error
occurs.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1099


CWBUN_LDAP_BINDOPT_SHOW_DLG
Show the ″Connect to Directory Server″ dialog before attempting to
connect to the server. The user has the opportunity to change bind
information before connecting to the server.
int version - input
Specifies the LDAP API version to use for binding to the server. Possible
values are:
LDAP_VERSION2 (from ldap.h)
Bind as a LDAP version 2 client.
LDAP_VERSION3 (from ldap.h)
Bind as a LDAP version 3 client. If the server does not support version
3, the bind will fail with a protocol error.
CWBUN_LDAP_VERSION_LATEST
Bind as a LDAP version 3 client if supported by the server. Otherwise,
bind as a LDAP version 2 client.
LDAP **LPldap - output
On return, *LPldap points to the LDAP* returned by the LDAP bind APIs.
HWND hwnd - input
Window handle to be used for messages. This handle also will be used as the
parent window of the ″Connect to Directory server″ dialog. NULL can be
specified.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_BIND_FAILED
A connection could not be established to the server.

Usage: None

1100 Client Access Express Programming


cwbUN_NullBindToLdapServerOnAs400
Purpose: Performs an unauthenticated bind to the server. If any required
information is not available, a dialog is displayed to collect the data. If an error
occurs, a message is displayed to the user.

The connection is established through the Client Access LDAP client (LDAP.LIB
and LDAP.DLL), and only can be used with that client.

This API will attempt to establish bind using LDAP version 3, and then LDAP
version 2. Use the ldap_get_option LDAP client API to determine what version the
bind used if you need to use LDAP version 3 client APIs with the connection.

Syntax:

int cwbUN_NullBindToLdapServerOnAs400A
( LPCSTR system,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

int cwbUN_NullBindToLdapServerOnAs400W
( LPCWSTR system,
cwbUN_LdapBindOption options,
int version,
HWND hwnd,
void **LPldap
);

Parameters:
LPCSTR system - input
NULL terminated AS/400 system name.
int port - input
The port to be used for standard connections. Specify 0 to force an SSL
connection.
int sslPort - input
The port to be used for SSL connections. Specify 0 if SSL connections are not
supported by the server.
cwbUN_LdapBindOption options - input
Specifies options controlling the display of error messages and the ″Connect to
Directory Server″ dialog. Possible values are:
CWBUN_LDAP_BINDOPT_NO_DLG
Do not show the ″Connect To Directory Server″ dialog and do not
display any error messages.
CWBUN_LDAP_BINDOPT_DLG_ON_ERR
Show the ″Connect To Directory Server″ dialog and error messages.
The user has the opportunity to change bind information if an error
occurs.
CWBUN_LDAP_BINDOPT_SHOW_DLG
Show the ″Connect to Directory Server″ dialog before attempting to
connect to the server. The user has the opportunity to change bind
information before connecting to the server.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1101


int version - input
Specifies the LDAP API version to use for binding to the server. Possible
values are:
LDAP_VERSION2 (from ldap.h)
Bind as a LDAP version 2 client.
LDAP_VERSION3 (from ldap.h)
Bind as a LDAP version 3 client. If the server does not support version
3, the bind will fail with a protocol error.
CWBUN_LDAP_VERSION_LATEST
Bind as a LDAP version 3 client if supported by the server. Otherwise,
bind as a LDAP version 2 client.
LDAP **LPldap - output
On return, *LPldap points to the LDAP* returned by the LDAP bind APIs.
HWND hwnd - input
Window handle to be used for messages. This handle also will be used as the
parent window of the ″Connect to Directory server″ dialog. NULL can be
specified.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_NOT_AVAIL
Directory services is not installed or the server has not been configured.
CWBUN_LDAP_BIND_FAILED
A connection could not be established to the server.

Usage: None

1102 Client Access Express Programming


cwbUN_OpenLdapBindInfo
Purpose: Creates a handle that can be used to access information about how the
current user on a PC connects to an LDAP server through Operations Navigator.

Syntax:

int cwbUN_OpenLdapBindInfoW
( LPCWSTR server,
cwbUN_ldapBindInfoHandle *pHandle
);

int cwbUN_OpenLdapBindInfoA
( LPCSTR server,
cwbUN_ldapBindInfoHandle *pHandle
);

Parameters:
LPCSTR server - input
Pointer to LDAP server name or IP address.
cwbUN_ldapBindInfoHandle *pHandle - output
On return, contains a handle that can be used with the following APIs:
v cwbUN_FreeLdapBindInfo
v cwbUN_GetLdapServerBindDn

Note: This handle should be released with a call to


cwbUN_FreeLdapBindInfo().

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_POINTER
A NULL pointer was specified.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1103


cwbUN_OpenLdapPublishing
Purpose: Creates a handle that can be used to access configuration information
about information published by this AS/400 to LDAP directories.

Syntax:

int cwbUN_OpenLdapPublishingW
( LPCWSTR system,
cwbUN_ldapPubHandle *pHandle
);

int cwbUN_OpenLdapPublishingA
( LPCSTR system,
cwbUN_ldapPubHandle *pHandle
);

Parameters:
LPCSTR system - input
Pointer to AS/400 system name.
cwbUN_ldapSvrHandle *pHandle - output
On return, contains a handle that can be used with the following APIs:
cwbUN_FreeLdapPublishing
cwbUN_GetLdapPublishCount
cwbUN_GetLdapPublishType
cwbUN_GetLdapPublishParentDn
cwbUN_GetLdapPublishServer
cwbUN_GetLdapPublishPort

Note: This handle should be released with a call to


cwbUN_FreeLdapPublishing().

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_API_HANDLE
Invalid handle.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_NOT_AVAIL
Directory services is not installed or the server has not been configured.

Usage: None

1104 Client Access Express Programming


cwbUN_OpenLocalLdapServer
Purpose: Creates a handle that can be used to access configuration information
about the Directory Services (LDAP) server on the AS/400.

Syntax:

int cwbUN_OpenLocalLdapServerW
( LPCWSTR system,
cwbUN_ldapSvrHandle *pHandle
);

int cwbUN_OpenLocalLdapServerA
( LPCSTR system,
cwbUN_ldapSvrHandle *pHandle
);

Parameters:
LPCSTR system - input
Pointer to AS/400 system name.
cwbUN_ldapSvrHandle *pHandle - output
On return, contains a handle that can be used with the following APIs:
v cwbUN_FreeLocalLdapServer
v cwbUN_GetLdapSvrPort
v cwbUN_GetLdapSvrSuffixCount
v cwbUN_GetLdapSuffixName

Note: This handle should be released with a call to


cwbUN_FreeLocalLdapServer

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_INVALID_API_PARAMETER
Invalid parameter specified.
CWB_INVALID_POINTER
A NULL pointer was specified.
CWBUN_LDAP_NOT_AVAIL
Directory Services is not installed or the server has not been configured.

Usage: None

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1105


cwbUN_RefreshAll
Purpose: Refreshes the contents of the tree window and the list window for the
Operations Navigator.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_RefreshAll(


const char * pszStatusText
);

Parameters:
const char * pszStatusText - input
A null-terminated string to be placed in the status bar window on completion.
This parameter may be NULL.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_WINDOW_NOTAVAIL
Could not find the view windows.

Usage: Use this function to refresh the entire contents of the Operations Navigator
after performing an action that is requested by the user.

1106 Client Access Express Programming


cwbUN_RefreshList
Purpose: Refreshes the contents of the list view window for the Operations
Navigator.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_RefreshList(


const char * pszStatusText
);

Parameters:
const char * pszStatusText - input
A null-terminated string to be placed in the status bar window on completion.
This parameter may be NULL.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_WINDOW_NOTAVAIL
Could not find list view window.

Usage: Use this function to refresh the contents of the list window after
performing an action that is requested by the user.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1107


cwbUN_RefreshListItems
Purpose: Refreshes the currently selected item (or items) in the list view window
of the Operations Navigator.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_RefreshListItems(


const char * pszStatusText
);

Parameters:
const char * pszStatusText - input
A null-terminated string to be placed in the status bar window on completion.
This parameter may be NULL.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_WINDOW_NOTAVAIL
Could not find list view window.

Usage: Use this function to refresh the selected items in the list window after
performing an action that was requested by the user.

1108 Client Access Express Programming


cwbUN_ReleaseSystemHandle
Purpose: Releases a system handle that contains the security (SSL) settings to be
used for this AS/400 system. The system handle is obtained using the
cwbUN_GetSystemHandle function.

If the caller of this function has the last reference to the handle, the handle
resources actually will be destroyed.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_ReleaseSystemHandle(


cwbCO_SysHandle * systemHandle
);

Parameters:
cwbCO_SysHandle * systemHandle - input
Pointer to the handle of the system that was obtained on a
cwbUN_GetSystemHandle call.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWB_API_ERROR
The system handle could not be released.

Usage: When the caller of this function no longer needs the system handle for
communications, the handle can be released.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1109


cwbUN_UpdateStatusBar
Purpose: Inserts a text string into the status bar of the Operations Navigator
window.

Syntax:

CWBAPI unsigned int WINAPI cwbUN_UpdateStatusBar(


const char * pszStatusText
);

Parameters:
const char * pszStatusText - input
A null-terminated string to be placed in the status bar window on completion.

Return Codes: The following list shows common return values:


CWB_OK
Successful completion.
CWBUN_WINDOW_NOTAVAIL
Could not find status bar window.

Usage: Use this function to inform the user that an action that was requested by
clicking the OK button on a dialog has completed successfully.

1110 Client Access Express Programming


Return codes unique to Operations Navigator APIs
6000 CWBUN_BAD_PARAMETER
An input parameter was not valid.
6001 CWBUN_FORMAT_NOT_VALID
The input object name was not valid.
6002 CWBUN_WINDOW_NOTAVAIL
View window not found.
6003 CWBUN_INTERNAL_ERROR
Processing error occurred.
6004 CWBUN_USER_NOT_AUTHORIZED
User does not have specified authority.
6005 CWBUN_OBJECT_NOT_FOUND
Object not found on the AS/400.
6006 CWBUN_INVALID_ITEM_ID
Invalid item ID parameter.
6007 CWBUN_NULL_PARM
NULL parameter passed.
6008 CWBUN_RTN_STR_TOO_LONG
String too long for return buffer.
6009 CWBUN_INVALID_OBJ_NAME
Invalid object name parameter.
6010 CWBUN_INVALID_PIDL
Invalid PIDL parameter.
6011 CWBUN_NULL_PIDL_RETURNED
Parent folder PIDL was NULL.
6012 CWBUN_REFRESH_FAILED
Refresh list failed.
6012 CWBUN_UPDATE_FAILED
Update toolbar failed.
6013 CWBUN_INVALID_NAME_TYPE
Invalid AS/400 name type.
6014 CWBUN_INVALID_AUTH_TYPE
Invalid authority type.
6016 CWBUN_HOST_COMM_ERROR
AS/400 communications error.
6017 CWBUN_INVALID_NAME_PARM
Invalid name parameter.
6018 CWBUN_NULL_DISPLAY_STRING
Null display string returned.
6019 CWBUN_GENERAL_FAILURE
General AS/400 operation failure.
6020 CWBUN_INVALID_SYSVAL_ID
Invalid system value ID.
6021 CWBUN_INVALID_LIST_OBJECT
Can not get list object from name.
6022 CWBUN_INVALID_IFS_PATH
Invalid IFS path specified.
6023 CWBUN_LANG_NOT_FOUND
Extension does not support any of the languages installed.
6024 CWBUN_INVALID_USER_ATTR_ID
Invalid user attribute ID.
6025 CWBUN_GET_USER_ATTR_FAILED
Unable to retrieve user attribute.
6026 CWBUN_INVALID_FLAG_VALUE
Invalid flag parameter value set.
6027 CWBUN_CANT_GET_IMAGELIST
Cannot get icon image list.

The following return codes are for name check APIs.

6050 CWBUN_NAME_TOO_LONG
Name is too long.
6051 CWBUN_NAME_NULLSTRING
String in empty - no chars at all.
6054 CWBUN_NAME_INVALIDCHAR
Invalid character.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1111


6055 CWBUN_NAME_STRINGTOOLONG
String too long.
6056 CWBUN_NAME_MISSINGENDQUOTE
End quote missing.
6057 CWBUN_NAME_INVALIDQUOTECHAR
Char invalid for quote string.
6058 CWBUN_NAME_ONLYBLANKS
A string of only blanks found.
6059 CWBUN_NAME_STRINGTOOSHORT
String is too short.
6060 CWBUN_NAME_TOOLONGFORIBM
String OK, too long for IBM cmd.
6011 CWBUN_NAME_INVALIDFIRSTCHAR
The first char is invalid.
6020 CWBUN_NAME_CHECK_LAST
Reserved range.

The following return codes are for LDAP-related APIs.

6101 CWBUN_LDAP_NOT_AVAIL
LDAP is not installed or configured.
6102 CWBUN_LDAP_BIND_FAILED
LDAP bind failed.

The following return codes are for check AS/400 name APIs.

1001 CWBUN_NULLSTRING
String is empty.
1004 CWBUN_INVALIDCHAR
Invalid character.
1005 CWBUN_STRINGTOOLONG
String is too long.
1006 CWBUN_MISSINGENDQUOTE
End quote for quoted string missing.
1007 CWBUN_INVALIDQUOTECHAR
Character invalid for quoted string.
1008 CWBUN_ONLYBLANKS
String contains only blanks.
1009 CWBUN_STRINGTOOSHORT
String is less than the defined minimum.
1011 CWBUN_TOOLONGFORIBM
String is OK, but too long for IBM commands.
1012 CWBUN_INVALIDFIRSTCHAR
First character is invalid.
1999 CWBUN_GENERALFAILURE
Unspecified error.

Java plug-ins
To create Operations Navigator plug-ins in Java, you must create one or more Java
classes that implement certain predefined interfaces. The class files and any
associated strings and graphics resources are then packaged into one or more Java
Archive (JAR) files for distribution to Operations Navigator users. When
Operations Navigator detects that one or more Java plug-ins are installed, the IBM
Win32 Java virtual machine is loaded into the Navigator’s process space. Running
Java code in Operations Navigator is similar to running Java code in a Web
browser; the plug-in may be thought of as an Operations Navigator applet. For
V4R5, Java plug-ins must be written to run on version 1.1.8 of the Java virtual
machine, using version 1.1.1 of the Swing classes.

Certain predefined information about the plug-in must be provided by the


developer in the form of a Windows registry file. This information is written to the
user’s registry when the plug-in is installed. The registry information allows
Operations Navigator to identify the new plug-in and call its implementation in

1112 Client Access Express Programming


response to appropriate user actions. For more information, see “The Windows
registry for Operations Navigator plug-ins” on page 982 and “Registry files for
Operations Navigator plug-ins” on page 983.
Java plug-ins overview topics:
v “Product architecture for Operations Navigator Java plug-ins”
v “Operations Navigator structure and flow of control for Java plug-ins”
on page 1117
Developing Java plug-ins topics:
v “Developing Operations Navigator Java plug-ins” on page 1118
v “Installing Java plug-ins” on page 1121
v “Identifying Java plug-ins to Operations Navigator” on page 1121

Product architecture for Operations Navigator Java plug-ins


The internal architecture of the Operations Navigator product reflects that it is
intended to serve as an integration point for an extensible, broad-based operations
interface for the AS/400. Each functional component of the interface is packaged as
an ActiveX server. The Navigator learns about the existence of a particular server
component by means of entries in the Windows registry. Multiple servers may
register their request to add menu items and dialogs to a given object type in the
Navigator hierarchy. For information about the Microsoft Component Object Model

(COM) and ActiveX servers, see the Microsoft Web site .


AS/400 Toolbox for Java
The AS/400 Toolbox for Java is a set of Java classes that allow you to
access AS/400 data through a Java program. It includes the Graphical
Toolbox, which contains tools to help you create custom user interface
panels and incorporate them into your Operations Navigator plug-ins, and
information on Program Call Markup Language (PCML), an Extensible
Markup Language (XML)-based tag language that helps you call AS/400
programs, but with writing less Java code.

Note: For third-party Java plug-ins to be available to Operations


Navigator users, Client Access users must have Version 4 Release 4
Modification Level 0 of Client Access Express for Windows installed
on their personal computers.
Product architecture for Operations Navigator Java plug-ins topics:
v “Using Secure Sockets Layer in Java plug-ins”
v Operations Navigator Java plug-ins javadoc documentation

Using Secure Sockets Layer in Java plug-ins


Secure Sockets Layer (SSL) provides secure connections by encrypting the data
that is exchanged between a client and an AS/400 server session, and by
performing server authentication. There is an increased cost in performance with
SSL because SSL connections perform slower than connections without encryption.
SSL can be used only with an SSL-capable AS/400 running OS/400, V4R4 or later.
You use SSL connections when the sensitivity of the data transferred merits the
increased cost in performance (for example, with credit card or bank statement
information).

Note: If you are running Java over SSL, and creating your own CA certificate,
Client Access GA service pack is required.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1113


For more information on using Secure Sockets Layer in Java plug-ins, link to the
Secure Sockets Layer topic in the AS/400 Toolbox for Java.
Using Secure Sockets Layer in Java plug-ins topics:
v “SSL versions”
v “SSL considerations for AS/400 Operations Navigator Java plug-ins”
v “Using SSL”

SSL versions: AS/400 Toolbox for Java does not contain the algorithms needed to
encrypt and decrypt data. These algorithms are shipped with AS/400 licensed
programs 5769-CE1, 5769-CE2, and 5769-CE3. You need to order one of the
5769-CEx product versions of SSL depending on the country in which you live.
Contact your IBM representative for more information, or to order:
v AS/400 Client Encryption (40-bit), 5769-CE1, is used in France.
v AS/400 Client Encryption (56-bit), 5769-CE2, is used in countries other than the
US, Canada or France.

Note: 5769-CE2 client encryption is only 40-bit within AS/400 Toolbox for Java.
v AS/400 Client Encryption (128-bit), 5769-CE3, is used only in the United States
and Canada.

SSL considerations for AS/400 Operations Navigator Java plug-ins: Before you
use SSL with an AS/400 Operations Navigator Java plug-in, you should take into
consideration the following:
v You must understand your legal responsibilities. IBM AS/400 Client Encryption
products provide SSL Version 3.0 encryption support using non-exportable
128-bit (designated US and Canada use only) and exportable 40-bit encryption
algorithms for international use.
v In customer configurations where client encryption products might be
downloaded across national boundaries, the customer is responsible to assure
that the non-exportable client encryption products are not made available
outside the US and Canada. Both the non-exportable and exportable Client
Encryption products can be used in combination to allow the appropriate Client
Encryption product to be downloaded based on different URLs.
v You must install a Cryptographic Access Provider licensed program (5769-AC1,
5769-AC2, or 5769-AC3). The 5769-CE products provide encryption capabilities
on the client side. You also need encryption on the AS/400 side, which is
provided by the 5769-AC products. Contact your IBM representative for more
information.
v If you are creating your own CA certificate, Client Access GA service pack is
required.

Using SSL: To use SSL, the AS/400 Java Toolbox and the Secure Sockets Layer
(SSL) components must be selected during installation of AS/400 Client Access
Express for Windows.

1114 Client Access Express Programming


Note: You also can add these components by using AS/400 Client Access Express
for Windows Selective Setup.

When installation of the required components is complete, restart your computer.


Additionally, if you are creating your own CA certificate, Client Access GA service
pack is required.
Related topics:
v “SSL certificates”
v “Building your own SSL certificates” on page 1116

SSL certificates: You can use two types of SSL certificates:


v Certificates from a trusted authority
v Certificates that you build

If you are using certificates issued by a trusted authority, you need to perform the
following steps:
1. Install the certificate authority certificate on the AS/400.
2. Apply the certificate to your host servers.

Afterward, the certificate keyring is set up for you, the connection is secure, and
SSL is working for you. When you choose to use a trusted certificate authority,
there are no further steps required on the client.

AS/400 Toolbox for Java supports certificates that are issued by the following
trusted authorities:
v VeriSign, Inc
v Integrion Financial Network
v IBM World Registry
v Thawte Consulting
v RSA Data Security, Inc.

If you choose not to use a certificate from a trusted authority, you can build your
own certificate. Benefits of building your own certificate include:
v You do not have to pay for it.
v You have more control over it.
v You are putting together a local intranet of systems.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1115


Building your own SSL certificates:

Note: Client Access GA service pack is required to build your own CA certificate.

When you choose to create your own SSL certificates, there are several steps
required to set them up for use with Java plug-ins:
1. Create a file called makekey.bat. This file simplifies the creation and
installation of the AS/400 SSL keys that are needed to run by using secure
sockets:
@echo off
if %1.==. goto error

REM Make sure that the next two lines point at the AS/400 Client Access Express for Windows Classes directory:

C:
cd "\Program Files\IBM\Client Access\Classes"

set port=9476
if not %2.==. set port=%2
mkdir com
mkdir com\ibm
mkdir com\ibm\as400
mkdir com\ibm\as400\access
echo Password is: toolbox
..\jre\bin\jre -nojit -classpath
..\jre\lib\rt.jar;..\jt400\lib\jt400.jar;..\jt400\lib\SSLTools.zip;..\jt400\lib\sslightu.zip;
..\jt400\lib\sslightx.zip; com.ibm.sslight.nlstools.keyrng com.ibm.as400.access.KeyRing connect %1:%port%
goto end
:error
echo usage: makekey system [port]
:end
2. Run this program, and provide the name of the AS/400 system to which you
will connect by using SSL. If your system administrator has set up SSL on a
port other than 9476, provide that port number as the second parameter.
The certificate that you need to copy from the AS/400 system to the client is
the Certificate Authority (CA) certificate, NOT a site certificate.

Note: If you will be using certificates provided by a trusted authority and SSL
certificates that you build yourself, it will be necessary to extract the
com.ibm.as400.access.KeyRing.class file from jt400.jar file and place it in
the c:\Program Files\IBM\Client
Access\Classes\com\ibm\as400\access subdirectory before you run the
makekey program.
makekey systemname portnumber
The password required by the makekey program is: toolbox.
makekey systemname
Password is: toolbox
Password for com.ibm.as400.access.KeyRing.class: toolbox
Connecting to systemname: 9,476

-------------------------- Server Certificate Chain --------------------------

Site Certificate - Number 0

Key : RSA/512 bits


Subject: SYSTEMNAME.DOMAINNAME.COM,
Issuer: SSL Test Certificate
Valid from: 12/2/98 3:02 AM
Valid to: 12/3/99 3:02 AM
Fingerprint: 17:0D:E5:9A:6B:CC:AD:B5:21:3A:56:FA:AD:12:13:DB

CA Certificate - Number 1

Key : RSA/512 bits


Subject: SSL Testing CA
Issuer: SSL Testing CA
Valid from: 12/2/98 2:57 AM
Valid to: 12/2/01 2:57 AM
Fingerprint: E1:F2:45:4A:1D:84:D5:B1:02:5A:81:6C:0E:9E:13:A2

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

1116 Client Access Express Programming


Enter the number of the certificate to be added to com.ibm.as400.access.KeyRing.class (q to qu
1
Adding the CA Certificate - 1 to com.ibm.as400.access.KeyRing.class
Done.

3. Remember that you will need to run makekey for every AS/400 system that
you will run by using SSL. After a connection to the AS/400 system has been
configured by using AS/400 Operations Navigator, it is necessary to specify
SSL as the connection method:
a. Right-click on the AS/400 system name in AS/400 Operations Navigator,
and select Properties.
b. Select the Connections tab.
c. In the Security box, select Use Secure Sockets Layer (SSL). (insert AS/400
properties dialog, viewed by right-clicking on a configured AS/400 system)
d. Press OK to continue.
e. Restart AS/400 Operations Navigator to enable the SSL connection to the
AS/400 system.

Operations Navigator structure and flow of control for Java


plug-ins
Operations Navigator quickly is becoming the AS/400’s primary user interface.
From a programming standpoint, there must not be any architectural limits built
into the Navigator that would prevent developers from continually being able to
add new function. For this reason, Operations Navigator components are packaged
as ActiveX server DLLs. The Navigator uses Microsoft’s Component Object Model
(COM) technology to activate only the component implementations that currently
are needed to service a user request. This avoids the problem of having to load the
entire product at startup, thereby consuming the majority of Windows resources,
and impacting performance of the entire system.

For Java plug-ins, Operations Navigator provides a built-in ActiveX server that
manages the communication between the Navigator and the plug-in’s Java classes.
The server component uses the Java Native Interface (JNI) API to create the
plug-in’s objects and to call their methods. Thus, Java programmers who are
developing Operations Navigator plug-ins do not need to be concerned with the
details of ActiveX server implementation.

When a user is interacting with Operations Navigator Java plug-ins, calls will be
generated to the different registered Java interface classes for the implementation
of the specific request.

Plug-ins work by responding to method calls from Operations Navigator that are
generated in response to user actions. For example, when a user right-clicks on an
object in the Navigator hierarchy, the Navigator constructs a context menu for the
object, and displays the menu on the screen. The Navigator obtains the menu items
by calling each plug-in that has registered its intent to supply context menu items
for the selected object type.

The functions that are implemented by a plug-in logically are grouped into
″interfaces.″ An interface is a set of logically related methods on a class that
Operations Navigator can call to perform a specific function. For Java plug-ins, the
following three Java interfaces are defined:
v ListManager
v ActionsManager

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1117


v DropTargetManager
Operations Navigator structure and flow of control for Java plug-ins topics:
v Operations Navigator Java interfaces
v “The Windows registry for Operations Navigator plug-ins” on page 982
v “Operations Navigator data for Java plug-ins”
v “Operations Navigator services from a Java plug-in”

Operations Navigator data for Java plug-ins


When the Navigator calls a function implemented by a plug-in, the request
typically involves an object or objects the user selected in the main Navigator
window. The plug-in must be able to determine which objects have been selected.

The plug-in receives this information as a list of fully-qualified object names. For
Java plug-ins, an ObjectName class is defined that provides information about the
selected objects.

Plug-ins that add folders to the object hierarchy must return items in the folder to
Operations Navigator in the form of ″item identifiers.″ For Java plug-ins, an
ItemIdentifier class is defined that is used by the plug-in to return the requested
information.

See Operations Navigator Java interfaces for more information.

Operations Navigator services from a Java plug-in


An Operations Navigator plug-in sometimes will need to affect the behavior of the
main Navigator window. For example, following completion of a user operation, it
may be necessary to refresh the Navigator list view or to insert text into the
Navigator’s status area. Utility classes are supplied in the package
com.ibm.as400.opnav that provide the required services.

Developing Operations Navigator Java plug-ins


One of the best ways to learn about Operations Navigator plug-ins is to build one.
This section provides instructions for creating a new Operations Navigator Java
plug-in. The instructions use the sample Java plug-in that is available in Client

Access Express Toolkit - Operations Navigator Plug-ins .


Details:
1. For V4R5, Java plug-ins must be created by using Sun Microsystems JDK 1.1.8
and Swing release 1.1.1. To compile the sample, you also must include the file
jopnav.jar in your classpath. The jopnav.jar file may be found in the
directory Client Access\classes. It contains the package com.ibm.as400.opnav,
which contains the Java classes and interfaces that are needed to build a Java
plug-in.
2. The sample’s user interface was developed by using the Graphical Toolbox for
Java, which is a part of the AS/400 Toolbox for Java. The Toolbox is an
optionally installable component of Client Access Express, and may be installed
by using Client Access Selective Setup. The sample provides instructions on
how to install and to use the Toolbox classes. See the AS/400 Toolbox for Java
for more information.
3. All Java plug-ins require a small Windows resource DLL that contains certain
information about your plug-in. This allows Operations Navigator to represent
your function in the Navigator object hierarchy without having to load your
plug-in’s implementation. The sample’s resource DLL was created by using

1118 Client Access Express Programming


Microsoft’s Visual C++ version 4.2, but any C compiler that supports compiling
and linking Windows resources may be used.
4. Operations Navigator does not support attaching a debug process to the
Navigator’s Java Virtual Machine. Instead, a Java console is provided as an aid
to debugging. The console is activated by selecting a registry file to write the
required console indicators to the Windows registry. When the console is
activated, the JIT compiler is turned off to allow source code line numbers to
appear in the stack trace, and any exceptions that are encountered in the
Navigator’s Java infrastructure will be displayed in message boxes. The registry
files for activating and for deactivating the console are provided with the
sample Java plug-in.
How to develop a Java plug-in:
To develop an Operations Navigator Java plug-in, complete the following
tasks:
1. Install and run the Java sample plug-in.
2. Customize your new Java plug-in.
3. Diagnose any Java plug-in errors.
4. Prepare the Java plug-in for final delivery and installation.

Installing and running the Java sample plug-in


To install and to run the Java sample plug-in, download the sample from theClient

Access Express Toolkit - Operations Navigator Plug-ins Web page . The sample
includes detailed set-up instructions and documentation.
What to do next:
Customize your new Java plug-in.

Customizing Java plug-ins


When you customize your new Java plug-in, you incorporate the unique function
that you intend to make available to Operations Navigator users. Follow these
steps to customize your Java plug-in:
1. Create Windows registry files for the plug-in.
2. Implement the appropriate Java classes.

Note: You can copy sections of the Operations Navigator sample Java plug-in to
use as a base for your new plug-in.
What to do next:
Diagnose any Java plug-ins errors.

Diagnosing Java plug-ins errors


For some plug-ins errors, including:
v Incorrect registry-entry specifications
v Windows unable to load server DLL
the only visible symptom in the main Operations Navigator dialog is the absence
of the plug-in function. To help you determine the source of errors, Operations
Navigator writes error messages to the Client Access History Log.
To access the History Log:
Select IBM AS400 Client Access Express, --> Service --> History Log.

Note: By default, the History Log is not active. To ensure that error messages are
written to this file, History logging must be started. See the Express User’s
Guide, which is shipped with Client Access Express, for information on
starting the History Log.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1119


The entries in the History Log consist of messages with and without message IDs.
Messages with message IDs have online help available. Messages without message
IDs do not have online help available.
Displaying recovery information for error messages with IDs:
To display the cause and recovery information associated with a message
that has a message ID, double-click on it. View any message that has a
message ID by selecting the Message topic in the online Express User’s
Guide.

Client Access Express also has associated messages that are logged on the AS/400
system. These messages begin with PWS or IWS.
To display messages that are logged on the AS/400 system:
Type the appropriate command (displayed below) at the AS/400
command-line prompt, where xxxx is the number of the message:
DSPMSGD RANGE(IWSxxxx) MSGF(QIWS/QIWSMSG)

DSPMSGD RANGE(PWSxxxx) MSGF(QIWS/QIWSMSG)


For error-handling information that is specific to Express C/C++ APIs:
See “Express return codes and error messages” on page 15

Preparing Java plug-ins for final delivery and installation


When you are satisfied with the function that you have developed to extend the
AS/400 Operations Navigator, it is time to prepare the plug-in for final delivery to
customers as part of an OS/400 licensed program. For your Java plug-in files to be
available for installation on client PCs, they must reside in the following AS/400
directory:
/QIBM/USERDATA/OpNavPlugin
Use this directory for Java plug-ins. Use Client Access Express to Install
plug-ins in this directory. Client Access is unable to install them.

Each OS/400 licensed program that has an associated Operations Navigator


plug-in should create its own subdirectory at this location as part of its normal
install processing. The name of this subdirectory must match the
<vendor>. <component> string that is defined for the plug-in in the registry file.

For Operations Navigator Java plug-ins, the subdirectory should contain:


v The registry file for the plug-in.
v The Express setup file for the plug-in.
v The Java JAR file that contains all Java classes, HTML files, gif files, PDML files,
PCML files, and serialization files.

If the plug-in supports Windows policies, include the .adm policy template file for
the plug-in in the MRI29xx directory.

The plug-in must create at least one directory below the


<VENDOR>.<COMPONENT> subdirectory that is named MRI29XX, where XX
identifies a supported language. For more information about MRI codes, see the
following IBM publication: AS/400 International Application Development: SC41–5603.
This directory contains the correct national language version of the following
items:
v The resource DLL for the plug-in
v The “MRI setup file” on page 996 for the plug-in.
v The Java JAR file that contains list resource bundle Java files, and HTML files.

1120 Client Access Express Programming


Note: These files must reside in the Code Java Jar file for the English Language.
This file is used for non-English installs only.
Related topic:
“Application Administration support for your plug-in” on page 996

Installing Java plug-ins


You can deliver your Java plug-in code to Operations Navigator users by including
it with your OS/400 applications. The install program for the application writes
the plug-in’s code binaries, registry file, and translatable resources to the
/QIBM/UserData/OpNavPlugins folder in the AS/400 Integrated File System
(AS/400 IFS). Once this process is completed, users can obtain the plug-in from the
AS/400 IFS (with the help of an AS/400 NetServer mapped network drive) by
invoking the Client Access Selective Setup program. The setup program copies
your plug-in code to the user’s machine, downloads the appropriate translatable
resources based on the language settings on the user’s PC, and runs the registry
file to write your plug-in’s registry information to the Windows registry. All you
need is a setup file, which identifies the files to be installed. If you provide a
Windows policy template with your plug-in, you also can take advantage of
Windows system policies to control which network users can install your plug-in.
You also can use the AS/400-based Application Administration support of
Operations Navigator to control which users and groups have access to your
plug-in.
Additional resources for Application Administration support information:
v “Application Administration support for your plug-in” on page 996
v Application Administration topic in the Information Center

After the users have installed your new plug-in, you may choose either to upgrade
it at a later date, or to ship code problem fixes. When the code is upgraded on the
AS/400, the Client Access Check Version program detects that this process has
occurred, and automatically downloads the updates to the users’ PCs. Client
Access also provides uninstall support, which allows users to completely remove
the plug-in from their PCs.

Users can display the plug-ins that are installed on their PCs by selecting the
Plug-ins tab on the Operations Navigator Properties for a particular AS/400.

Identifying Java plug-ins to Operations Navigator


Java plug-ins identify themselves to Operations Navigator by supplying
information in the Windows registry (see “The Windows registry for Operations
Navigator plug-ins” on page 982 for more information). This information is
supplied when the plug-in software is installed on a user’s PC. The registry entries
specify the location of the plug-in code, and identify the classes that implement the
special plug-in interfaces. You can supply additional registry information that
instructs Operations Navigator whether to activate the plug-in’s function for a
particular AS/400 system. For example, a plug-in may require a certain minimum
release of OS/400, or it may specify that a certain product must be installed on the
AS/400 in order for it to function.

When a user makes a selection on an AS/400 in the Operations Navigator tree


after installing a plug-in, the AS/400 is examined to determine whether it is
capable of supporting the new plug-in. The software prerequisites (specified in the
plug-in’s registry entries) are compared against the software that is installed on the
AS/400. If the plug-in’s requirements are satisfied, the new function is displayed in

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1121


the Navigator tree. If the requirements are not met, the plug-in’s function does not
appear in the Navigator tree hierarchy for that AS/400. However, the plug-in may
participate in the determination of whether to be included in the hierarchy, by
implementing a special callback function that can be called by Operations
Navigator during this scanning process.

Visual Basic plug-ins


Construction of Operations Navigator plug-ins in Visual Basic involves the creation
of a set of Visual Basic classes that contain the plug-in’s implementation. The
classes then are compiled into to an ActiveX server DLL. An example showing
how to do this is provided (see below). Visual Basic plug-ins must be written to
run on version 5.0 of the Visual Basic runtime.

Certain predefined information about the plug-in must be provided by the


developer in the form of a Windows registry file. This information is written to the
user’s registry when the plug-in is installed. The registry information allows the
Navigator to identify the new plug-in and call its implementation in response to
appropriate user actions. See “The Windows registry for Operations Navigator
plug-ins” on page 982 and “Registry files for Operations Navigator plug-ins” on
page 983 for more information.
Visual Basic plug-ins overview topics:
v “Product architecture for Operations Navigator Visual Basic plug-ins”
v “Operations Navigator structure and flow of control for Visual Basic
plug-ins”
Developing Visual Basic plug-ins topics:
v “Developing Operations Navigator Visual Basic plug-ins” on page 1125
v “Installing Visual Basic plug-ins” on page 1135
v “Identifying Visual Basic plug-ins to Operations Navigator” on page 1135

Product architecture for Operations Navigator Visual Basic


plug-ins
The internal architecture of the Operations Navigator product reflects that it is
intended to serve as an integration point for an extensible, broad-based operations
interface for the AS/400. Each functional component of the interface is packaged as
an ActiveX server. The Navigator learns about the existence of a particular server
component by means of entries in the Windows registry. Multiple servers may
register their request to add menu items and dialogs to a given object type in the
Navigator hierarchy. For information about the Microsoft Component Object Model

(COM) and ActiveX servers, see the Microsoft Web site .

Operations Navigator structure and flow of control for Visual


Basic plug-ins
Operations Navigator quickly is becoming the AS/400’s primary user interface.
From a programming standpoint, there must not be any architectural limits built
into Navigator that would prevent developers from continually being able to add
new function. For this reason, Operations Navigator components are packaged as
ActiveX server DLLs. The Navigator uses Microsoft’s Component Object Model
(COM) technology to activate only the component implementations that currently
are needed to service a user request. This avoids the problem of having to load the
entire product at startup, thereby consuming the majority of Windows resources,
and impacting performance of the entire system.

1122 Client Access Express Programming


For Visual Basic plug-ins, Operations Navigator provides a built-in ActiveX server
that manages the communication between Navigator and the plug-in’s
implementation. Visual Basic programmers who are developing Operations
Navigator plug-ins then use the facilities that are provided by Microsoft’s Visual
Basic 5.0 to create their plug-in classes, and to package them in an ActiveX server
DLL.

Plug-ins work by responding to method calls from Operations Navigator that are
generated in response to user actions. For example, when a user right-clicks on an
object in the Navigator hierarchy, Navigator constructs a context menu for the
object and displays the menu on the screen. Navigator obtains the menu items by
calling each plug-in that has registered its intent to supply context menu items for
the selected object type.

The functions that are implemented by a plug-in are logically grouped into
interfaces. An interface is a set of logically related methods on a class that
Operations Navigator can call to perform a specific function. For Visual Basic
plug-ins, three interfaces are defined:
v ListManager
v ActionsManager
v DropTargetManager

See the following topics for more information:


v “Operations Navigator Visual Basic interfaces”
v “The Windows registry for Operations Navigator plug-ins” on page 982
v “Operations Navigator data for Visual Basic plug-ins” on page 1124
v “Operations Navigator services from a Visual Basic plug-in” on page 1124

Operations Navigator Visual Basic interfaces


A Visual Basic plug-in must implement one or more Operations Navigator
interface classes, depending on the type of function that the developer intends to
provide to the Operations Navigator.

The Client Access Express Toolkit contains a link to the Visual Basic interface
definition help file. See “Accessing the Visual Basic interface definition help file”
for instructions.

There are three Operations Navigator interface classes:


v “Operations Navigator ListManager interface class” on page 1124
v “Operations Navigator ActionsManager interface class” on page 1124
v “Operations Navigator DropTargetManager interface class” on page 1124
Your application does not have to implement all three interface classes.

Accessing the Visual Basic interface definition help file: The Client Access
Express Toolkit contains a link to the Visual Basic interface definition help file. To
access this file, do the following:
1. Make sure that the Client Access Express Toolkit is installed on your PC. If it is
not, see “Installing the Express Toolkit” on page 10 for instructions.
2. Launch the Express Toolkit. See “Launching the Express Toolkit” on page 10 for
instructions.
3. Select the AS/400 Operations topic.
4. Select the Operations Navigator Plug-ins topic.
5. Select Visual Basic.
6. Under the Interface definition topic, select cwbunvbi.hlp to open the interface
description help file.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1123


Operations Navigator ListManager interface class: The ListManager interface
class is used for data serving in Operations Navigator. For example, when a list
view needs to be created and filled with objects, Operations Navigator will call
methods in the ListManager class to do this. The Visual Basic Sample plug-in
provides an example of this class in the file listman.cls. You must have a
ListManager class if your plug-in needs to populate Operations Navigator
component lists.

For detailed descriptions of this class and its methods, see the online help
provided with the Operations Navigator Visual Basic Plug-in Support DLL
(cwbunvbi.dll and cwbunvbi.hlp).

Operations Navigator ActionsManager interface class: The ActionsManager


interface class is used to build context menus, and to implement commands of the
context menu actions. For example, when a user performs a right mouse-click on a
Visual Basic list object in Operation Navigator, the queryActions method in the
ActionsManager interface class will be called to return the context menu item
strings. The Visual Basic Sample plug-in provides an example of this class in the
file actnman.cls. You must define an ActionsManager interface class for each
unique object type that your plug-in supports. You can specify the same
ActionsManager interface class for different object types, but your code logic must
handle being called with multiple types of objects.

For detailed descriptions of this class and its methods, see the online help
provided with the Operations Navigator Visual Basic Plug-in Support DLL
(cwbunvbi.dll and cwbunvbi.hlp files).

Operations Navigator DropTargetManager interface class: The


DropTargetManager interface class is used to handle drag-and-drop operations in
Operations Navigator. When a user selects a Visual Basic list object, and performs
mouse drag-and-drop operations on it, methods in this class will be called to
perform the drag-and-drop operations.

For detailed descriptions of this class and its methods, see the online help
provided with the Operations Navigator Visual Basic Plug-in Support DLL
(cwbunvbi.dll and cwbunvbi.hlp).

Operations Navigator data for Visual Basic plug-ins


When the Navigator calls a function implemented by a plug-in, the request
typically involves an object or objects the user selected in the main Navigator
window. The plug-in must be able to determine which objects have been selected.

The plug-in receives this information as a list of fully-qualified object names. For
Visual Basic plug-ins, an ObjectName class is defined that provides information
about the selected objects.

Plug-ins that add folders to the object hierarchy must return items in the folder to
Operations Navigator in the form of ″item identifiers.″ For Visual Basic plug-ins,
an ItemIdentifier class is defined that is used by the plug-in to return the requested
information.

See “Operations Navigator Visual Basic interfaces” on page 1123 for more
information.

Operations Navigator services from a Visual Basic plug-in


An Operations Navigator plug-in sometimes will need to affect the behavior of the
main Navigator window. For example, following completion of a user operation, it

1124 Client Access Express Programming


may be necessary to refresh the Navigator list view or to insert text into the
Navigator’s status area. A utility class called UIServices is supplied in the Visual
Basic environment that provides the required services.

Detail: A Visual Basic plug-in also can use the C++ APIs in the cwbun.h header
file to achieve similar results.

For detailed descriptions of this class and its methods, see the online help that is
provided with the Operations Navigator Visual Basic Plug-in Support DLL
(cwbunvbi.dll and cwbunvbi.hlp).

Developing Operations Navigator Visual Basic plug-ins


One of the best ways to learn about Operations Navigator plug-ins is to build one.
This section provides step-by-step instructions for creating a new Operations
Navigator Visual Basic plug-in. The instructions use the sample Visual Basic
plug-ins that are available in Client Access Express Toolkit - Operations Navigator

Plug-ins .
Details:
1. Visual Basic plug-ins must be created using Microsoft Visual Basic 5.0.
2. All Visual Basic plug-ins require a small Windows resource DLL that contains
certain information about your plug-in. This allows Operations Navigator to
represent your function in the Navigator object hierarchy without having to
load your plug-in’s implementation. The sample’s resource DLL was created by
using Microsoft’s Visual C++ version 4.2, but any C compiler that supports
compiling and linking Windows resources may be used.
3. For third-party Visual Basic plug-ins to be available to Operations Navigator
users, they must have Version 4 Release 4 Modification Level 0 or later of
Client Access Express for Windows installed on their personal computers.
4. The Client Access Express Toolkit contains the binaries and help files that are
needed to build a Visual Basic plug-in. The Toolkit component is not included
in a typical install. See “Installing the Express Toolkit” on page 10 and
“Launching the Express Toolkit” on page 10 for more information.
How to develop a Visual Basic plug-in:
To develop an Operations Navigator Visual Basic plug-in, complete the
following tasks:
1. Build, register and run the Visual Basic sample plug-in
2. Customize your new Visual Basic plug-in.
3. Diagnose any Visual Basic plug-ins errors.
4. Prepare the Visual Basic plug-in for final delivery and installation.

Building, registering, and running the Visual Basic sample


plug-in
This task involves building and running the sample ActiveX server DLL. The
sample provides a functioning Visual Basic project that you can use to observe the
behavior of a typical Operations Navigator plug-in. It also allows you to verify
that your Visual Basic environment is set up correctly for compiling and linking
plug-in code.

Follow these steps:


1. Prepare to build an ActiveX server DLL
2. Build the ActiveX server DLL
3. Build the resource library
4. Register the ActiveX server DLL

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1125


5. Observe your sample Visual Basic plug-in

Preparing to build an ActiveX server DLL for Visual Basic plug-ins:


1. Create a new directory that is named ″VBSample″ on your local hard drive.
This example assumes that the local drive is the C: drive.

Detail: If the new directory is not C:\VBSample, you will need to change the
registry file. See for “Registering the ActiveX server DLL for Visual
Basic plug-ins” on page 1127 more information.
2. Download the Visual Basic sample from the Client Access Express Toolkit -

Operations Navigator Plug-ins Web page. , and copy all of the sample files
into this directory.
3. In Visual Basic, open the File menu and select Open Project.
4. In the Open Project dialog, switch to the VBSample directory.
5. Select vbsample.vbp and click Open.
6. Open the Project menu and select References.
7. In the References dialog, select IBM AS/400 Client Access Express ActiveX
Object Library. Also select Operations Navigator Visual Basic Plug-in
Support.

Detail: The IBM AS/400 Client Access Express ActiveX Object Library contains
ActiveX automation objects that the sample application requires to
make remote command calls to the AS/400. The Operations Navigator
Visual Basic Plug-in Support contains classes and interfaces required to
create a Visual Basic Plug-in.

If either of these references do not appear in your References dialog,


select Browse and look for cwbx.dll and cwbunvbi.dll in the Client
Access Express shared directory.
Next, build the ActiveX server DLL.

Building the ActiveX server DLL for Visual Basic plug-ins: To build the ActiveX
server DLL, complete the following steps.
1. In Visual Basic, open the File menu and select Make....

Detail: If the DLL does not compile and link cleanly, locate and fix the errors.
Then open the File menu and select Make... to restart the build.
Next, build the resource library.

Building the resource library for Visual Basic plug-ins: The resource DLL that
contains the translatable text strings and other locale-dependent resources for the
plug-in is included with the sample. This means that you do not have to create this
DLL on your own. Even if your plug-in supports only one language, your plug-in
code must load its text strings and locale-specific resources from this resource
library.

To build the resource DLL, complete the following steps:


1. This example assumes that the sample component is in C:\VBSample.

Detail: If the sample directory is not C:\VBSample, you will need to change
the registry file. See “Registering the ActiveX server DLL for Visual
Basic plug-ins” on page 1127 for more information.
2. In Microsoft Developer Studio, open the File menu, select Open Workspace...
and select the VBSample\win32 directory.

1126 Client Access Express Programming


3. In Files of Type:, specify Makefiles (*.mak).
4. Select vbsmpmri.mak and click Open.
5. Open the Build menu and select Rebuild All to compile and link the DLL.

Detail: You can change the icons for the Visual Basic Sample plug-in in
Operations Navigator by using this project. There are two icons that
can be changed:
IDI_LIBRARY
Visual Basic Sample plug-in library icon.
IDI_SAMPLEFOLDER
Visual Basic Sample plug-in folder in open and closed state.

If you want to change the title of the plug-in in the Operations


Navigator tree list, change the caption of the string table entry as
follows:
ID: IDS_SAMPLE_FOLDER_NAME
Caption:
Visual Basic Sample Folder

Do not change the supplied toolbar, since Visual Basic Operations


Navigator plug-ins can use only the system-supplied default
Operations Navigator toolbar with no customization.
Next, register the ActiveX server DLL.

Registering the ActiveX server DLL for Visual Basic plug-ins: The
VBSMPDBG.REG file in the VBSample directory contains registry keys that
communicate the location of the sample plug-in on your PC to the Operations
Navigator. If you specified a directory other than c:\VBSample in “Preparing to
build an ActiveX server DLL for Visual Basic plug-ins” on page 1126, complete the
following steps.
1. Open the VBSMPDBG.REG file in a text editor.
2. Replace all occurrences of ″c:\\VBSample\\″ with ″x:\\<dir>\\,″ where x is
the drive where your directory resides and <dir> is the name of the directory.
3. Save the files.
4. In Windows Explorer, double-click the VBSMPDBG.REG file. This will write the
entries in the registry file to the Windows registry on your machine.

Detail: In Windows NT, you must login with administrative privileges on your
PC to write to the Windows registry.
Finally, Observe your sample Visual Basic plug-in.

Observing the sample Visual Basic plug-in: To run Operations Navigator and
observe the sample plug-in in action, complete the following steps:
1. Make sure that Operations Navigator is installed on your PC. If it is not, install
Operations Navigator by selecting Start --> Programs --> IBM AS400 Client
Access --> Selective Setup. Follow the prompts until the Component selection
dialog is displayed, and select Operations Navigator. Follow the prompts
through completion.
2. In Windows, select Start --> Programs --> IBM AS400 Client Access Express
--> AS400 Operations Navigator (or if you have the Operations Navigator icon
on your desktop, simply double-click on it).
3. Because you have just registered a new Navigator plug-in, an AS/400
Operations Navigator Scan dialog is displayed. Click on Scan Now.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1127


4. After the progress indicator finishes, click OK in the resulting dialog.
5. After the Navigator window refreshes, a new folder (Visual Basic Sample
Folder) appears in the hierarchy under the AS/400 that was initially selected.
For more information about this folder, see “Plug-ins samples in the Express
Toolkit” on page 980.

Customizing Visual Basic plug-ins


By customizing your new Visual Basic plug-in, you incorporate the unique
function that you intend to make available to Operations Navigator users. This
involves creating Windows registry files for the plug-in, and making changes to the
source code.

To customize your new Visual Basic plug-in, complete the following tasks:
1. Create a new registry file with a new ProgID for your Visual Basic plug-in
2. Register the Visual Basic plug-in implementation
3. Register the Visual Basic data server implementation
4. Register new Visual Basic folder information
5. Register Visual Basic plug-in objects
6. Construct Visual Basic property pages for a property sheet handler
7. Test the new Visual Basic plug-in

For more information that is specific to working with registry files in this context,
see “Registry files for Operations Navigator plug-ins” on page 983.

Creating a new registry file with a new ProgID for your Visual Basic plug-in:
The registry file contains important information about your plug-in, including the
programmatic identifier (ProgID). For more information about registry files, see
“Registry files for Operations Navigator plug-ins” on page 983. For more
information about ProgID, see “Programmatic identifier (ProgID)” on page 984.

To create a new registry file for your Visual Basic plug-in, complete the following
steps.
1. Copy the VBSMPRLS.REG, one of the sample registry files that is included with
the sample.

Detail: You need to copy and edit both of the registry files that are included in
the sample: VBSMPDBG.REG and VBSMPRLS.REG. Use
VBSMPDBG.REG as you develop your plug-in. Use VBSMPRLS.REG
for the retail version of your plug-in.
2. Rename the VBSMPRLS.REG file. Use the naming convention that you have
defined for your new plug-in.
3. Begin editing the registry file with your preferred utility. Change all instances
of ″IBM.VBSample″ with your new ←vendor→.←component→ string (ProgID).
What to do next:
Register the Visual Basic plug-in implementation.

Example: Registering the Visual Basic plug-in implementation: The primary


registry key defines a set of fields which specify global information for the plug-in.
This information is required. Note that the subkey name must match the ProgID
for your extension.
;--------------------------------------------------------------------
; Define the primary registry key for plug-in
; NOTE: NLS and ServerEntryPoint DLL names must not contain qualified directory paths
; This section will register a Visual Basic plug-in implementation path for each new folder
; added to the Operations Navigator hierarchy. This section is needed for every Visual Basic
; Plug-in.

1128 Client Access Express Programming


[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.VBSample]
"Type"="Plugin"
"NLS"="vbsmpmri.dll"
"NameID"=dword:00000080
"DescriptionID"=dword:00000081
"MinimumIMPIRelease"="NONE"
"MinimumRISCRelease"="040200"
"ProductID"="NONE"
"ServerEntryPoint"="vbsample.dll"
1. Change the name ″vbsample.dll″ in the ServerEntryPoint key to match the
name of the plug-in ActiveX server DLL.
2. Change the name ″vbsmpmri.dll″ in the NLS key to match the name of the C++
MRI resource DLL for your plug-in. Each Visual Basic plug-in must have a
unique C++ MRI DLL name.
What to do next:
Register the Visual Basic data server implementation.

Example: Registering the Visual Basic data server implementation: If your


plug-in does not add any new folders to the Operations Navigator hierarchy,
delete this section and proceed to the next task. The Visual Basic ListManager class
is the main interface to serve data to your plug-in folder.
; --------------------------------------------------------------------
; This section will register a Visual Basic Plug-in ListManager class implementation for
; each new folder added to the Operations Navigator hierarchy. This section is not needed if
; your plug-in does not add any folders.

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.VBSample\folders\SampleVBFolder]


"Parent"="AS4"
"Attributes"=hex:00,01,00,20
"CLSID"="{040606B1-1C19-11d2-AA12-08005AD17735}"
"VBClass"="vbsample.SampleListManager"
"VBInterface"="{0FC5EC72-8E00-11D2-AA9A-08005AD17735}"
"NameID"=dword:00000082
"DescriptionID"=dword:00000083
"DefaultIconIndex"=dword:00000001
"OpenIconIndex"=dword:00000001

1. Change all occurrences of the name SampleVBFolder in the registry file to a


unique name that will identify your folder object. The name that is specified in
the registry file must match the object name that is specified in your
ListManager and ActionsManager Visual Basic classes. For the sample plug-in
these Visual Basic source files are: listman.cls and actnman.cls.
2. Change the name ″vbsample.SampleListManager″ in the VBClass key to match
the program identifier name of your ListManager class. For example, if your
ActiveX Server DLL is named foo.dll, and your ListManager implementation
class is MyListManager, then the program identifier is ″foo.MyListManager″.
This name is case-sensitive.
3. Change the value of the ″VBInterface″ key to the ListManager implementation
class interface ID.
4. The sample places the Sample Visual Basic Folder into the root level of an
AS/400 system name in the Operations Navigator hierarchy. If you want your
folder to appear at some other point in the hierarchy, you must change the
″Parent″ key value. See “New folder registry key” on page 986 for a list of
possible values.
What to do next:
Register new Visual Basic folder information.

Registering new Visual Basic folder information: This section of the registry is
necessary when your plug-in adds a new folder to the Operations Navigator
hierarchy. If your plug-in does not add a new folder to the Operations Navigator
hierarchy, delete the section entirely, and register Visual Basic plug-in objects.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1129


Edit this section of the registry by using the information in New folder registry
key.
What to do next:
Register Visual Basic plug-in objects.

Example: Registering Visual Basic plug-in objects: The final section of the
registry specifies which objects in the Navigator hierarchy are affected by
implementation of the Visual Basic plug-in. To edit this section of the registry,
complete the following steps. The CLSID key for all Visual Basic plug-ins must use
the value: 040606B2-1C19-11d2-AA12-08005AD17735

Note: Property sheet handlers including the Auto Refresh property sheet handler
are not supported for Visual Basic plug-ins.
You will see code similar to that in the following example:
;--------------------------------------------------------------------
; Register a context menu handler for the new folder and its objects
[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.VBSample\shellex\SampleVBFolder\*\
ContextMenuHandlers\{040606B2-1C19-11d2-AA12-08005AD17735}]
"VBClass"="vbsample.SampleActionsManager"
"VBInterface"="{0FC5EC7A-8E00-11D2-AA9A-08005AD17735}"
;------------------------------------------------------------------------------
; Register drag and drop context menu handlers
[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.VBSample\shellex\SampleVBFolder\*\
DragDropHandlers\{040606B2-1C19-11d2-AA12-08005AD17735}]
"VBClass"="vbsample.SampleActionsManager"
"VBInterface"="{0FC5EC7A-8E00-11D2-AA9A-08005AD17735}"
;------------------------------------------------------------------------------
; Register Drop Handler to accept drops of objects

[HKEY_CLASSES_ROOT\IBM.AS400.Network\3RD PARTY EXTENSIONS\IBM.VBSample\shellex\SampleVBFolder\*\


DropHandler]
@="{040606B2-1C19-11d2-AA12-08005AD17735}"
"VBClass"="vbsample.SampleDropTargetManager"
"VBInterface"="{0FC5EC6E-8E00-11D2-AA9A-08005AD17735}"
1. The CLSID in the entries above should always have the following:
″{040606B2-1C19-11d2-AA12-08005AD17735}″
2. The ″VBClass″ key contains the program identifier (ProgID) of the Visual Basic
implementation class.
3. The ″VBInterface″ key contains the Visual Basic implementation class’ interface
ID.
4. If your plug-in will not be a drop handler for objects, remove the drag and
drop context menu handler and drop handler registry entries.
5. Rename the subkeys \SampleVBFolder\*\ and use a unique string to identify
your folder object. This name is the object type that will be used in your Visual
Basic source to identify when actions are taken on this folder in Operations
Navigator.
6. In the file that you created that was based on the ActionsManager interface,
edit the code that checks for the object types that are defined by the sample to
reflect the name of your new folder object. The sample’s ActionsManager
interface is located in actnman.cls The following example, located in
actnman.cls, checks for an object type defined by the sample:
If selectedFolderType = "SampleVBFolder" Then
(perform some action)
End If

Details:
v On many of the ActionsManager, ListManager and DropTargetManager
class methods, you will be passed in items or objects. To determine
which folder object is being referenced, use the object type string that is
defined in the Windows registry.
v Property sheets still can be added to your plug-in by using a context
menu item. You cannot use a registry key for a property sheet that is
the mechanism that is used for a C++ plug-in.

1130 Client Access Express Programming


Next, .
What to do next:
Construct Visual Basic property pages for a property sheet handler.

Example: Constructing Visual Basic property pages for a property sheet


handler: Property pages that are implemented by Operations Navigator Visual
Basic plug-ins can not use a registry key to specify property pages. You must add a
specific property page context menu item in your ListManager class to implement
a property page. You can not add a property page to any existing property sheet
objects.

In the Visual Basic Sample plug-in, a property page is supported for Libraries in
the Operations Navigator List. This is done with the following steps:
1. In listman.cls, the Library object type specifies a properties page in the
getAttributes method:
' Returns the attributes of an object in the list.
Public Function ListManager_getAttributes(ByVal item As Object) As Long
Dim uItem As ItemIdentifier
Dim nAttributes As ObjectTypeConstants

If Not IsEmpty(item) Then


Set uItem = item
End If

If uItem.getType = "SampleVBFolder" Then


nAttributes = OBJECT_ISCONTAINER
ElseIf item.getType = "SampleLibrary" Then
nAttributes = OBJECT_IMPLEMENTSPROPERTIES
Else
nAttributes = 0
End If

ListManager_getAttributes = nAttributes
End Function
2. In actnman.cls, the queryActions method specifies that properties should be
shown on the Library object context menu.
Public Function ActionsManager_queryActions(ByVal flags As Long) As Variant
.
.

' Add menu items to a Sample Library


If selectedFolderType = "SampleLibrary" Then
' Standard Actions
If (flags And STANDARD_ACTIONS) = STANDARD_ACTIONS Then
ReDim actions(0)

' Properties
Set actions(0) = New ActionDescriptor
With actions(0)
.Create
.setID IDPROPERTIES
.SetText m_uLoader.getString(IDS_ACTIONTEXT_PROPERTIES)
.setHelpText m_uLoader.getString(IDS_ACTIONHELP_PROPERTIES)
.setVerb "PROPERTIES"
.setEnabled True
.setDefault True
End With

' Properties is only selectable if there is ONLY 1 object selected


If Not IsEmpty(m_ObjectNames) Then
If UBound(m_ObjectNames) > 0 Then
actions(2).setEnabled False
End If

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1131


End If
End If
End If
.
.
End Function
3. In actnman.cls, the actionsSelected method displays a properties form when the
properties context menu is selected.
Public Sub ActionsManager_actionSelected(ByVal action As Integer, ByVal owner As Long)
.
.
Select Case action
.
.
Case IDPROPERTIES
If (Not IsEmpty(m_ObjectNames)) Then
' Pass the System Name into a hidden field on the form for later use
frmProperties.lblSystemName = m_ObjectNames(0).getSystemName

' Pass the Display Name of the selected object into a hidden field on the form
frmProperties.lblLibName = m_ObjectNames(0).getDisplayName

' Show the properties


frmProperties.Show vbModal
End If
.
.
Case Else
'Do Nothing
End Select

.
End Sub

Note: The code to create and display the property sheet can be seen in
propsht.frm
What to do next:
Test the new Visual Basic plug-in.

Testing the new Visual Basic plug-in: After finishing the previous tasks, you
have copied all of your Visual Basic source parts to a development directory, and
created a project workspaces for your new C++ resource DLL. You have also
created a registry file that you can use to try out the new Visual Basic plug-in.

Build the C++ resource DLL by completing the following steps:

Note: The Visual Basic sample plug-in assumes the resource DLL source files will
be copied to the c:\vbsample\win32 directory.
1. In Microsoft Developer Studio, open the Build menu and select Rebuild All for
the resource MRI DLL (vbsmpmri.mak).

Note: If a project does not rebuild cleanly, press F4 to display errors, then
make appropriate changes to the code. You may have to remove
INCLUDE statements for header files that you are not using.
2. In Windows Explorer, double-click your new registry file (the development
version) to register your new plug-in (vbsmpdbg.reg).

Note: If you choose to use a different build directory than C:\VBSAMPLE, you
must change the path in the registry file before you apply the registry in
Windows Explorer.

1132 Client Access Express Programming


You also will need to change the class file names, and MRI DLL resource
name if you changed them from the sample source.
3. Run Operations Navigator.
4. If you do not see evidence of your new plug-in, check the Client Access
History Log for error messages. The online help for the messages will explain
how to correct any problems.

Detail: You should see the folders, context menu items, and property pages from
the sample, depending on how much function from the sample you
decided to retain.
What to do next:
Diagnose Visual Basic plug-ins errors.

Diagnosing Visual Basic plug-ins errors


For some plug-ins errors, including:
v Incorrect registry-entry specifications
v Windows unable to load server DLL
the only visible symptom in the main Operations Navigator dialog is the absence
of the plug-in function. To help you determine the source of errors, Operations
Navigator writes error messages to the Client Access History Log.
To access the History Log:
Select IBM AS400 Client Access Express, --> Service --> History Log.

Note: By default, the History Log is not active. To ensure that error messages are
written to this file, History logging must be started. See the Express User’s
Guide, which is shipped with Client Access Express, for information on
starting the History Log.

The entries in the History Log consist of messages with and without message IDs.
Messages with message IDs have online help available. Messages without message
IDs do not have online help available.
Displaying recovery information for error messages with IDs:
To display the cause and recovery information associated with a message
that has a message ID, double-click on it. View any message that has a
message ID by selecting the Message topic in the online Express User’s
Guide.

Client Access Express also has associated messages that are logged on the AS/400
system. These messages begin with PWS or IWS.
To display messages that are logged on the AS/400 system:
Type the appropriate command (displayed below) at the AS/400
command-line prompt, where xxxx is the number of the message:
DSPMSGD RANGE(IWSxxxx) MSGF(QIWS/QIWSMSG)

DSPMSGD RANGE(PWSxxxx) MSGF(QIWS/QIWSMSG)


For error-handling information that is specific to Express C/C++ APIs:
See “Express return codes and error messages” on page 15
What to do next:
Prepare your Visual Basic plug-in for final delivery and installation.

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1133


Preparing your Visual Basic plug-in for final delivery and
installation
When you are satisfied with the function that you have developed to extend the
AS/400 Operations Navigator, it is time to prepare the Visual Basic (VB) plug-in
for final delivery to customers as part of an OS/400 licensed program.
To prepare your VB plug-in for final delivery and installation:
1. Modify your project for binary compatibility.
2. Modify the Release registry file.

For your Visual Basic plug-in files to be available for installation on client PCs,
they must reside in the following AS/400 directory:
/QIBM/USERDATA/OpNavPlugin
Use this directory for Visual Basic plug-ins. Use Client Access Express to
Install plug-ins in this directory. Client Access is unable to install them.

Each OS/400 licensed program that has an associated Operations Navigator


plug-in should create its own subdirectory at this location as part of its normal
install processing. The name of this subdirectory must match the
<vendor>.<component> string that is defined for the plug-in in the registry file.

For Operations Navigator Visual Basic plug-ins, the subdirectory should contain:
v The registry file for the plug-in.
v The Express setup file for the plug-in.
v The ActiveX server DLL for the plug-in, and any associated code DLLs.

If the Visual Basic plug-in supports Windows policies, include the .adm policy
template file for the plug-in in the MRI29xx directory.

The plug-in must create at least one directory below the


<VENDOR>.<COMPONENT> subdirectory that is named MRI29XX, where XX
identifies a supported language. For more information about MRI codes, see the
following IBM publication: AS/400 International Application Development: SC41–5603.
This directory contains the correct national language version of the following
items:
v The resource DLL for the plug-in
v The help files for the plug-in
v The “MRI setup file” on page 996 for the plug-in.
Related topic:
“Application Administration support for your plug-in” on page 996

Modifying your project for binary compatibility: When you are satisfied with
the function that you have developed to extend the AS/400 Operations Navigator,
it is time to ensure that you have new globally unique identifiers (GUIDs) for your
Visual Basic classes, and to set the binary compatibility in your Visual Basic
project. Follow these steps create new GUIDs for your classes, and to set binary
compatibility:
1. Open the Project menu and select Properties.
2. Select the Component tab.
3. Select the No Compatibility radio button.
4. Select OK to close the Properties dialog.
5. Open the File menu and select Make to build the project and create new
GUIDs for your classes.
6. Open the Project menu and select Properties.
7. Select the Component tab.
8. Select the Binary Compatibility radio button.

1134 Client Access Express Programming


9. Modify the text box for Binary Compatibility to the name of the project DLL.

Detail: The process documented above creates new GUIDs for your project’s
classes, and then ensures that subsequent builds retain your newly created
GUIDs.

Modifying the Release registry file: Visual Basic creates globally unique
identifiers (GUIDs) for your project and classes at compile time, and writes them to
the registry automatically. Since customers will not be compiling your projects, you
must include in the release registry file the registry entries (with your newly
created GUIDs) for your project and classes. VBSMPRLS.REG contains an example
of a release registry file.

Installing Visual Basic plug-ins


You can deliver your Visual Basic plug-in code to Operations Navigator users by
including it with your OS/400 applications. The install program for the application
writes the plug-in’s code binaries, registry file, and translatable resources to the
/QIBM/UserData/OpNavPlugins folder in the AS/400 Integrated File System
(AS/400 IFS). Once this process is completed, users can obtain the plug-in from the
AS/400 IFS (with the help of an AS/400 NetServer mapped network drive) by
invoking the Client Access Selective Setup program. The setup program copies
your plug-in code to the user’s machine, downloads the appropriate translatable
resources based on the language settings on the user’s PC, and runs the registry
file to write your plug-in’s registry information to the Windows registry. All you
need is a setup file, which identifies the files to be installed. If you provide a
Windows policy template with your plug-in, you also can take advantage of
Windows system policies to control which network users can install your plug-in.
You also can use the AS/400-based Application Administrationsupport of
Operations Navigator to control which users and groups have access to your
plug-in.
Additional resources for Application Administration support information:
v “Application Administration support for your plug-in” on page 996
v Application Administration topic in the Information Center

After the users have installed your new plug-in, you may choose either to upgrade
it at a later date, or to ship code problem fixes. When the code is upgraded on the
AS/400, the Client Access Check Version program will detect that this process has
occurred, and automatically download the updates to the users’ PCs. Client Access
also provides uninstall support, which allows users to completely remove the
plug-in from their PCs.

Users can display the plug-ins that are installed on their PCs by selecting the
Plug-ins tab on the Operations Navigator Properties for a particular AS/400.

Identifying Visual Basic plug-ins to Operations Navigator


Visual Basic plug-ins identify themselves to Operations Navigator by supplying
information in the Windows registry (see “The Windows registry for Operations
Navigator plug-ins” on page 982 for more information). This information is
supplied when the plug-in software is installed on a user’s PC. The registry entries
specify the location of the plug-in code, and identify the classes that implement the
special plug-in interfaces. You can supply additional registry information that
instructs Operations Navigator whether to activate the plug-in’s function for a

Chapter 4. Developing AS/400 Operations Navigator plug-ins 1135


particular AS/400 system. For example, a plug-in may require a certain minimum
release of OS/400, or it may specify that a certain product must be installed on the
AS/400 in order for it to function.

When a user makes a selection on an AS/400 in the Operations Navigator tree


after installing a plug-in, the AS/400 is examined to determine whether it is
capable of supporting the new plug-in. The software prerequisites (specified in the
plug-in’s registry entries) are compared against the software that is installed on the
AS/400. If the plug-in’s requirements are satisfied, the new function is displayed in
the Navigator tree. If the requirements are not met, the plug-in’s function does not
appear in the Navigator tree hierarchy for that AS/400. However, the plug-in may
participate in the determination of whether to be included in the hierarchy, by
implementing a special callback function that can be called by Operations
Navigator during this scanning process.

1136 Client Access Express Programming


Chapter 5. Java programming
The Java programming language, which was defined by Sun, enables the
development of portable Web-based applications.
See the AS/400 Toolbox for Java
The AS/400 Toolbox for Java, which is shipped with Client Access Express,
provides Java classes for accessing AS/400 resources. AS/400 Toolbox for
Java uses the Express Host Servers as access points to the system.
However, you do not need Client Access Express to use AS/400 Toolbox
for Java. Use the Toolbox to write applications that run independent of
Client Access Express.

Note: AS/400 Toolbox for Java interface behaviors such as security and
tracing may differ from those of other Express interfaces.

© Copyright IBM Corp. 1999, 2000 1137


1138 Client Access Express Programming
Chapter 6. ActiveX programming
ActiveX automation is a programming technology that is defined by Microsoft.

Client Access Express provides the following methods for accessing AS/400
resources by using ActiveX automation:
Automation objects:
These objects provide support for:
v Accessing AS/400 data queues
v Calling AS/400 system application programming interfaces and user
programs
v Managing AS/400 connections and validating security
v Running CL commands on the AS/400
v Performing data-type and code-page conversions
v Interfacing with host emulation sessions
“Express OLE DB Provider” on page 136:
Call the Express OLE DB Provider, by using Microsoft’s ActiveX Data
Objects (ADO), to access the following AS/400 resources:
v The AS/400 database, through record-level access
v The AS/400 database, through SQL
v SQL stored procedures
v Data queues
v Programs
v CL commands
Custom controls:
ActiveX custom controls are provided for:
v AS/400 data queues
v AS/400 CL commands
v AS/400 system names for previously connected systems
v Operations Navigator
Express Toolkit:
For detailed information on ActiveX support for Client Access Express, see
the ActiveX topic in the Express Toolkit component of Client Access
Express. It includes complete documentation of ADO and ActiveX
automation objects, and links to ActiveX information resources.
How to access the ActiveX topic:
1. Ensure that the Express Toolkit is installed (see “Installing the
Express Toolkit” on page 10).
2. Launch the Express Toolkit (see “Launching the Express
Toolkit” on page 10).
3. Select the Overview topic.
4. Select Programming Technologies.
5. Select ActiveX.

© Copyright IBM Corp. 1999, 2000 1139


1140 Client Access Express Programming


Printed in U.S.A.

Vous aimerez peut-être aussi