9.0 Example Code

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, 
                                &reg, 
                                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 ); 
  }