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 ); }