Example #1
0
int init_memory(unsigned long arg1){
	unsigned long virt_real_start_addr,virt_start_addr,virt_end_addr;
	unsigned long pc_size;
	unsigned long current_end_memused=&end; /* till this point memory is used*/

	unsigned long phy_end_addr = g_phy_mem_size;
	ut_log("	Initializing memory phy_endaddr : %x  current end:%x symbols_end:%x\n",phy_end_addr,current_end_memused,symbols_end);
	if (symbols_end != 0){
		current_end_memused = symbols_end;
	}

	virt_start_addr=initialise_paging_new(phy_end_addr, current_end_memused,&virt_real_start_addr,&virt_end_addr);
	INIT_LOG("	After Paging initialized Virtual start_addr: %x virtual endaddr: %x  current end:%x virtualreal_start:%x\n",virt_start_addr,virt_end_addr,current_end_memused,virt_real_start_addr);
	INIT_LOG("	code+data  : %x  -%x size:%dK",&_start,&_end);
	INIT_LOG("	free area  : %x - %x size:%dM\n",virt_start_addr,virt_end_addr,(virt_end_addr-virt_start_addr)/1000000);
	virt_start_addr=init_free_area( virt_start_addr, virt_end_addr);

	pc_size = g_pagecache_size ;
	pc_init((unsigned char *)virt_start_addr,pc_size);
	ut_log("	pagecache  : %x - %x size:%dM",virt_start_addr,virt_start_addr+pc_size,pc_size/1000000);

	virt_start_addr=virt_start_addr+pc_size;

#if 0 /* reserve the test memory for testing */
	if (virt_end_addr > (virt_start_addr + (600*1024*1024))){
	test_mem_start = virt_start_addr;
	test_mem_end  = virt_start_addr + 512 *1024 *1204 ; /* 512M */
	virt_start_addr =  test_mem_end + 4096;
	}
#endif

	init_mem(virt_start_addr, virt_end_addr, virt_real_start_addr);
	INIT_LOG("		buddy pages: %x - %x size:%dM\n",virt_start_addr, virt_end_addr,(virt_end_addr-virt_start_addr)/1000000);
	return JSUCCESS;
}
Example #2
0
static void init_mem(unsigned long start_mem, unsigned long end_mem, unsigned long virt_start_addr){
	int reservedpages = 0;
	unsigned long tmp;

	end_mem &= PAGE_MASK;
	g_max_mapnr  = MAP_NR(end_mem);

	INIT_LOG("	first page : %x :%x :%x\n",MAP_NR(start_mem),MAP_NR(start_mem+PAGE_SIZE),MAP_NR(virt_start_addr));
	start_mem = PAGE_ALIGN(start_mem);
	g_stat_mem_size = end_mem -start_mem;
	while (start_mem < end_mem) {
		clear_bit(PG_reserved, &g_mem_map[MAP_NR(start_mem)].flags);
		start_mem += PAGE_SIZE;
	}
	for (tmp = virt_start_addr ; tmp < (end_mem - 0x2000) ; tmp += PAGE_SIZE) {
		/*if (tmp >= MAX_DMA_ADDRESS)
		  clear_bit(PG_DMA, &g_mem_map[MAP_NR(tmp)].flags);*/
		if (PageReserved(g_mem_map+MAP_NR(tmp))) {
			reservedpages++;
			continue;
		}
		atomic_set(&g_mem_map[MAP_NR(tmp)].count, 1);
		PageSetReferenced(g_mem_map+MAP_NR(tmp));
		mm_putFreePages(tmp,0);
	}
	stat_allocs=0;
	stat_frees =0;
	INIT_LOG("	Reserved pages : %x(%d) \n",reservedpages,reservedpages);
	init_done=1;
	INIT_LOG("	Release to FREEMEM : %x \n",(end_mem - 0x2000));
	return;
}
Example #3
0
/*
 * set up the free-area data structures:
 *   - mark all pages reserved
 *   - mark all memory queues empty
 *   - clear the memory bitmaps
 */
static unsigned long init_free_area(unsigned long start_mem, unsigned long end_mem)
{
	page_struct_t *p;
	unsigned long mask = PAGE_MASK;
	unsigned long i;
	unsigned long start_addrspace = KADDRSPACE_START;
	int size;

	/*
	 * Select nr of pages we try to keep free for important stuff
	 * with a minimum of 10 pages and a maximum of 256 pages, so
	 * that we don't waste too much memory on large systems.
	 * This is fairly arbitrary, but based on some behaviour
	 * analysis.
	 */
	INIT_LOG("	init_free_area start_mem: %x endmem:%x   \n",start_mem,end_mem);
	i = (end_mem - start_addrspace) >> (PAGE_SHIFT+7);
	if (i < 10)
		i = 10;
	if (i > 256)
		i = 256;
	/*TODO freepages.min = i;
	  freepages.low = i * 2;
	  freepages.high = i * 3;*/
	g_mem_map = (page_struct_t *) LONG_ALIGN(start_mem+8);
	INIT_LOG("	g_mem_map :%x  size:%x  \n",g_mem_map,MAP_NR(end_mem));
	p = g_mem_map + MAP_NR(end_mem);
	start_mem = LONG_ALIGN((unsigned long) p);
	size=(start_mem -(unsigned long) g_mem_map);
	INIT_LOG(" freearemap setup map: %x diff:%x(%dM)   \n",g_mem_map,(start_mem -(unsigned long) g_mem_map),size/(1024*1024));
	//while(1);
	ut_memset((unsigned char *)g_mem_map, 0, start_mem -(unsigned long) g_mem_map);
	do {
		--p;
		atomic_set(&p->count, 0);
		p->flags = (1 << PG_DMA) | (1 << PG_reserved) ;
	} while (p > g_mem_map);

	for (i = 0 ; i < NR_MEM_LISTS ; i++) {
		unsigned long bitmap_size;
		init_mem_queue(free_mem_area+i);
		mask += mask;
		end_mem = (end_mem + ~mask) & mask;
		bitmap_size = (end_mem - start_addrspace) >> (PAGE_SHIFT + i);
		bitmap_size = (bitmap_size + 7) >> 3;
		bitmap_size = LONG_ALIGN(bitmap_size);
		free_mem_area[i].map = (unsigned int *) start_mem;
		ut_memset((void *) start_mem, 0, bitmap_size);
		start_mem += bitmap_size;
		INIT_LOG("		%d : bitmapsize:%x end_mem:%x \n",i,bitmap_size,end_mem);
	}
	return start_mem;
}
Example #4
0
int main(int argc, char *argv[])
{
	INIT_LOG(NULL, LOG_CONSOLE, "test.log", 1);

	const char *ip = NULL;
	const char *port = NULL;
    if(argc < 3)
    {
        ip = defaultip;
        port = defaultport;
    }
    else
    {
    	ip = argv[1];
    	port = argv[2];
    }

    //    vos::make_thread(thread_fun, NULL);
    pthread_t t1, t2;
    pthread_create(&t1, NULL, thread_fun, 0);

//  pthread_create(&t2, NULL, thread_fun, (void*)10000);

	while(1)
	{
		sleep(1);
	}

    return 0;
}
Example #5
0
void log_uart_init(void)
{
    simple_uart_config(RTS_PIN_NUMBER, TX_PIN_NUMBER,
                        CTS_PIN_NUMBER, RX_PIN_NUMBER,
                        HWFC);

    nrf_delay_ms(1);
    INIT_LOG();
}
Example #6
0
int main()
{
	INIT_LOG(NULL, LOG_CONSOLE, "test.log", 10);
	FileServer file_server;
	file_server.start("127.0.0.1", 8808, new FileService);

	while (1)
	{
		sleep(5);
	}

    return 0;
}
Example #7
0
int main(int argc, char *argv[]) {
    int i = 0;
    BOOT_OK("This is ok:%s", "we'll continue");
    BOOT_OK("This is ok:%s", "This is a very long message which will extended the limit of the screen");
    INIT_LOG("./log", "test.log", LOG_LEVEL_ALL);
    BOOT_OK("initialize log file");

    srand(time(NULL));
    while (1) {
        log_write(rand() % (LOG_LEVEL_DEBUG + 1), 
            "[%s:%d]%s:%d", __FILE__, __LINE__,
            "Just a test log", i++);
    }

    exit(0);
}
int main( int argc, char *argv[] ) {

  char sectype_code = '_';
  MarFS_SecType marfs_sectype;
  char compType_code = '_';
  MarFS_CompType marfs_comptype;
  char comptype_code = '_';
  MarFS_CorrectType marfs_correcttype;
  char code;
  int ret_val;
  MarFS_Namespace_Ptr namespacePtr;
  MarFS_Repo_Ptr repoPtr;


  INIT_LOG();
  fprintf( stdout, "\n" );

  if (read_configuration()) {
    fprintf( stderr, "ERROR: Reading MarFS configuration failed.\n" );
    return 1;
  }
  fprintf( stdout, "CORRECT: The members of the MarFS config structure are:\n" );
  fprintf( stdout, "\tconfig name            : %s\n", marfs_config->name );
  fprintf( stdout, "\tconfig version         : %d.%d\n", marfs_config->version_major, marfs_config->version_minor );
  fprintf( stdout, "\tconfig mnt-top          : %s\n", marfs_config->mnt_top );
  // fprintf( stdout, "\tconfig namespace count : %lu\n", marfs_config->namespace_count );
  fprintf( stdout, "\n" );

  ret_val = free_configuration();
  if ( ! ret_val ) {
     fprintf( stdout, "CORRECT: free_configuration returned %d\n", ret_val );
     if ( marfs_config == NULL ) {
        fprintf( stdout, "CORRECT: We freed the MarFS configuration and it is now NULL.\n" );
     } else {
        fprintf( stderr, "ERROR: free_configuration did not set the MarFS configuration to NULL.\n" );
     }
  } else {
    fprintf( stderr, "ERROR: free_configuration returned %d\n", ret_val );
  }
  fprintf( stdout, "\n" );


  fprintf( stdout, "Re-reading the configuration to continue testing...\n" );
  read_configuration(); 
  if ( marfs_config == NULL ) {
    fprintf( stderr, "ERROR: Reading MarFS configuration failed.\n" );
    return 1;
  }
  fprintf( stdout, "\n" );


  if ( lookup_sectype( "none", &marfs_sectype )) {
    fprintf( stderr, "ERROR: Invalid sectype value of \"%s\".\n", "none" );
  } else {
    fprintf( stdout, "CORRECT: SecType value of \"%s\" translates to %d.\n", "none", marfs_sectype );
  }

  if ( encode_sectype( SECTYPE_NONE, &code )) {
    fprintf( stderr, "ERROR: Invalid enumeration value of %d.\n", SECTYPE_NONE );
  } else {
    fprintf( stdout, "CORRECT: Encode value of %d is \"%c\".\n", SECTYPE_NONE, code );
  }

  if ( decode_sectype( '_', &marfs_sectype )) {
    fprintf( stderr, "ERROR: Invalid code of \"%c\".\n", '_' );
  } else {
    fprintf( stdout, "CORRECT: Decode code of \"%c\" is %d.\n", '_',marfs_sectype ); 
  }

  fprintf( stdout, "\n" );

  if ( lookup_comptype( "none", &marfs_comptype )) {
    fprintf( stderr, "ERROR: Invalid comptype value of \"%s\".\n", "none" );
  } else {
    fprintf( stdout, "CORRECT: CompType value of \"%s\" translates to %d.\n", "none", marfs_comptype );
  }

  if ( encode_comptype( COMPTYPE_NONE, &code )) {
    fprintf( stderr, "ERROR: Invalid enumeration value of %d.\n", COMPTYPE_NONE );
  } else {
    fprintf( stdout, "CORRECT: Encode value of %d is \"%c\".\n", COMPTYPE_NONE, code );
  }

  if ( decode_comptype( '_', &marfs_comptype )) {
    fprintf( stderr, "ERROR: Invalid code of \"%c\".\n", '_' );
  } else {
    fprintf( stdout, "CORRECT: Decode code of \"%c\" is %d.\n", '_',marfs_comptype ); 
  }

  fprintf( stdout, "\n" );

  if ( lookup_correcttype( "none", &marfs_correcttype )) {
    fprintf( stderr, "ERROR: Invalid correcttype value of \"%s\".\n", "none" );
  } else {
    fprintf( stdout, "CORRECT: CorrectType value of \"%s\" translates to %d.\n", "none", marfs_correcttype );
  }

  if ( encode_correcttype( CORRECTTYPE_NONE, &code )) {
    fprintf( stderr, "ERROR: Invalid enumeration value of %d.\n", CORRECTTYPE_NONE );
  } else {
    fprintf( stdout, "CORRECT: Encode value of %d is \"%c\".\n", CORRECTTYPE_NONE, code );
  }

  if ( decode_correcttype( '_', &marfs_correcttype )) {
    fprintf( stderr, "ERROR: Invalid code of \"%c\".\n", '_' );
  } else {
    fprintf( stdout, "CORRECT: Decode code of \"%c\" is %d.\n", '_',marfs_correcttype ); 
  }
  fprintf( stdout, "\n" );


  namespacePtr = find_namespace_by_name( "BoGuS" );
  if ( namespacePtr == NULL ) {
    fprintf( stdout, "CORRECT: Namespace \"BoGuS\" does not exist.\n" );
  } else {
    fprintf( stderr, "ERROR: Namespace \"BoGuS\" does not exist and was found.\n" );
  }
  fprintf( stdout, "\n" );

  namespacePtr = find_namespace_by_name( "s3" );
  if ( namespacePtr != NULL ) {
    fprintf( stdout, "CORRECT: Namespace \"s3\" does exist and has mnt_path \"%s\".\n", namespacePtr->mnt_path );
  } else {
    fprintf( stderr, "ERROR: Namespace \"s3\" does exist and was not found.\n" );
  }
  fprintf( stdout, "\n" );


  namespacePtr = find_namespace_by_mnt_path( "/BoGuS" );
  if ( namespacePtr == NULL ) {
    fprintf( stdout, "CORRECT: Mntpath \"/BoGuS\" does not exist.\n" );
  } else {
    fprintf( stderr, "ERROR: Mntpath \"/BoGuS\" does not exist and was found.\n" );
  }
  fprintf( stdout, "\n" );


  namespacePtr = find_namespace_by_mnt_path( "/s3" );
  if ( namespacePtr != NULL ) {
    fprintf( stdout, "CORRECT: Mntpath \"/s3\" does exist and has name \"%s\".\n", namespacePtr->name );
  } else {
    fprintf( stderr, "ERROR: Mntpath \"/s3\" does exist and was not found.\n" );
  }

  repoPtr = find_repo_by_range( namespacePtr, 38 );
  if ( repoPtr != NULL ) {
    fprintf( stdout, "CORRECT: Namespace \"%s\" has a repo \"%s\" for files of size 38.\n",
			namespacePtr->name,
			repoPtr->name );
  } else {
    fprintf( stderr, "ERROR: Namespace \"%s\" should have a repo for files of size 38.\n",
			namespacePtr->name );
  }
  fprintf( stdout, "\n" );

  namespacePtr = find_namespace_by_mnt_path( "/" );
  if ( namespacePtr != NULL ) {
    fprintf( stdout, "CORRECT: Mntpath \"/\" does exist and has name \"%s\".\n", namespacePtr->name );
  } else {
    fprintf( stderr, "ERROR: Mntpath \"/\" does exist and was not found.\n" );
  }
  fprintf( stdout, "\n" );



/*
 * Since the file_size argument is size_t, that is unsigned and negative numbers
 * are not allowed.
 *
  fprintf( stdout, "\n" );

  repoPtr = find_repo_by_range( namespacePtr, -2 );
  if ( repoPtr == NULL ) {
    fprintf( stdout, "CORRECT: Namespace \"%s\" should not have a repo for files of size -2.\n",
			namespacePtr->name );
  } else {
    fprintf( stderr, "ERROR: Namespace \"%s\" incorrectly has a repo \"%s\" for files of size -2.\n",
			namespacePtr->name,
                        repoPtr->repo_name );
  }
 */

  fprintf( stdout, "\n" );

  repoPtr = find_repo_by_range( NULL, 38 );
  if ( repoPtr == NULL ) {
    fprintf( stdout, "CORRECT: A NULL namespace should not have a repo for files of size 38.\n" );
  } else {
    fprintf( stderr, "ERROR: A NULL namespace incorrectly has a repo \"%s\" for files of size 38.\n",
			repoPtr->name );
  }

  fprintf( stdout, "\n" );

  repoPtr = find_repo_by_name( "BoGuS" );
  if ( repoPtr == NULL ) {
    fprintf( stdout, "CORRECT: Repo name \"BoGuS\" does not exist.\n" );
  } else {
    fprintf( stderr, "ERROR: Repo name \"BoGuS\" does not exist and was found.\n" );
  }

  fprintf( stdout, "\n" );

  repoPtr = find_repo_by_name( "emcS3_00" );
  if ( repoPtr != NULL ) {
    fprintf( stdout, "CORRECT: Repo name \"emcS3_00\" does exist and has host \"%s\".\n", repoPtr->host );
  } else {
    fprintf( stderr, "ERROR: Repo name \"emcS3_00\" does exist and was not found.\n" );
  }
  fprintf( stdout, "\n" );

  // --- show contents of all repos
  RepoIterator rit = repo_iterator();
  while (( repoPtr = repo_next( &rit )) != NULL ) {
     debug_repo(repoPtr);
     fprintf(stdout, "\n");
  }
  fprintf(stdout, "\n");

  // --- show contents of all namespaces
  NSIterator nit = namespace_iterator();
  while (( namespacePtr = namespace_next( &nit )) != NULL ) {
     debug_namespace(namespacePtr);
     fprintf(stdout, "\n");
  }
  fprintf( stdout, "\n" );


  return 0;
}
Example #9
0
int loServiceCreate(loService **result, const loDriver *drv, unsigned tagcount)
{
    int rv = 0;
    size_t size;
    loService *se;

    if (!result) return EINVAL;
    *result = 0;
    if (!drv || 0 >= tagcount || 0 >= ++tagcount) return EINVAL;

    UL_DEBUG((LOGID, "structs: tE=%u tA=%u tD=%u tV=%u tS=%u tP=%u",
              sizeof(loTagEntry), sizeof(loTagAttrib), sizeof(loTagDetail),
              sizeof(loTagValue), sizeof(loTagState), sizeof(loTagPair)));

    size = sizeof(loService) +
           (sizeof(loTagEntry) + sizeof(loTagValue) + sizeof(lo_hash)) * tagcount;
    UL_TRACE((LOGID, "loCreate(%u) requested size = %u", tagcount - 1, size));

    se = (loService*)mallocX(size);
    if (!se)
    {
        UL_ERROR((LOGID, "loCreate(%u) requested size = %ud FAILED", tagcount, size));
        return ENOMEM;
    }
    se->iam = se;
    se->servlist = 0;
    se->serv_key = 0;
    se->shutdown = 0;

    se->initphase = 0;
    se->tag_count = 0;
    se->firstfree = 1; /* first entry is not used */
    se->lastused  = 0;
    se->lastnamed = 0;

    se->proplist = 0;
    se->proplist_count = 0;

    se->driver = *drv;

    se->cactx.ca_se = se;
    se->cactx.ca_se_arg = se->driver.ldDriverArg;
    se->cactx.ca_cli = 0;
    se->cactx.ca_cli_arg = 0;

    se->ts_prim = se->ts_sec = 0;
    se->ts_size = 0;

    se->log = 0;
#if 0 <= USE_LOG
    if (!lolog)
    {
        lolog = (unilog*)(se->log = INIT_LOG());
        UL_INFO((LOGID, "UNILOG initialization missed..."));
        UL_TRACE((LOGID, "loCreate(%u) requested size = %u", tagcount - 1, size));
    }
#endif

    se->ts_prim = se->ts_sec = (FILETIME*)mallocX(2 * sizeof(FILETIME));
    if (!se->ts_prim)
    {
        rv = ENOMEM;
        UL_ERROR((LOGID, "ts_prim init() FAILED"));
        goto Fail;
    }
    memset(se->ts_prim, 0, 2 * sizeof(FILETIME));
    se->ts_size = 1;

    if (rv = lo_proplist_init(se))
    {
        UL_ERROR((LOGID, "lo_proplist_init() FAILED"));
        goto Fail;
    }

    lo_setup_clock();
    if (se->driver.ldRefreshRate < 1)
    {
        se->driver.ldRefreshRate = lo_default_timegran(
                                       se->driver.ldRefreshRate_min < 1 ?
                                       &se->driver.ldRefreshRate_min : 0);
        if (se->driver.ldRefreshRate/*_min*/ < 1)
            se->driver.ldRefreshRate/*_min*/ = 16;
    }

    if (se->driver.ldRefreshRate_min < se->driver.ldRefreshRate)
        se->driver.ldRefreshRate_min = se->driver.ldRefreshRate;

    if (se->driver.ldQueueMax < 1) se->driver.ldQueueMax = 4; /* DEFAULT */

    if ((se->driver.ldFlags & loDf_EE_SFALSE) == loDf_EE_SFALSE)
        se->driver.ldFlags &= ~loDf_EE_SFALSE;

    se->wstrcmp = (se->driver.ldFlags & loDF_IGNCASE)? _wcsicmp: wcscmp;
    se->wstrncmp = (se->driver.ldFlags & loDF_IGNCASE)? _wcsnicmp: wcsncmp;
    se->wstrhash = (se->driver.ldFlags & loDF_IGNCASE)? lo_wcsihash: lo_wcshash;
#if 0
    se->wstrnhash = (se->driver.ldFlags & loDF_IGNCASE)? lo_wcsnihash: lo_wcsnhash;
#endif

    if (!se->driver.ldCurrentTime) se->driver.ldCurrentTime = ld_current_time;

    if (!se->driver.ldBranchSep ||
            0 >= mbtowc(&se->branch_sep, &se->driver.ldBranchSep, 1)) se->branch_sep = 0;
    UL_TRACE((LOGID, "Branch Separator = \\x%02X <%lc>\\x%02X",
              se->driver.ldBranchSep, se->branch_sep, se->branch_sep));

    se->tags = (loTagEntry*)(&se[1]);
    loTagEntry_init(se->tags, tagcount);
    se->secondary = (loTagValue*)(&se->tags[tagcount]);
    loTagValue_init(se->secondary, tagcount);
    se->tag_count = tagcount;
    se->name_hash = (lo_hash*)(&se->secondary[tagcount]);
    memset(se->name_hash, 0, sizeof(lo_hash) * tagcount);
    /* we assume VT_EMPTY === 0 */
    se->sec_trid = se->prim_trid = 0;
    /* se->prim_changed = 0; */

    se->tags[0].attr.taDetail = (loTagDetail*)mallocX(sizeof(loTagDetail));
    if (!se->tags[0].attr.taDetail)
    {
        UL_ERROR((LOGID, "loCreate(%u) taDetail FAILED", tagcount));
        rv = ENOMEM;
        goto Fail;
    }
    loTagDetail_init(se->tags[0].attr.taDetail);
    se->tags[0].attr.taFlags = loTt_DETAILS | loTF_EMPTY;
    se->tags[0].attr.taDetail->tdName[0] = 0;
    se->tags[0].attr.taRangecent = 0.0;

    if (rv = lw_rwlock_init(&se->lkMgmt, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkMgmt FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKMGMT;

    if (rv = lw_rwlock_init(&se->lkPrim, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkPrim FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKPRIM;

    if (rv = lw_mutex_init(&se->lkList, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkList FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKLIST;

    if (rv = lw_mutex_init(&se->lkDr, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkDr FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKDR;

    if (rv = lw_condb_init(&se->lkTridWait, 0))
    {
        UL_ERROR((LOGID, "loCreate()::lkTridWait FAILED"));
        goto Fail;
    }
    se->initphase |= ifTRWAIT;

    if (rv = loThrControl_init(&se->update_pipe))
    {
        UL_ERROR((LOGID, "loCreate()::loThr_init FAILED"));
        goto Fail;
    }
    se->initphase |= ifLKSEC;

    if (rv = loThrControl_start(&se->update_pipe, 0, loUpdatePipe, se))
    {
        UL_ERROR((LOGID, "loCreate()::loThr_start FAILED"));
        goto Fail;
    }

    se->cform_dataonly = RegisterClipboardFormat("OPCSTMFORMATDATA");
    se->cform_datatime = RegisterClipboardFormat("OPCSTMFORMATDATATIME");
    se->cform_writecompl = RegisterClipboardFormat("OPCSTMFORMATWRITECOMPLETE");

    *result = se;
    return 0;
Fail:
    UL_WARNING((LOGID, "%!e loCreate(%u) failed", rv, tagcount));
    loServiceDestroy(se);
    return rv;
}