This section contains a commented sample program using some of the features of Media Manager.
#include "mmpublic.h"
#define PARTITION_STAMP 0x88888888
#define NUMBER_OF_PARTITION_STAMPS 8
LONG ReservationAlert(
HNDL reservationhandle,
LONG token,
LONG alerttype,
LONG alertreason );
void InitPartitionCallback(
HNDL messagehandle,
LONG *requestcount, /* callback parameter */
LONG returnparameter,
/* certain IO requests can return additional info */
LONG ccode );
LONG
requestcount,
MMapplicationtag;
/*
Function InitializePartition() is written only tho illistrate the use
of some MM APIs. An application is registered, the database is
quiried for a Logical Partition object that is a NetWare Partition
type 0x65 (that is a NetWare partition that has not been abstracted
into HotFix and Mirror objects. The object is then reserved and IO
performed on it. The reservation is released and the application
unregistered.
*/
LONG InitializePartition()
{
struct ApplicationRegistrationDef
reg;
OBID
objid;
HNDL
apphandle,
reshandle;
LONG
i,
ccode,
returnparameter;
struct IOObjectGenericInfoDef
iogeninfo;
struct PartitionSpecificInfoDef
partinfo;
BYTE
sectorbuffer[512];
/*
Registering an application does not require an application handle,
however, to satisfy the MM_RegisterObject() prototype the
application parameter, the forth parameter, is set to the variable
’apphandle’ even though it is not yet initialized. It becomes
initialized, in this example, as a result of calling
MM_RegisterObject().
*/
reg.classobjectsignature = MM_APPLICATION_SIGNATURE;
reg.controlroutine = NULL;
reg.name = "The Foo Application";
reg.type = MM_GENERAL_STORAGE_APPLICATION;
reg.identifier = 0x45454545; /* User defined */
ccode = MM_RegisterObject( &apphandle,
MM_APPLICATION_CLASS,
®,
apphandle,
MMapplicationtag );
/*
The MMapplicationtag is assumed initialized prior to entering this
function.
*/
/*
Find a Logical Partition that is a NetWare Partition, (not an
abstraction of a NetWare Partition). {Indeed, I could just as well
look for MM_PARTITION_OBJECTs and check for a childcount, found in
the generic info, of zero}
*/
if ( ccode == MM_OK )
{
objid = -1; * Seed for the start of the find first, find next */
while( (ccode = MM_FindObjectType( MM_IO_CLASS,
MM_LOGICAL_PARTITION_OBJECT,
&objid ))
== MM_OK )
{
if ( (ccode = MM_ReturnObjectGenericInfo( objid,
sizeof( iogeninfo ),
&iogeninfo ))
== MM_OK )
{
if ( iogeninfo.type == MM_PARTITION_OBJECT )
{
if ( (ccode = MM_ReturnObjectSpecificInfo( objid,
sizeof( partinfo ),
&partinfo ))
== MM_OK )
{
if ( partinfo.partitiontype == NETWARE_386_PARTITION )
{
break;
}
}
}
}
}
/*
Reserve the found object and do some IO.
ccode will be MM_OK only if the object was found and information
about the object was successfull obtained.
*/
if ( ccode == MM_OK )
{
if ( (ccode = MM_ReserveIOObject( &reshandle,
objid,
MM_IO_MODE,
0,
/* user defined value */
ReservationAlert,
/* Can be NULL */
apphandle ))
== MM_OK )
{
/*
Let’s say sector 44 contains a stamp that, if present, indicates the
partition is initialized otherwise it needs to be initialized.
Initializing the partition includes placing the stamp at sector 44
and every 10 sectors thereafter up to NUMBER_OF_PARTITION_STAMPS.
*/
if ( ((ccode = MM_ObjectBlockingIO( &returnparameter,
reshandle,
MM_RANDOM_READ,
1,
44,
0,
512,
sectorbuffer ))
== MM_OK)
&& ( *(LONG *) sectorbuffer != PARTITION_STAMP) )
{
requestcount = NUMBER_OF_PARTITION_STAMPS;
*(LONG *) sectorbuffer = PARTITION_STAMP;
/*
Because the asynchronous IO call MM_ObjectIO() is used, the entire
for loop is executed without blocking.
*/
for ( i = 0; i < NUMBER_OF_PARTITION_STAMPS; i++ )
{
if ( MM_ObjectIO( NULL,
reshandle,
MM_RANDOM_WRITE,
1,
44 + 10*i,
0,
512,
sectorbuffer,
(LONG) &requestcount,
InitPartitionCallback )
!= MM_OK )
{
requestcount–; /* This request will not have a */
/* callback event. */
}
}
while( requestcount != 0 )
{
/* Do some work that causes thread switches */
/* or simply ThreadSwitch(); */
}
}
MM_ReleaseIOObject( reshandle );
}
}
MM_UnregisterObject( apphandle, MM_ALERT_PROGRAM_CONTROL );
}
return( ccode );
}
void InitPartitionCallback(
HNDL messagehandle,
LONG *requestcount, /* callback parameter */
LONG returnparameter,
/* certain IO requests can return additional info */
LONG ccode )
{
(*requestcount)–;
}
LONG ReservationAlert(
HNDL reservationhandle,
LONG token,
LONG alerttype,
LONG alertreason )
{
LONG
ccode = MM_OK;
/* Deal with the event. */
return( ccode );
}