- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
301 lines
11 KiB
C++
301 lines
11 KiB
C++
// BDE - (C) Copyright 1995 by Borland International
|
|
|
|
// drvcaps.c
|
|
#include "snipit.h"
|
|
|
|
static DBIResult DisplayOptionalParams(pCHAR szDriver);
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// DriverCaps();
|
|
//
|
|
// Description:
|
|
// This example shows how to determine the capabilities of
|
|
// available IDAPI drivers. This includes the table types
|
|
// supported and the fields which those table types support.
|
|
//=====================================================================
|
|
void
|
|
DriverCaps (void)
|
|
{
|
|
hDBIDb hDb; // Handle to the database
|
|
hDBICur hDrvCur; // Handle to the in-memory table
|
|
// containing the driver list
|
|
hDBICur hTblTypeCur; // Handle to the in-memory table
|
|
// containing the table-type list
|
|
hDBICur hFldTypeCur; // Handle to the in-memory table
|
|
// containing the field-type list
|
|
hDBICur hIdxTypeCur; // Handle to the in-memory table
|
|
// containing the index-type list
|
|
DBIResult rslt; // Return value from IDAPI functions
|
|
CURProps TblProps; // Table properties
|
|
pBYTE pRecBuf; // Record buffer
|
|
DBINAME szDriver; // String to contain the driver name
|
|
DBIMSG szTempBuf; // Temporary buffer for displaying
|
|
// information
|
|
BOOL bIsBlank; // Is the field blank?
|
|
DRVType drvType; // Driver type information
|
|
|
|
Screen("*** Driver Capabilities Example ***\r\n");
|
|
|
|
BREAK_IN_DEBUGGER();
|
|
|
|
Screen(" Initializing IDAPI...");
|
|
if (InitAndConnect(&hDb) != DBIERR_NONE)
|
|
{
|
|
Screen("\r\n*** End of Example ***");
|
|
return;
|
|
}
|
|
|
|
Screen(" Setting the database directory...");
|
|
rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
|
|
ChkRslt(rslt, "SetDirectory");
|
|
|
|
// Get a list of the drivers which are available to the system
|
|
// (drivers which are defined in the configuration file).
|
|
rslt = DbiOpenDriverList(&hDrvCur);
|
|
if (ChkRslt(rslt, "OpenDriverList") != DBIERR_NONE)
|
|
{
|
|
CloseDbAndExit(&hDb);
|
|
Screen("\r\n*** End of example ***");
|
|
return;
|
|
}
|
|
|
|
// Get the size of the record buffer.
|
|
rslt = DbiGetCursorProps(hDrvCur, &TblProps);
|
|
ChkRslt(rslt, "GetProps");
|
|
|
|
// Allocate space for the record buffer.
|
|
pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE));
|
|
if (pRecBuf == NULL)
|
|
{
|
|
Screen(" Error - Could not allocate memory");
|
|
rslt = DbiCloseCursor(&hDrvCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
CloseDbAndExit(&hDb);
|
|
Screen("\r\n*** End of example ***");
|
|
return;
|
|
}
|
|
|
|
Screen(" Go to the beginning of the table...");
|
|
rslt = DbiSetToBegin(hDrvCur);
|
|
ChkRslt(rslt, "SetToBegin");
|
|
|
|
// Iterate through all available drivers in the configuration file.
|
|
while (DbiGetNextRecord(hDrvCur, dbiNOLOCK, pRecBuf, NULL)
|
|
== DBIERR_NONE)
|
|
{
|
|
// Get the name of the driver.
|
|
rslt = DbiGetField(hDrvCur, 1, pRecBuf, (pBYTE) szDriver,
|
|
&bIsBlank);
|
|
ChkRslt(rslt, "GetField");
|
|
|
|
// Get the description of the driver.
|
|
rslt = DbiGetDriverDesc(szDriver, &drvType);
|
|
if (ChkRslt(rslt, "GetDriverDesc") != DBIERR_NONE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Limit driver information to local tables (the edit control
|
|
// can only hold so much....)
|
|
if (drvType.edrvCat == drvFILE)
|
|
{
|
|
// Skip a line.
|
|
Screen("");
|
|
|
|
// Display the information about the driver.
|
|
Screen(" Driver Name: %s",
|
|
drvType.szType);
|
|
Screen(" Description: %s",
|
|
drvType.szText);
|
|
|
|
// Create a string to display depending on the driver category.
|
|
switch(drvType.edrvCat)
|
|
{
|
|
case drvFILE:
|
|
strcpy(szTempBuf, "File-based (PDox, dBASE, Text)");
|
|
break;
|
|
case drvOTHERSERVER:
|
|
strcpy(szTempBuf, "Other type of server???");
|
|
break;
|
|
case drvSQLBASEDSERVER:
|
|
strcpy(szTempBuf, "SQL-based server");
|
|
break;
|
|
}
|
|
Screen(" Category: %s", szTempBuf);
|
|
Screen(" Supports true database concepts: %s",
|
|
drvType.bTrueDb ? "Yes" : "No");
|
|
Screen(" Database type to use: %s",
|
|
drvType.szDbType);
|
|
Screen(" Supports multi-user: %s",
|
|
drvType.bMultiUser ? "Yes" : "No");
|
|
Screen(" Read only?: %s",
|
|
drvType.bReadWrite ? "No" : "Yes");
|
|
Screen(" Transaction support: %s",
|
|
drvType.bTrans ? "Yes" : "No");
|
|
Screen(" Supports pass-through SQL: %s",
|
|
drvType.bPassThruSQL ? "Yes" : "No");
|
|
Screen(" Requires explicit login: %s",
|
|
drvType.bLogIn ? "Yes" : "No");
|
|
Screen(" Can create a database: %s",
|
|
drvType.bCreateDb ? "Yes" : "No");
|
|
Screen(" Can drop a database: %s",
|
|
drvType.bDeleteDb ? "Yes" : "No");
|
|
Screen(" Can create a table: %s",
|
|
drvType.bCreateTable ? "Yes" : "No");
|
|
Screen(" Can delete a table: %s",
|
|
drvType.bDeleteTable ? "Yes" : "No");
|
|
Screen(" Multiple passwords: %s",
|
|
drvType.bMultiplePWs ? "Yes" : "No");
|
|
|
|
// Determine table types that the driver can use.
|
|
rslt = DbiOpenTableTypesList(szDriver, &hTblTypeCur);
|
|
if (ChkRslt(rslt, "OpenTableTypesList") != DBIERR_NONE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Screen("\r\n Table types supported by the driver...");
|
|
DisplayInMemoryTable(hTblTypeCur, 0);
|
|
|
|
rslt = DbiCloseCursor(&hTblTypeCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
// Determine field types that the driver can use.
|
|
rslt = DbiOpenFieldTypesList(szDriver, NULL, &hFldTypeCur);
|
|
if (ChkRslt(rslt, "OpenFieldTypesList") != DBIERR_NONE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Screen("\r\n Field types supported by the driver...");
|
|
DisplayInMemoryTable(hFldTypeCur, 0);
|
|
|
|
rslt = DbiCloseCursor(&hFldTypeCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
// Determine index types that the driver can use.
|
|
rslt = DbiOpenIndexTypesList(szDriver, &hIdxTypeCur);
|
|
if (ChkRslt(rslt, "OpenTableTypesList") != DBIERR_NONE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Screen("\r\n Display the index types that the driver"
|
|
" supports...");
|
|
DisplayInMemoryTable(hIdxTypeCur, 0);
|
|
|
|
rslt = DbiCloseCursor(&hIdxTypeCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
Screen("\r\n Optional parameters....\r\n");
|
|
DisplayOptionalParams (drvType.szType);
|
|
}
|
|
}
|
|
|
|
free(pRecBuf);
|
|
|
|
rslt = DbiCloseCursor(&hDrvCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
Screen("\r\n Close the database and exit IDAPI...");
|
|
CloseDbAndExit(&hDb);
|
|
|
|
Screen("\r\n*** End of Example ***");
|
|
}
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// DisplayOptionalParams (pCHAR szDriver)
|
|
//
|
|
// Input: szDriver - Name of the driver
|
|
//
|
|
// Return: DBIResult - Result of the operation
|
|
//
|
|
// Description:
|
|
// This function is used to display the optional parameters
|
|
// for a given driver.
|
|
//=====================================================================
|
|
DBIResult
|
|
DisplayOptionalParams (pCHAR szDriver)
|
|
{
|
|
DBIResult rslt; // Return value from IDAPI functions
|
|
hDBICur hCur; // Handle to the cursor
|
|
pCHAR szNode; // String which contains the name of the
|
|
// node
|
|
pCFGDesc CfgDesc; // Configuration descriptor
|
|
DBIPATH szCfgPath; // Maximum length of the path in the
|
|
// configuration file
|
|
pCHAR szFieldNames; // String to contain the field names
|
|
pCHAR szFieldValues; // String to contain the field values
|
|
|
|
// Set up the option to get from the configuration file.
|
|
strcpy(szCfgPath, "\\");
|
|
strcat(szCfgPath, szCFGDRIVER);
|
|
strcat(szCfgPath, "\\");
|
|
strcat(szCfgPath, szDriver);
|
|
strcat(szCfgPath, "\\");
|
|
strcat(szCfgPath, szCFGTBLCREATE);
|
|
strcat(szCfgPath, "\\");
|
|
|
|
// Open the configuration file - returns the configuration options
|
|
// for the current level in a schema table referenced by hCur.
|
|
rslt = DbiOpenCfgInfoList(NULL, dbiREADONLY, cfgPersistent,
|
|
szCfgPath, &hCur);
|
|
if (ChkRslt(rslt, "OpenCfgInfoList") != DBIERR_NONE)
|
|
{
|
|
return rslt;
|
|
}
|
|
|
|
// Allocate resources.
|
|
szNode = (pCHAR) malloc(DBIMAXPATHLEN * sizeof(CHAR) + 1);
|
|
szFieldNames = (pCHAR) malloc(DBIMAXSCRECSIZE * sizeof(CHAR) + 1);
|
|
szFieldValues = (pCHAR) malloc(DBIMAXSCRECSIZE * sizeof(CHAR) + 1);
|
|
CfgDesc = (pCFGDesc) malloc(sizeof(CFGDesc));
|
|
if ((szNode == NULL) || (szFieldNames == NULL) || (szFieldValues == NULL)
|
|
|| (CfgDesc == NULL))
|
|
{
|
|
if (szNode) free(szNode);
|
|
if (szFieldNames) free(szFieldNames);
|
|
if (szFieldValues) free(szFieldValues);
|
|
if (CfgDesc) free((pCHAR)CfgDesc);
|
|
rslt = DbiCloseCursor(&hCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
return DBIERR_NOMEMORY;
|
|
}
|
|
|
|
// Set the spacing.
|
|
strcpy(szFieldNames, " ");
|
|
strcpy(szFieldValues, " ");
|
|
|
|
// Process all nodes.
|
|
// Get the next record in the table - contains the next option
|
|
// of the given level in the tree.
|
|
while (DbiGetNextRecord(hCur, dbiNOLOCK, (pBYTE)CfgDesc, NULL)
|
|
== DBIERR_NONE)
|
|
{
|
|
// Output this node, copying the name of the node to the
|
|
// szNode variable.
|
|
sprintf(szNode, "%-16s\t", CfgDesc->szNodeName);
|
|
strcat(szFieldNames, szNode);
|
|
|
|
sprintf(szNode, " %-16s\t", CfgDesc->szValue);
|
|
strcat(szFieldValues, szNode);
|
|
}
|
|
|
|
// Display the field names and values.
|
|
Screen(szFieldNames);
|
|
Screen(szFieldValues);
|
|
|
|
// Clean up.
|
|
free(szNode);
|
|
free(szFieldNames);
|
|
free(szFieldValues);
|
|
free((pCHAR) CfgDesc);
|
|
rslt = DbiCloseCursor(&hCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
return rslt;
|
|
}
|
|
|