Category : Databases and related files
Archive   : MF-DB102.ZIP
Filename : MFCONV.C

 
Output of file : MFCONV.C contained in archive : MF-DB102.ZIP
/*

MF Conversion utility
Copyright 1993, Carl Brown

Converts MF database types:
1.0x
to
1.02

(compiled under MSC 8.0 (VC++))

You may do whatever you want with this. It's public domain.

This utility has been placed in a DLL so you can use it
once and discard (delete) it.

You may distribute this DLL with your application so that
you can convert end-users systems to the new DB version.

You may also copy this source code and place it in to your own
source code, if you wish. (That way the conversion code will
be embedded into one file...). Optionally, you may translate this
code in to another language and embed it in your application(s).

The conversion routines were not placed in the database
because they take a while to run and we wouldn't want your
call to mfOpen to take 1/2 an hour to complete...

This routine also OVER DOUBLES the size of the disk space required
to hold the DB file. (only while this routine is running).

ONE LAST WORD:
BACK UP YOU DATABASE BEFORE RUNNING THIS!
I tested it on about 200 databases and found a few anomalies along the
way:
1- Corrupt databases NEVER convert (they just lock the system...)
2- Databases with 4 byte records GPF (can't figure out why,,,
(however, they DO convert! Wierd...)

-Carl Brown


*/
#include
#include
#include


/*
External conversion procedure

Call this function with:
DATABASE (FULL path and filename) to convert

returns:
0 - All ok
-1 - Error

*/
int
// this allows it to be a DLL or an EXE...
#ifndef NOT_DLL
FAR PASCAL _export
#endif
mfConvert(LPSTR lpszDBName)
{
HFILE hDBFile;
HFILE hTempDBFile;

char szTempFile[] = "/mfTEMP.$$$";

int iDBRecSize; // Internal DB information
long lDBNumRecs;
long lDBDeletePtr;


hDBFile = _lopen(lpszDBName, READ_WRITE);
if (hDBFile == HFILE_ERROR)
{
MessageBox(NULL, "Database could not be opened", "ERROR", MB_OK);
return (-1);
}

hTempDBFile = _lcreat((LPSTR)szTempFile, READ_WRITE);
if (hDBFile == HFILE_ERROR)
{
_lclose(hDBFile);
MessageBox(NULL, "Temporary Database could not be created", "ERROR", MB_OK);
return (-1);
}


/*
Read the record size,
the # of records in the database, and
the 'delete' pointer.
*/
_llseek(hDBFile, 8, SEEK_SET);
_lread(hDBFile, &iDBRecSize, 2);

_llseek(hDBFile, 14, SEEK_SET);
_lread(hDBFile, &lDBNumRecs, 4);

_llseek(hDBFile, 18, SEEK_SET);
_lread(hDBFile, &lDBDeletePtr, 4);

/*

Convert the data to the new DB format

*/
/*
Fix header information
*/
{
char aHdr[50];

_llseek(hDBFile, 0, SEEK_SET);
_lread(hDBFile, (LPSTR)aHdr, 50);

/* Is this a valid MF file? */
aHdr[5] = 0;
if(lstrcmp((LPSTR)&aHdr, "M1.00") != 0)
return (-1);

lstrcpy((LPSTR)&aHdr, "M1.02");

_llseek(hTempDBFile, 0, SEEK_SET);
_lwrite(hTempDBFile, (LPSTR)aHdr, 50);

_llseek(hTempDBFile, 0, SEEK_SET);
lstrcpy((LPSTR)&aHdr, "M1.02");
_lwrite(hTempDBFile, (LPSTR)&aHdr, 5);


}

/*
Process the old records into the new format
*/
{
long lCurRecord; // Current record being processed

HGLOBAL hMemRecord; // One DB record
LPSTR lpRecord; // "

hMemRecord = GlobalAlloc(GPTR, iDBRecSize + 8);
lpRecord = GlobalLock(hMemRecord);

/*
Initialize the last 8 bytes of the new record to 0
(These are new bytes used by the new file format)
*/
{
int n;
for (n = 1; n <= 8; n++)
*(lpRecord + iDBRecSize - n) = 0;
}

for(lCurRecord = 0; lCurRecord <= lDBNumRecs; lCurRecord++)
{
_llseek(hDBFile, (lCurRecord * iDBRecSize ) + 50, SEEK_SET);
_lread(hDBFile, lpRecord, iDBRecSize);

_llseek(hTempDBFile, (lCurRecord * (iDBRecSize + 8)) + 50, SEEK_SET);
_lwrite(hTempDBFile, lpRecord, iDBRecSize + 8);

}
GlobalUnlock(hMemRecord);
GlobalFree(hMemRecord);
}


/*
Since the old system contained a linked list of deletes,
we need to mark all the converted records so the new DB
can process deleted records
*/
{
int iDelMarker = 1;
long lLiveCount = lDBNumRecs;
while (lDBDeletePtr != -1)
{
_llseek(hTempDBFile, ((lDBDeletePtr + 1) * (iDBRecSize + 8)) + 50 - 8, SEEK_SET);
_lwrite(hTempDBFile, &iDelMarker, sizeof(int));
lLiveCount--;

_llseek(hTempDBFile, (lDBDeletePtr * (iDBRecSize + 8)) + 50, SEEK_SET);
_lread(hTempDBFile, &lDBDeletePtr, sizeof(long));

}
/*
Now we know how many live (not deleted) records are
in the database
*/
_llseek(hTempDBFile, 22, SEEK_SET);
_lwrite(hTempDBFile, &lLiveCount, 4);

}

/*
Now, copy the temp DB over the live DB
*/
{
int bRead;
static char ioBuffer[4096];
_llseek(hTempDBFile, 0, SEEK_SET);
_llseek(hDBFile, 0, SEEK_SET);

do{

bRead = _lread( hTempDBFile, ioBuffer, 4096 );
if(bRead == -1)
return(-1);

if(_lwrite( hDBFile, ioBuffer, bRead ) == -1)
return(-1);

} while (bRead != 0);

}

_lclose(hDBFile);
_lclose(hTempDBFile);
_unlink(szTempFile);

}



#ifndef NOT_DLL
/*----------------------------------------------------------------------
This is required for 'windows' dll's.
Generally, you put any startup code that you might require,
initialize variables, allocate memory, etc...
*/
int FAR PASCAL LibMain(
HANDLE hModule,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine
)
{
return 1;
}

#endif



  3 Responses to “Category : Databases and related files
Archive   : MF-DB102.ZIP
Filename : MFCONV.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/