- 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>
1188 lines
40 KiB
C++
1188 lines
40 KiB
C++
// BDE - (C) Copyright 1995 by Borland International
|
|
|
|
#include "structer.h"
|
|
#include "macro.h"
|
|
|
|
#define szCURRENTMODULE "STRUCTER"
|
|
|
|
//=====================================================================
|
|
// This BDE example provides users a means of doing a limited Paradox and
|
|
// dBASE table restructure using Paradox for Windows ver. 5.0 ObjectPAL. The
|
|
// ObjectPAL procedures created are: AddField, DeleteField, ModifyField,
|
|
// and MoveField. You only need to use one procedure for an entire
|
|
// restructure.
|
|
//
|
|
// You can change field order, names, types, and sizes on local tables or on
|
|
// tables where the user has all rights to its directory. You can also add
|
|
// or delete fields and/or pack the table. Table properties are maintained
|
|
// (i.e. Validity Checks, Table Lookup, Secondary Indexes, etc.).
|
|
//
|
|
// Because you can already re-key a table with ObjectPAL, primary key
|
|
// operations are not done in this DLL. If adding, dropping, or copying
|
|
// (moving) a field in the the key you will need to remove the key with
|
|
// ObjectPAL (delete .PX), restructure with this DLL, and then reindex
|
|
// using ObjectPAL. You can modify a field in a primary key without
|
|
// removing the key.
|
|
//
|
|
// Also, because of the complexity of table encryption (passwords) this
|
|
// example only supports tables with no passwords.
|
|
//
|
|
//
|
|
// This is a Paradox Uses block:
|
|
//
|
|
// Uses structer
|
|
//
|
|
// DeleteField(tablePath cptr, tableName cptr, FieldName cptr,
|
|
// PackOrNoPack cptr, returnStringBuffer cptr)
|
|
//
|
|
// MoveField(tablePath cptr, tableName cptr,
|
|
// NewFieldPosition cword, CurrentFieldName cptr,
|
|
// PackOrNoPack cptr, returnStringBuffer cptr)
|
|
//
|
|
// AddField(tablePath cptr, tableName cptr, NewFieldPosition
|
|
// cword, FieldName cptr, FieldType cptr, FieldSize cword,
|
|
// PackOrNoPack cptr, returnStringBuffer cptr)
|
|
//
|
|
// ModifyField(tablePath cptr, tableName cptr,
|
|
// FieldName cptr, NewFieldName cptr, FieldType cptr,
|
|
// FieldSize cword, PackOrNoPack cptr,
|
|
// returnStringBuffer cptr)
|
|
//
|
|
// endUses
|
|
//
|
|
//
|
|
// Return value: (returnStringBuffer) "Restructure successful." or an error.
|
|
// Using the return value is optional.
|
|
//
|
|
//
|
|
// And some typical methods:
|
|
//
|
|
// Var ; on the form level
|
|
// returnStringBuffer String
|
|
// endVar
|
|
//
|
|
// method open(var eventInfo Event)
|
|
// ; requires a 129 byte buffer:
|
|
// returnStringBuffer = space(129)
|
|
// endmethod
|
|
//
|
|
// method mouseDown(var eventInfo MouseEvent)
|
|
// DeleteField(workingdir(), "test.dbf", "Company", "PACK",
|
|
// returnStringBuffer)
|
|
// message(returnStringBuffer)
|
|
// endmethod
|
|
//
|
|
// method mouseDown(var eventInfo MouseEvent)
|
|
// MoveField(workingdir(), "test", 2, "Phone", "NOPACK",
|
|
// returnStringBuffer)
|
|
// message(returnStringBuffer)
|
|
// endmethod
|
|
//
|
|
// method mouseDown(var eventInfo MouseEvent)
|
|
// AddField(workingdir(), "test", 2, "autoincre", "+", 0, "PACK",
|
|
// returnStringBuffer)
|
|
// message(returnStringBuffer)
|
|
// endmethod
|
|
//
|
|
// method mouseDown(var eventInfo MouseEvent)
|
|
// ModifyField(workingdir(), "test", "Company", "Company Name", "A",
|
|
// 50, "NOPACK", returnStringBuffer)
|
|
// message(returnStringBuffer)
|
|
// endmethod
|
|
//
|
|
//
|
|
// Arguments used with DeleteField:
|
|
//
|
|
// 1st and 2nd argument: the table Path and the table name (.db is optional,
|
|
// and .dbf is
|
|
// required)
|
|
// 3th argument: the current field name
|
|
// 4th argument: specify "PACK" or "NOPACK" (anything but "PACK" does not
|
|
// pack the table)
|
|
// 5th argument: return value
|
|
//
|
|
// Arguments used with MoveField:
|
|
//
|
|
// 1st and 2nd argument: the table Path and the table name
|
|
// 3rd argument: the new field position
|
|
// 4th argument: the current field name
|
|
// 5th argument: specify "PACK" or "NOPACK"
|
|
// 6th argument: return value
|
|
//
|
|
//
|
|
// Arguments used with AddField and ModifyField:
|
|
//
|
|
// 1st and 2nd argument: the table Path and the table name
|
|
// 3rd argument: the new field position
|
|
// 4th argument: the current field name
|
|
// 5th argument: the new field type:
|
|
//
|
|
// Paradox types: dBASE types:
|
|
// "A" = Alpha "C" = Character
|
|
// "N" = Number "F" = Float
|
|
// "$" = Money "N" = Number
|
|
// "S" = Short "D" = Date
|
|
// "I" = Long Integer "L" = Logical
|
|
// "#" = BCD "M" = Memo
|
|
// "D" = Date "O" = OLE
|
|
// "T" = Time "B" = Binary
|
|
// "@" = Timestamp
|
|
// "M" = Memo
|
|
// "F" = Formatted Memo
|
|
// "G" = Graphic
|
|
// "O" = OLE
|
|
// "L" = Logical
|
|
// "+" = Autoincrement
|
|
// "B" = Binary
|
|
// "Y" = Bytes
|
|
//
|
|
// 6th argument: Field size
|
|
// Needs a valid number. If a type requires no size, then use 0.
|
|
// 7th argument: specify "PACK" or "NOPACK"
|
|
// 8th argument: return value
|
|
//
|
|
//
|
|
// Other notes:
|
|
//
|
|
// Follow the standard rules for all field types (i.e. you can
|
|
// convert existing number, short, and long integer fields to
|
|
// autoincrement fields if the field is the table's single-field
|
|
// primary index (key). Use correct field sizes (0 for no size).)
|
|
//
|
|
// Changes get ignored outside of these rules and give various BDE
|
|
// errors such as "Invalid field type" or "Invalid field descriptor".
|
|
//
|
|
// Make sure that you have enough file handles (IDAPI maxfilehandles
|
|
// + 20). Only use full, absolute paths for tablePathOrAlias. Relative
|
|
// paths are not supported.
|
|
// Using too few or too many parameters the Paradox Uses block
|
|
// WILL CAUSE A GPF!! (in Pdoxwin).
|
|
//=====================================================================
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// AddField(pCHAR pTblDir, pCHAR pTblName, int iNewFldNum,
|
|
// pCHAR pNewName, pCHAR pFldType, UINT16 iUnits1,
|
|
// pCHAR pPack, pCHAR pszRetBuffer)
|
|
//
|
|
// Description:
|
|
// This example shows how to change the characteristics of a
|
|
// table, just adding one field.
|
|
//
|
|
//=====================================================================
|
|
void FAR WINAPI _export
|
|
AddField (pCHAR pTblDir, pCHAR pTblName, int iNewFldNum,
|
|
pCHAR pNewName, pCHAR pFldType, UINT16 iUnits1, pCHAR pPack,
|
|
pCHAR pszRetBuffer)
|
|
{
|
|
CHAR szFldType[1] = {"\0"}; // for user field type code
|
|
HGLOBAL hglbCorrectTableInfo; // handle to TableInfo struct
|
|
|
|
// store field type code
|
|
sprintf(szFldType, "%s", pFldType);
|
|
|
|
// initialize buffer for return string
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
// initialize handle to TableInfo struct
|
|
hglbCorrectTableInfo = NULL;
|
|
|
|
// allocate memory for TableInfo struct
|
|
hglbCorrectTableInfo = (struct TBLINFO*) GlobalAlloc (GMEM_MOVEABLE,
|
|
sizeof(struct TBLINFO));
|
|
if (hglbCorrectTableInfo == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// get return string from calling the first function
|
|
// set the new number of fields to + 1
|
|
BeginRestructure(hglbCorrectTableInfo, pTblDir, pTblName, 1, pszRetBuffer);
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
SetFieldDescriptions(hglbCorrectTableInfo, crADD, iNewFldNum,
|
|
pNewName, pNewName, szFldType, iUnits1,
|
|
pszRetBuffer);
|
|
}
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
EndRestructure(hglbCorrectTableInfo, pPack, pszRetBuffer);
|
|
}
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
cleanUpMemory(hglbCorrectTableInfo);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// DeleteField(pCHAR pTblDir, pCHAR pTblName, pCHAR pOldName,
|
|
// pCHAR pPack, pCHAR pszRetBuffer)
|
|
//
|
|
// Description:
|
|
// This example shows how to change the characteristics of a
|
|
// table, just deleting one field.
|
|
//
|
|
//=====================================================================
|
|
void FAR WINAPI _export
|
|
DeleteField (pCHAR pTblDir, pCHAR pTblName, pCHAR pOldName, pCHAR pPack,
|
|
pCHAR pszRetBuffer)
|
|
{
|
|
CHAR szFldType[1] = {"\0"};
|
|
HGLOBAL hglbCorrectTableInfo;
|
|
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
hglbCorrectTableInfo = NULL;
|
|
hglbCorrectTableInfo = (struct TBLINFO*) GlobalAlloc (GMEM_MOVEABLE,
|
|
sizeof(struct TBLINFO));
|
|
if (hglbCorrectTableInfo == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
BeginRestructure(hglbCorrectTableInfo, pTblDir, pTblName, -1, pszRetBuffer);
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
SetFieldDescriptions(hglbCorrectTableInfo, crDROP, 0, pOldName,
|
|
pOldName, szFldType, 0, pszRetBuffer);
|
|
}
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
EndRestructure(hglbCorrectTableInfo, pPack, pszRetBuffer);
|
|
}
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
cleanUpMemory(hglbCorrectTableInfo);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// ModifyField(pCHAR pTblDir, pCHAR pTblName, pCHAR pOldName,
|
|
// pCHAR pNewName, pCHAR pFldType, UINT16 iUnits1,
|
|
// pCHAR pPack, pCHAR pszRetBuffer)
|
|
//
|
|
// Description:
|
|
// This example shows how to change the characteristics of a
|
|
// table, just modifying one field.
|
|
//
|
|
//=====================================================================
|
|
void FAR WINAPI _export
|
|
ModifyField (pCHAR pTblDir, pCHAR pTblName, pCHAR pOldName,
|
|
pCHAR pNewName, pCHAR pFldType, UINT16 iUnits1, pCHAR pPack,
|
|
pCHAR pszRetBuffer)
|
|
{
|
|
CHAR szFldType[1] = {"\0"};
|
|
HGLOBAL hglbCorrectTableInfo;
|
|
|
|
sprintf(szFldType, "%s", pFldType);
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
hglbCorrectTableInfo = NULL;
|
|
hglbCorrectTableInfo = (struct TBLINFO*) GlobalAlloc (GMEM_MOVEABLE,
|
|
sizeof(struct TBLINFO));
|
|
if (hglbCorrectTableInfo == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
BeginRestructure(hglbCorrectTableInfo, pTblDir, pTblName, 0, pszRetBuffer);
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
SetFieldDescriptions(hglbCorrectTableInfo, crMODIFY, 0, pOldName,
|
|
pNewName, szFldType, iUnits1, pszRetBuffer);
|
|
}
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
EndRestructure(hglbCorrectTableInfo, pPack, pszRetBuffer);
|
|
}
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
cleanUpMemory(hglbCorrectTableInfo);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// MoveField(pCHAR pTblDir, pCHAR pTblName, int iNewFldNum,
|
|
// pCHAR pOldName, pCHAR pPack, pCHAR pszRetBuffer)
|
|
//
|
|
// Description:
|
|
// This example shows how to change the characteristics of a
|
|
// table, just moving one field.
|
|
//
|
|
//=====================================================================
|
|
void FAR WINAPI _export
|
|
MoveField (pCHAR pTblDir, pCHAR pTblName, int iNewFldNum,
|
|
pCHAR pOldName, pCHAR pPack, pCHAR pszRetBuffer)
|
|
{
|
|
CHAR szFldType[1] = {"\0"};
|
|
HGLOBAL hglbCorrectTableInfo;
|
|
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
hglbCorrectTableInfo = NULL;
|
|
hglbCorrectTableInfo = (struct TBLINFO*) GlobalAlloc (GMEM_MOVEABLE,
|
|
sizeof(struct TBLINFO));
|
|
if (hglbCorrectTableInfo == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
BeginRestructure(hglbCorrectTableInfo, pTblDir, pTblName, 0, pszRetBuffer);
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
SetFieldDescriptions(hglbCorrectTableInfo, crCOPY, iNewFldNum,
|
|
pOldName, "", szFldType, 0, pszRetBuffer);
|
|
}
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
EndRestructure(hglbCorrectTableInfo, pPack, pszRetBuffer);
|
|
}
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
cleanUpMemory(hglbCorrectTableInfo);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// BeginRestructure(HGLOBAL hglbCorrectTableInfo, pCHAR pTblDir,
|
|
// pCHAR pTblName, int wNUMOFFIELDS,
|
|
// pCHAR pszRetBuffer)
|
|
//
|
|
// Input:
|
|
// from AddField(), DeleteField(), ModifyField(), or MoveField()
|
|
// hglbCorrectTableInfo - handle to TableInfo struct
|
|
// pTblDir - table directory
|
|
// pTblName - table name
|
|
// wNUMOFFIELDS - -1 (delete), 0 (move/modify), 1 (add)
|
|
// pszRetBuffer - return to client
|
|
//
|
|
// Return: (pszRetBuffer) null or error string.
|
|
//
|
|
// Description:
|
|
// This function allocates memory based on the new number of
|
|
// fields passed from the client, for example, Paradox. And,
|
|
// it gets the field descriptor for an existing cursor. The
|
|
// engine is not initialized or closed because it is in use
|
|
// by the client - Paradox for Windows. The private directory
|
|
// has also been set by Paradox.
|
|
//=====================================================================
|
|
void FAR WINAPI
|
|
BeginRestructure (HGLOBAL hglbCorrectTableInfo, pCHAR pTblDir, pCHAR pTblName,
|
|
int wNUMOFFIELDS, pCHAR pszRetBuffer)
|
|
{
|
|
DBIResult rslt;
|
|
UINT16 i; // loop counter
|
|
CURProps curProps; // table properties
|
|
struct TBLINFO *TableInfo; // pointer to TableInfo struct
|
|
CHAR szTblType1[] = szPARADOX; // table type (PARADOX)
|
|
CHAR szTblType2[] = szDBASE; // table type (DBASE)
|
|
|
|
// initialize return string to NULL
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
// make sure we have handle to TableInfo struct
|
|
CHKERR_NODISPLAY(hglbCorrectTableInfo == NULL);
|
|
|
|
// point to TableInfo struct
|
|
TableInfo = GlobalLock (hglbCorrectTableInfo);
|
|
if (TableInfo == NULL)
|
|
{
|
|
hglbCorrectTableInfo = NULL;
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// initialize TableInfo struct
|
|
TableInfo->pIdxDesc = NULL;
|
|
TableInfo->pFldDesc = NULL;
|
|
TableInfo->pFldDescriptor = NULL;
|
|
TableInfo->ecrFldOp = NULL;
|
|
TableInfo->uNumFields = 0;
|
|
TableInfo->uNewNumFields = 0;
|
|
TableInfo->hDb = NULL;
|
|
TableInfo->hCur = NULL;
|
|
TableInfo->retVal = 1;
|
|
TableInfo->bHasIndex = 0;
|
|
|
|
// initialize new table descriptor
|
|
memset(&TableInfo->crTblDesc, 0, sizeof(CRTblDesc));
|
|
|
|
// set new table descriptor to table name
|
|
strcpy(TableInfo->crTblDesc.szTblName, pTblName);
|
|
|
|
// open a database in the current session and get a database handle
|
|
CHKERR_CLEANUP(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENEXCL,
|
|
NULL, 0, NULL, NULL, &TableInfo->hDb));
|
|
|
|
// set the current directory
|
|
CHKERR_CLEANUP(DbiSetDirectory(TableInfo->hDb, pTblDir));
|
|
|
|
// associate a cursor handle with an opened table
|
|
CHKERR_CLEANUP(DbiOpenTable(TableInfo->hDb, (pCHAR) pTblName, NULL,
|
|
NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL,
|
|
xltFIELD, FALSE, NULL, &TableInfo->hCur));
|
|
|
|
// set field translate mode no translation
|
|
CHKERR_CLEANUP(DbiSetProp(TableInfo->hCur, curXLTMODE, xltNONE));
|
|
|
|
// get the cursor properties for the existing table
|
|
CHKERR_CLEANUP(DbiGetCursorProps(TableInfo->hCur, &curProps));
|
|
|
|
// if table is password protected, cancel restructure
|
|
if (curProps.bProtected)
|
|
{
|
|
GetString(12, pszRetBuffer); //"Only tables without passwords are
|
|
// supported."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// if table is other than Paradox or dBASE, cancel restructure
|
|
if (strcmp(szTblType1, curProps.szTableType) && strcmp(szTblType2,
|
|
curProps.szTableType))
|
|
{
|
|
GetString(6, pszRetBuffer); //"Only Paradox and dBASE tables are
|
|
// supported."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// set new table descriptor to table type
|
|
strcpy(TableInfo->crTblDesc.szTblType, curProps.szTableType);
|
|
|
|
// if table has primary key, allocate memory for existing index descriptor
|
|
if (curProps.iIndexes)
|
|
{
|
|
TableInfo->bHasIndex = 1;
|
|
TableInfo->pIdxDesc =
|
|
(IDXDesc*) malloc (curProps.iIndexes * sizeof(IDXDesc));
|
|
if (TableInfo->pIdxDesc == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
|
|
// get existing number of fields
|
|
TableInfo->uNumFields = curProps.iFields;
|
|
|
|
// get new number of fields
|
|
TableInfo->uNewNumFields = curProps.iFields + wNUMOFFIELDS;
|
|
|
|
// allocate memory for existing field descriptor
|
|
TableInfo->pFldDesc =
|
|
(FLDDesc*) malloc (curProps.iFields * sizeof(FLDDesc));
|
|
if (TableInfo->pFldDesc == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// allocate memory for new field descriptor
|
|
TableInfo->pFldDescriptor =
|
|
(FLDDesc*) malloc (TableInfo->uNewNumFields * sizeof(FLDDesc));
|
|
if (TableInfo->pFldDescriptor == NULL)
|
|
{
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// allocate memory for field operations array
|
|
TableInfo->ecrFldOp =
|
|
(CROpType*) malloc (TableInfo->uNewNumFields * sizeof(CROpType));
|
|
if (TableInfo->ecrFldOp == NULL)
|
|
{
|
|
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// get existing field descriptors
|
|
CHKERR_CLEANUP(DbiGetFieldDescs(TableInfo->hCur, TableInfo->pFldDesc));
|
|
CHKERR_CLEANUP(DbiSetProp(TableInfo->hCur, curXLTMODE, xltFIELD));
|
|
|
|
// initialize new field numbers and field operations array
|
|
for (i = 0; i < TableInfo->uNewNumFields; i++)
|
|
{
|
|
TableInfo->pFldDescriptor[i].iFldNum = -1;
|
|
TableInfo->ecrFldOp[i] = NULL;
|
|
}
|
|
|
|
TableInfo->retVal = 0;
|
|
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
GlobalUnlock(hglbCorrectTableInfo);
|
|
hglbCorrectTableInfo = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// SetFieldDescriptions(HGLOBAL hglbCorrectTableInfo,
|
|
// CROpType FieldOp, UINT16 iNewFldNum,
|
|
// pCHAR pOldName, pCHAR pNewName,
|
|
// pCHAR pFldType, UINT16 iUnits1,
|
|
// pCHAR pszRetBuffer)
|
|
//
|
|
// Input:
|
|
// from AddField(), DeleteField(), ModifyField(), or MoveField()
|
|
// hglbCorrectTableInfo - handle to TableInfo struct
|
|
// FieldOp - crCOPY, crDROP, crADD, or crMODIFY
|
|
// iNewFldNum - new position of field
|
|
// pOldName - old field name
|
|
// pNewName - new field name
|
|
// pFldType - field type
|
|
// iUnits1 - field size
|
|
// pszRetBuffer - return to client
|
|
//
|
|
// Return: (pszRetBuffer) null or error string.
|
|
//
|
|
// Description:
|
|
// This function sets up the field structure for the new table.
|
|
//=====================================================================
|
|
void FAR WINAPI
|
|
SetFieldDescriptions (HGLOBAL hglbCorrectTableInfo, CROpType FieldOp,
|
|
UINT16 iNewFldNum, pCHAR pOldName, pCHAR pNewName,
|
|
pCHAR pFldType, UINT16 iUnits1, pCHAR pszRetBuffer)
|
|
{
|
|
UINT16 i;
|
|
UINT16 iField = 0;
|
|
UINT16 iDropped = 0;
|
|
UINT16 iCompleted= 0;
|
|
UINT16 iFieldFound = 0;
|
|
UINT16 iOrigFld;
|
|
UINT16 FieldType = 0;
|
|
struct TBLINFO *TableInfo;
|
|
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
CHKERR_NODISPLAY(hglbCorrectTableInfo == NULL);
|
|
|
|
TableInfo = GlobalLock (hglbCorrectTableInfo);
|
|
if (TableInfo == NULL)
|
|
{
|
|
hglbCorrectTableInfo = NULL;
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
CHKERR_NODISPLAY((TableInfo == NULL) || (TableInfo->retVal == 1))
|
|
TableInfo->retVal = 1;
|
|
|
|
// allow any case for user input of field type
|
|
AnsiUpper(pFldType);
|
|
|
|
// set field types for dBASE
|
|
if (!strcmp(TableInfo->crTblDesc.szTblType, szDBASE))
|
|
{
|
|
switch (pFldType[0])
|
|
{
|
|
case 'C':
|
|
FieldType = fldDBCHAR;
|
|
break;
|
|
case 'F':
|
|
FieldType = fldDBFLOAT;
|
|
break;
|
|
case 'N':
|
|
FieldType = fldDBNUM;
|
|
break;
|
|
case 'D':
|
|
FieldType = fldDBDATE;
|
|
break;
|
|
case 'L':
|
|
FieldType = fldDBBOOL;
|
|
break;
|
|
case 'M':
|
|
FieldType = fldDBMEMO;
|
|
break;
|
|
case 'O':
|
|
FieldType = fldDBOLEBLOB;
|
|
break;
|
|
case 'B':
|
|
FieldType = fldDBBINARY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// set field types for Paradox
|
|
if (!strcmp(TableInfo->crTblDesc.szTblType, szPARADOX))
|
|
{
|
|
switch (pFldType[0])
|
|
{
|
|
case 'A':
|
|
FieldType = fldPDXCHAR;
|
|
break;
|
|
case 'N':
|
|
FieldType = fldPDXNUM;
|
|
break;
|
|
case '$':
|
|
FieldType = fldPDXMONEY;
|
|
break;
|
|
case 'D':
|
|
FieldType = fldPDXDATE;
|
|
break;
|
|
case 'S':
|
|
FieldType = fldPDXSHORT;
|
|
break;
|
|
case 'M':
|
|
FieldType = fldPDXMEMO;
|
|
break;
|
|
case 'B':
|
|
FieldType = fldPDXBINARYBLOB;
|
|
break;
|
|
case 'F':
|
|
FieldType = fldPDXFMTMEMO;
|
|
break;
|
|
case 'O':
|
|
FieldType = fldPDXOLEBLOB;
|
|
break;
|
|
case 'G':
|
|
FieldType = fldPDXGRAPHIC;
|
|
break;
|
|
case 'I':
|
|
FieldType = fldPDXLONG;
|
|
break;
|
|
case 'T':
|
|
FieldType = fldPDXTIME;
|
|
break;
|
|
case '@':
|
|
FieldType = fldPDXDATETIME;
|
|
break;
|
|
case 'L':
|
|
FieldType = fldPDXBOOL;
|
|
break;
|
|
case '+':
|
|
FieldType = fldPDXAUTOINC;
|
|
break;
|
|
case 'Y':
|
|
FieldType = fldPDXBYTES;
|
|
break;
|
|
case '#':
|
|
FieldType = fldPDXBCD;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// get index descriptor if a primary key exists
|
|
if (TableInfo->bHasIndex)
|
|
{
|
|
DbiGetIndexDescs(TableInfo->hCur, TableInfo->pIdxDesc);
|
|
}
|
|
|
|
// setup in order, set field numbers to old positions.
|
|
for (i = 0; i < TableInfo->uNumFields; i++)
|
|
{
|
|
|
|
// operation for moving fields
|
|
if (FieldOp == crCOPY)
|
|
{
|
|
// was it copied already?
|
|
if (!strcmpi(pOldName, TableInfo->pFldDesc[iNewFldNum - 1].szName))
|
|
{
|
|
GetString(9, pszRetBuffer); //"The field was already moved."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// the existing field name is found
|
|
if (!strcmpi(TableInfo->pFldDesc[i].szName,
|
|
pOldName))
|
|
{
|
|
|
|
// the table has a primary key
|
|
if (TableInfo->bHasIndex)
|
|
{
|
|
|
|
// don't allow a copy to an existing key
|
|
if ((((i + 1) <= TableInfo->pIdxDesc[0].iFldsInKey) ||
|
|
(iNewFldNum <= TableInfo->pIdxDesc[0].iFldsInKey) &&
|
|
!strcmp(TableInfo->crTblDesc.szTblType, szPARADOX)) &&
|
|
TableInfo->pIdxDesc[0].bPrimary)
|
|
{
|
|
GetString(2, pszRetBuffer); //"Only modifications can
|
|
// be made to primary keys."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
|
|
// is the new field number within range of the existing field
|
|
// descriptors?
|
|
if (iNewFldNum < 1 || iNewFldNum > TableInfo->uNumFields)
|
|
{
|
|
GetString(5, pszRetBuffer); //"Invalid field descriptor."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// copy a field descriptor
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1] =
|
|
TableInfo->pFldDesc[i];
|
|
|
|
// set field number to the old position (not to iFldNum)
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iFldNum = i + 1;
|
|
|
|
// set field operation
|
|
TableInfo->ecrFldOp[iNewFldNum - 1] = crCOPY;
|
|
|
|
// done with this operation
|
|
iFieldFound = 1;
|
|
}
|
|
|
|
// couldn't find field name
|
|
if (i + 1 == TableInfo->uNumFields && iFieldFound == 0)
|
|
{
|
|
GetString(5, pszRetBuffer); //"Invalid field descriptor."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
|
|
// operation for adding fields
|
|
if (FieldOp == crADD)
|
|
{
|
|
// is the new field number out of range?
|
|
if (iNewFldNum - 1 > TableInfo->uNumFields)
|
|
{
|
|
GetString(10, pszRetBuffer); //"The new field number is out of
|
|
// range."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
// was the field added already?
|
|
for (iFieldFound = 0; iFieldFound < TableInfo->uNumFields;
|
|
iFieldFound++)
|
|
{
|
|
if (!strcmpi(pOldName, TableInfo->pFldDesc[iFieldFound].szName))
|
|
{
|
|
GetString(4, pszRetBuffer); //"The field was already added."
|
|
CLEANUP_NODISPLAY;
|
|
|
|
}
|
|
}
|
|
|
|
if (TableInfo->bHasIndex)
|
|
{
|
|
if (iNewFldNum <= TableInfo->pIdxDesc[0].iFldsInKey &&
|
|
!strcmp(TableInfo->crTblDesc.szTblType, szPARADOX) &&
|
|
TableInfo->pIdxDesc[0].bPrimary)
|
|
{
|
|
GetString(2, pszRetBuffer); //"Only modifications can be made
|
|
// to primary keys."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
|
|
// set field numbers to zero for added fields
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iFldNum = 0;
|
|
|
|
strcpy(TableInfo->pFldDescriptor[iNewFldNum - 1]
|
|
.szName, pOldName);
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iFldType = FieldType;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iSubType = 0;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iUnits1 = iUnits1;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iUnits2 = 0;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iOffset = 0;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iLen = 0;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].iNullOffset = 0;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].efldvVchk =
|
|
fldvNOCHECKS;
|
|
TableInfo->pFldDescriptor[iNewFldNum - 1].efldrRights =
|
|
fldrREADWRITE;
|
|
TableInfo->ecrFldOp[iNewFldNum - 1] = crADD;
|
|
}
|
|
|
|
// operation for modifying field names, types, or sizes
|
|
if (FieldOp == crMODIFY)
|
|
{
|
|
|
|
// quit loop if this operation is finished
|
|
if (iCompleted == 1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for (iFieldFound = 0; iFieldFound < TableInfo->uNumFields;
|
|
iFieldFound++)
|
|
{
|
|
if (!strcmpi(pOldName, TableInfo->pFldDesc[iFieldFound].szName))
|
|
{
|
|
TableInfo->pFldDescriptor[iFieldFound] =
|
|
TableInfo->pFldDesc[iFieldFound];
|
|
TableInfo->pFldDescriptor[iFieldFound].iFldNum =
|
|
iFieldFound + 1;
|
|
strcpy(TableInfo->pFldDescriptor[iFieldFound].szName,
|
|
pNewName);
|
|
TableInfo->pFldDescriptor[iFieldFound].iFldType = FieldType;
|
|
TableInfo->pFldDescriptor[iFieldFound].iSubType = 0;
|
|
TableInfo->pFldDescriptor[iFieldFound].iUnits1 = iUnits1;
|
|
TableInfo->pFldDescriptor[iFieldFound].iUnits2 = 0;
|
|
TableInfo->pFldDescriptor[iFieldFound].iOffset = 0;
|
|
TableInfo->pFldDescriptor[iFieldFound].iLen = 0;
|
|
TableInfo->pFldDescriptor[iFieldFound].iNullOffset = 0;
|
|
TableInfo->pFldDescriptor[iFieldFound].efldvVchk =
|
|
fldvNOCHECKS;
|
|
TableInfo->pFldDescriptor[iFieldFound].efldrRights =
|
|
fldrREADWRITE;
|
|
TableInfo->ecrFldOp[iFieldFound] = crMODIFY;
|
|
iCompleted = 1;
|
|
break;
|
|
}
|
|
if (iFieldFound + 1 == TableInfo->uNumFields)
|
|
{
|
|
GetString(7, pszRetBuffer); //"The field name can't be found."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
}
|
|
|
|
// operation for deleting fields - deletes by skipping a field
|
|
// descriptor copy
|
|
// does nothing except check if field was already dropped
|
|
if (FieldOp == crDROP)
|
|
{
|
|
// was it dropped already?
|
|
for (iFieldFound = 0; iFieldFound < TableInfo->uNumFields;
|
|
iFieldFound++)
|
|
{
|
|
if (!strcmpi(TableInfo->pFldDesc[iFieldFound].szName, pOldName))
|
|
{
|
|
if (TableInfo->bHasIndex)
|
|
{
|
|
if ((iFieldFound + 1) <= TableInfo->pIdxDesc[0].
|
|
iFldsInKey && !strcmp(TableInfo->crTblDesc.
|
|
szTblType, szPARADOX)&& TableInfo->pIdxDesc[0].
|
|
bPrimary)
|
|
{
|
|
GetString(2, pszRetBuffer); //"Only modifications can
|
|
// be made to primary keys."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
iDropped = 1;
|
|
}
|
|
|
|
if ((iFieldFound + 1 == TableInfo->uNumFields) && iDropped == 0)
|
|
{
|
|
GetString(8, pszRetBuffer); //"The field was already deleted."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// fill in blank field descriptors
|
|
for (i = 0; i < TableInfo->uNewNumFields; i++)
|
|
{
|
|
|
|
// check for blank field (preassigned -1u - max of possible ranges)
|
|
if (TableInfo->pFldDescriptor[i].iFldNum == -1u)
|
|
{
|
|
for (iOrigFld = iField; iOrigFld < TableInfo->uNumFields;
|
|
iOrigFld++)
|
|
{
|
|
iField++;
|
|
if (strcmpi(TableInfo->pFldDesc[iOrigFld].szName, pOldName))
|
|
{
|
|
TableInfo->pFldDescriptor[i] =
|
|
TableInfo->pFldDesc[iOrigFld];
|
|
|
|
// set field number to the old position (not the iFldNum)
|
|
TableInfo->pFldDescriptor[i].iFldNum = iOrigFld + 1;
|
|
TableInfo->ecrFldOp[i] = crCOPY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
TableInfo->retVal = 0;
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
GlobalUnlock(hglbCorrectTableInfo);
|
|
hglbCorrectTableInfo = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// EndRestructure(HGLOBAL hglbCorrectTableInfo, pCHAR pPack,
|
|
// pCHAR pszRetBuffer)
|
|
//
|
|
// Input:
|
|
// from AddField(), DeleteField(), ModifyField(), or MoveField()
|
|
// hglbCorrectTableInfo - handle to TableInfo struct
|
|
// pPack - "PACK" or "NOPACK"
|
|
// pCHAR pszRetBuffer - return to client
|
|
//
|
|
// Return: null or error string.
|
|
//
|
|
// Description:
|
|
// This function gets creates a new table descriptor image
|
|
// and calls IDAPI to do the actual restructure.
|
|
//=====================================================================
|
|
void FAR WINAPI
|
|
EndRestructure (HGLOBAL hglbCorrectTableInfo, pCHAR pPack,
|
|
pCHAR pszRetBuffer)
|
|
{
|
|
DBIResult rslt;
|
|
DBIPATH szKeyViol;
|
|
struct TBLINFO *TableInfo;
|
|
|
|
GetString(11, szKeyViol); // Key violation table name
|
|
memset(pszRetBuffer, 0, (DBIMAXMSGLEN +1) * sizeof(char));
|
|
|
|
CHKERR_NODISPLAY(hglbCorrectTableInfo == NULL);
|
|
|
|
TableInfo = GlobalLock (hglbCorrectTableInfo);
|
|
if (TableInfo == NULL)
|
|
{
|
|
hglbCorrectTableInfo = NULL;
|
|
GetString(1, pszRetBuffer); //"Out of Memory."
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
CHKERR_NODISPLAY((TableInfo == NULL) || (TableInfo->retVal == 1))
|
|
TableInfo->retVal = 1;
|
|
|
|
// allow any case for user input of pack operation
|
|
AnsiUpper(pPack);
|
|
|
|
// set default to no table pack
|
|
TableInfo->crTblDesc.bPack = FALSE;
|
|
|
|
if (!strcmpi(pPack, "PACK"))
|
|
{
|
|
TableInfo->crTblDesc.bPack = TRUE;
|
|
}
|
|
|
|
if (!strcmpi(pPack, "NOPACK"))
|
|
{
|
|
TableInfo->crTblDesc.bPack = FALSE;
|
|
}
|
|
|
|
// copy information to new table descriptor
|
|
TableInfo->crTblDesc.iFldCount = TableInfo->uNewNumFields;
|
|
TableInfo->crTblDesc.pecrFldOp = TableInfo->ecrFldOp;
|
|
TableInfo->crTblDesc.pfldDesc = TableInfo->pFldDescriptor;
|
|
|
|
// allows DbiDoRestructure to get an exclusive lock on the table
|
|
CHKERR_CLEANUP(DbiCloseCursor(&TableInfo->hCur));
|
|
TableInfo->hCur = NULL;
|
|
|
|
// call to BDE to restructure the table
|
|
CHKERR_CLEANUP(DbiDoRestructure(TableInfo->hDb, 1, &TableInfo->crTblDesc,
|
|
NULL, szKeyViol, NULL, FALSE));
|
|
|
|
TableInfo->retVal = 0;
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
GlobalUnlock(hglbCorrectTableInfo);
|
|
hglbCorrectTableInfo = NULL;
|
|
}
|
|
if (!strcmp(pszRetBuffer, "\0"))
|
|
{
|
|
GetString(13, pszRetBuffer); // "Restructure successful."
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// DBIError(HGLOBAL hglbCorrectTableInfo, DBIResult retVal,
|
|
// pCHAR pszRetBuffer)
|
|
//
|
|
// Input:
|
|
// from macro.h:
|
|
// hglbCorrectTableInfo - handle to TableInfo struct
|
|
// retVal - BDE return
|
|
// pszRetBuffer - Buffer to contain the error string
|
|
//
|
|
// Return: a DBIResult value.
|
|
//
|
|
// Description:
|
|
// This function gets information of where an error occurred.
|
|
//=====================================================================
|
|
DBIResult
|
|
DBIError (HGLOBAL hglbCorrectTableInfo, DBIResult retVal, pCHAR pszRetBuffer)
|
|
{
|
|
struct TBLINFO *TableInfo;
|
|
|
|
if (retVal == DBIERR_NONE)
|
|
{
|
|
return retVal;
|
|
}
|
|
|
|
CHKERR_NODISPLAY(hglbCorrectTableInfo == NULL)
|
|
|
|
TableInfo = GlobalLock (hglbCorrectTableInfo);
|
|
if (TableInfo == NULL)
|
|
{
|
|
hglbCorrectTableInfo = NULL;
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
if (retVal == DBIERR_CANTFINDODAPI)
|
|
{
|
|
GetString(3, pszRetBuffer); //"Cannot find IDAPI files: Check path."
|
|
CLEANUP_DISPLAYERR(pszRetBuffer);
|
|
}
|
|
else
|
|
{
|
|
DbiGetErrorString(retVal, pszRetBuffer);
|
|
}
|
|
|
|
CleanUp:
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
GlobalUnlock(hglbCorrectTableInfo);
|
|
hglbCorrectTableInfo = NULL;
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// cleanUpMemory(HGLOBAL hglbCorrectTableInfo);
|
|
//
|
|
// Description:
|
|
// Free all allocations, cursors, and tables if needed.
|
|
//=====================================================================
|
|
void
|
|
cleanUpMemory (HGLOBAL hglbCorrectTableInfo)
|
|
{
|
|
UINT16 i;
|
|
struct TBLINFO *TableInfo;
|
|
|
|
CHKERR_NODISPLAY(hglbCorrectTableInfo == NULL);
|
|
|
|
TableInfo = GlobalLock (hglbCorrectTableInfo);
|
|
if (TableInfo == NULL)
|
|
{
|
|
hglbCorrectTableInfo = NULL;
|
|
CLEANUP_NODISPLAY;
|
|
}
|
|
|
|
if (hglbCorrectTableInfo)
|
|
{
|
|
if (TableInfo->hCur)
|
|
{
|
|
DbiCloseCursor(&TableInfo->hCur);
|
|
}
|
|
|
|
if (TableInfo->hDb)
|
|
{
|
|
DbiCloseDatabase(&TableInfo->hDb);
|
|
}
|
|
|
|
if (TableInfo->ecrFldOp)
|
|
{
|
|
free(TableInfo->ecrFldOp);
|
|
}
|
|
|
|
if (TableInfo->pIdxDesc)
|
|
{
|
|
free(TableInfo->pIdxDesc);
|
|
}
|
|
|
|
if (TableInfo->pFldDescriptor)
|
|
{
|
|
free(TableInfo->pFldDescriptor);
|
|
}
|
|
|
|
if (TableInfo->pFldDesc)
|
|
{
|
|
free(TableInfo->pFldDesc);
|
|
}
|
|
|
|
//decrement lock count to 0.
|
|
for (i = GlobalFlags(hglbCorrectTableInfo); i > 0; i--)
|
|
{
|
|
GlobalUnlock(hglbCorrectTableInfo);
|
|
}
|
|
GlobalFree(hglbCorrectTableInfo);
|
|
|
|
CleanUp:
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// GetString(WORD iStringID, pCHAR pszRetBuffer)
|
|
//
|
|
// Input:
|
|
// iStringID - Identifier for the string
|
|
// pszBuffer - Buffer to contain the error string.
|
|
// (Allocated by the calling function)
|
|
//
|
|
// Description:
|
|
// Load a string from STRUCTER.DLL.
|
|
//=====================================================================
|
|
void
|
|
GetString (WORD iStringID, pCHAR pszRetBuffer)
|
|
{
|
|
if (pszRetBuffer)
|
|
{
|
|
LoadString(GetModuleHandle(szCURRENTMODULE), iStringID, pszRetBuffer,
|
|
DBIMAXMSGLEN - 1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#pragma argsused
|
|
BOOL WINAPI
|
|
LibMain (HINSTANCE hInstance, WORD wDataSeg,
|
|
WORD cbHeapSize, LPSTR lpCmdLine) {
|
|
if (cbHeapSize != 0)
|
|
{
|
|
UnlockData(0);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int WINAPI
|
|
WEP (int nSystemExit) {
|
|
switch (nSystemExit) {
|
|
case WEP_SYSTEM_EXIT:
|
|
break;
|
|
case WEP_FREE_DLL:
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|