//Sample code file: var/ndk/webBuildengine/tmp/viewable_samples/7dc83345-68a3-4f0f-9806-411aabc6b121/NCSHARN.C

//Warning: This code has been marked up for HTML

//*++======================================================================

// Program Name:

//

//

// File Name:        ncsharn.c

//

// Version:

//

// Author:

//

// Abstract:

//

// Notes:

//

// Revision History:

//

// Copyright (C) 2001  Novell, Inc.  All Rights Reserved.

//

// Program Name: Test Harness

// Copyright (C) 1999-2002 Novell, Inc. All Rights Reserved. 

// THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.

// USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT 

// ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK. 

// PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A 

// ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS

// PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET, 

// DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S 

// PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S 

// CUSTOMERS WITH RESPECT TO THIS CODE. 

//

//=====================================================================--*/


// This activates CSS lock and callback code for NW6 ring 0 only.


class='cKeyword'>#define RING0   0


class='cKeyword'>#include <stdio.h>
class='cKeyword'>#include <string.h>
class='cKeyword'>#include <ncssdk.h>
class='cKeyword'>#include <nwthread.h>

/* Convert Unicode to Local                                                   */
int NWUnicodeToLocal(        
   void      *ruleHandle,      /* Rule table handle                  */
   class='cKeyword'>char      *dest,         /* Buffer for resulting Unicode       */
   size_t   maxLen,         /* Size of results buffer             */
   UINT16   *src,         /* Buffer with source local code      */
   class='cKeyword'>char      noMap,         /* No map character                   */
   size_t   *len         /* Number of unicode chars in output  */
);

/* Convert local to Unicode                                                   */
int NWLocalToUnicode(  
   void      *ruleHandle,         /* Rule table handle                  */
   UINT16   *dest,               /* Buffer for resulting Unicode       */
   size_t   maxLen,              /* Size of results buffer             */
   class='cKeyword'>char      *src,                /* Buffer with source local code      */
   UINT16   noMap,               /* No map character                   */
   size_t   *len               /* Number of unicode chars in output  */
);

class='cKeyword'>char *unitoloc( UINT16 *uStr);
UINT16 *loctouni( class='cKeyword'>char *aStr);


class='cKeyword'>#define SINT32 int

UINT32            NLMHandle, crmToggle, cssToggle;

NCS_HANDLE         sdkHandle;
UINT32             myGroupID;

NCS_RESOURCE      *resArray[ 10], *pRes;
UINT8               curResource[ 64];
UINT8               CSSKey[ 64];
UINT32             PageSize, NumPages, PageNum;
UINT32            numRess;

NCS_POOL_INFO      *pPool;
NCS_VOLUME_INFO   *aVol;
UINT32            numPools;
UINT32            IsNW6;

UINT8             bigBuff[ sizeof( NCS_POOL_INFO) * 5 ];
UINT8               bigBuff2[  4 * sizeof( NCS_VOLUME_INFO)];
UINT8               littleBuffs[3][ 2000];
int               thisResource;

void sdkHarnLoop( UINT32 threadnum, void *params);
void GetString( UINT8 *aString);
void AnyKey( void);
SINT32 atoi( UINT8 *aStr);

void myEpochCback( IN NCS_HANDLE Handle, IN UINT32 GroupEpoch, 
   IN UINT32 Members );

UINT32 myCrmCback(NCS_MAPI, NCS_RESOURCE *,  void * cxt);



int main(class='cKeyword'>char *argv[], int argc){
   cssToggle = FALSE;
   crmToggle = FALSE;
   sdkHandle = FALSE;
   pRes = NULL;
   numRess = 0;
   numPools = 0;
   CSSKey[0] = 0;
   myGroupID = GetThreadGroupID();
   sdkHarnLoop( NULL, NULL);
   return 0;
}


void sdkHarnLoop( UINT32 threadnum, void *params){
   UINT32 waitCount =0, done =FALSE;
   UINT32 retVal, tempUI, nodeArray[32], ipArray[32], retVal2;
   UINT8 tempIO[ 10], tBuff[ 80];
   BYTE kVal;
   
   int i, j;

   thisResource = -1;
   retVal = NCS_Register( myCrmCback, (unsigned class='cKeyword'>char*)"ClusterSDK", myEpochCback, NULL,
      NULL, &sdkHandle);
   if( sdkHandle == NULL){
      done = TRUE;
   }
   while( !done & waitCount < 1800){
      printf(  "\r\n\r\nClustering SDK Test Harness\r\n");
      printf(  "1. Cluster IP                   J. Find VirtualServer\r\n");
      printf(  "2. Is NW6                       K. Update Resource\r\n");
      printf(  "3. Toggle CRM callback %s      L. \r\n", ((crmToggle)?"OFF" : "ON "));
      printf(  "4. Toggle CSS callbacks %s     M. CSS Query Epoch\r\n", ((cssToggle)?"OFF" : "ON "));
      printf(  "5. List Nodes                   N. Rebuild Database\r\n");
      printf(  "6. List Resources               O. Set Maintenance mode\r\n");
      printf(  "7. Find Volume                  P. Get Maintenance mode\r\n");
      printf(  "8. Display a Resource           Q. \r\n");
      printf(  "9. Offline Resource             R. Revision\r\n");
      printf(  "A. Online Resource              S. Cluster Name\r\n");
      printf(  "B. Migrate Resource             T. This NodeNumber & IP\r\n");
      printf(  "C. List Pools                   U. Find Any String\r\n");
      printf(  "D. Show Pool                    V. Resource State\r\n");
      printf(  "E. Is Virtual Server            W. Node Num to Name\r\n");
      printf(  "F. Add Resource Filter          X.\r\n"); 
      printf(  "G. Remove Resource Filter       Y. Cluster Down\r\n");
      printf(  "H. Cluster Join                 Z. \r\n");
      printf(  "I. Cluster Leave                |  Quit.\r\n");
      printf(  "Enter option & CR :");
      if( 1 ){
         kVal = 0;
         gets( (class='cKeyword'>char*)tBuff);
         kVal = tBuff[0];
         switch( kVal){
         class='cKeyword'>case '1':
            retVal = NCS_ClusterIPAddress( sdkHandle, (UINT32 *)tempIO);
            if( retVal == 0){
               printf(  "\r\nIPaddress= %d.%d.%d.%d\r\n", 
                  tempIO[0], tempIO[1], tempIO[2], tempIO[3]);
            }else{
               printf(  "\r\nError =%d \r\n", retVal);
            }
            AnyKey();
            continue;
         class='cKeyword'>case '2':

// Several of the API's need this flag set, so do this on startup in your code


            retVal = NCS_IsNW6orHigher( sdkHandle );
            printf( "\r\nRetval=%d \r\n", retVal);
            if( retVal != NCS_NOT_SUPPORTED){
               IsNW6 = retVal;
            }else{
               IsNW6 = 0;
            }
            AnyKey();
            continue;
         class='cKeyword'>case '3':
            crmToggle = 1 - crmToggle;
            continue;
         class='cKeyword'>case '4':
            cssToggle = 1 - cssToggle;
            continue;
         class='cKeyword'>case '5':      // list nodes

            retVal = NCS_ListNodes( sdkHandle,  nodeArray, ipArray );
            if( retVal == 0){
               for( i = 0; i < MAX_NODES; i++){
                  if( nodeArray[ i] != -1){
                     memcpy( tempIO, &ipArray[i], 4);
                     retVal = NCS_NodeNumToName( sdkHandle,  nodeArray[i], tBuff );
                     printf(  "ret=%d offset=%d Num=%d IP=%d.%d.%d.%d Name=%s\r\n",
                        retVal, i, nodeArray[i], tempIO[0], tempIO[1], tempIO[2], tempIO[3], tBuff);
                  }
               }   
            }else{
               printf(  "\r\nError =%d \r\n", retVal);
            }
            AnyKey();
            continue;
         class='cKeyword'>case '6':      // list resources

            pRes = NULL;
            thisResource = -1;
            retVal = NCS_NumberResources( sdkHandle, &numRess);
            
            if( numRess > 10){
               numRess = 10;
            }
            j = 0;
            numPools = 0;
            for( i=0; i < 10; i++){
               resArray[i] = (NCS_RESOURCE *)&bigBuff[j];
               j += sizeof( NCS_RESOURCE);
               if( j > sizeof( bigBuff)){
                  numRess = i;
                  i = 1000;
               }
            }
            retVal = NCS_ListResources( sdkHandle, &numRess, 
               resArray );
            if( retVal == 0 || retVal == NCS_ALLOC_ERROR){
               for( i=0; i < numRess; i++){
                  printf(  "\r\nRes %d == %s ", i+1, resArray[i]->name);
               }
            }else{
               printf(  "\r\nError =%d \r\n", retVal);
            }
            AnyKey();
            continue;
         class='cKeyword'>case '7':
         class='cKeyword'>case 'u':
         class='cKeyword'>case 'U':
            numRess = 0;
            resArray[0] = (NCS_RESOURCE *)bigBuff;
            printf(  "Enter String: ");
            GetString( tBuff);
            j = strlen( (const class='cKeyword'>char *)tBuff);
            if( j > 0 ){
               if( tBuff[ j-1] == 10 || tBuff[ j-1] == 13){
                  tBuff[ j-1] = 0;
                  j--;
               }

               printf( "Findbuff=>>%s<< len=%d res=%x hand=%x\r\n", tBuff, j, resArray[0], sdkHandle);
               retVal = NCS_FindResource( sdkHandle, tBuff, 
                  (kVal == '7' ? FALSE : TRUE ), resArray[0]);
               if( retVal == NCS_RESOURCE_FOUND){
                  pRes = resArray[0];
                  printf(  "\r\nFound %s \r\n", pRes->name);
                  thisResource = 0;
                  numRess = 1;
               }else{
                  printf( "\r\nRet=%d\r\n", retVal);
               }
            }
            AnyKey();
            continue;
         class='cKeyword'>case '8':
            printf(  "\r\nEnter number of resource to display: ");
            GetString( tBuff);
            i = atoi( tBuff);
            if( i > 0){
               i--;
            }
            if( i < numRess){
               thisResource = i;
               pRes = resArray[ i];
               pRes->loadScript = littleBuffs[0];
               pRes->unloadScript = littleBuffs[1];
            
               retVal = NCS_ReadResource( sdkHandle,  pRes, 2000);
               if( retVal == 0){
                  printf(  "\r\n%s  loadwait=%d unloadwait=%d failover=%x\r\n", 
                     pRes->name, pRes->loadWait, pRes->unloadWait, pRes->failOver);
                  printf(  " Failback=%d ignore=%d revision=%d preferred=%d %d %d %d %d %d\r\n",
                     pRes->failBack, pRes->ignore_quorum, pRes->revision, 
                     pRes->fail_order[ 0], pRes->fail_order[ 1], pRes->fail_order[ 2],
                     pRes->fail_order[ 3], pRes->fail_order[ 4], pRes->fail_order[ 5]);
                  AnyKey();
                  printf(  " %s\r\n%s\r\n",
                     pRes->loadScript , pRes->unloadScript);
                              
               }else{
                  printf(  "\r\nError =%d \r\n", retVal);
               }
            }
            AnyKey();
         
            continue;
         class='cKeyword'>case '9':      // offline

            if( pRes != NULL && numRess != 0){
               retVal = NCS_ResourceControl( sdkHandle, NCS_MAPI_OFFLINE,
                  pRes, NULL);
            }
            continue;
         class='cKeyword'>case 'a':      // online

         class='cKeyword'>case 'A':
            if( pRes != NULL && numRess != 0){
// WARNING! Make sure to read the resource state before doing an online so as

// to get the current revision. Otherwise the resource will get stuck in NDS_SYNCH

// state!!!


               pRes->fromTo = -1;  // can be the new node number. -1 means most preferred node

               retVal = NCS_ResourceControl( sdkHandle, NCS_MAPI_ONLINE,
                  pRes, NULL);
            }
            continue;
         class='cKeyword'>case 'b':
         class='cKeyword'>case 'B':
            if( pRes != NULL && numRess != 0){
               printf( "\r\nEnter Node Number: ");
               GetString( tBuff);
               j = atoi( tBuff);
               pRes->fromTo = j;
               retVal = NCS_ResourceControl( sdkHandle, NCS_MAPI_MIGRATE,
                  pRes, NULL);
            }
            continue;
         class='cKeyword'>case 'c':
         class='cKeyword'>case 'C':
            numRess = 0;
            pRes = NULL;
            thisResource = -1;
            retVal = NCS_NumPools( sdkHandle, &numPools);
            printf( "\r\nRetVal = %d Total Pools=%d \r\n", retVal, numPools);            
            if( retVal == 0 && numPools != 0){
               memset( bigBuff,0, sizeof( bigBuff));
               numPools = 5;
               pPool = (NCS_POOL_INFO *)bigBuff;
               retVal = NCS_WherePools( sdkHandle, &numPools, pPool); 
               if( retVal == 0 && numPools != 0){
                  pPool = (NCS_POOL_INFO *)bigBuff;
                  for( i=0; i < numPools; i++){
                     memcpy( &tempIO, &pPool->ResourceIP, 4);
                     printf(  "\r\n %d Pool %s - Resource %s numvols %d node %d IP=%d.%d.%d.%d ",
                        i +1, pPool->PoolName, pPool->ResName, pPool->numVols, pPool->WhichNode,
                        tempIO[0], tempIO[1], tempIO[2], tempIO[3]);
                     pPool++;
                  }
               }else{
                  printf( "Wherepool=%d\r\n", retVal);
               }
            }else{
               printf( "Error=%d\r\n", retVal);
            }
            AnyKey();
            continue;

         class='cKeyword'>case 'd':
         class='cKeyword'>case 'D':
            if( numPools != 0 && IsNW6){
               printf( "\r\nEnter Pool Number: ");
               GetString( tBuff);
               j = atoi( tBuff);
               if( j >=0 && j <= numPools){
                  j--;
                  pPool = (NCS_POOL_INFO *)bigBuff;
                  while( j > 0){
                     pPool++;
                     j--;
                  }
                  j = pPool->numVols;
                  if( j > 0){
                     memset( bigBuff2, 0, sizeof( bigBuff2));
                     pPool->volArray = (NCS_VOLUME_INFO *)bigBuff2;
                  
                     retVal = NCS_WhatVolumes( sdkHandle, pPool); 
                     if( retVal == 0){
                        printf( "\r\n Pool=%s\r\n", pPool->PoolName);
                        for( i=0; i < pPool->numVols; i++){
                           printf(  "\r\n %d Vol %s",
                              i+1, pPool->volArray[i].VolName);
                        }
                     }
                  }            
               }   
            }
            AnyKey();
            continue;

         class='cKeyword'>case 'e':
         class='cKeyword'>case 'E':
            printf(  "\r\nEnter Name of Server: ");
            GetString( tBuff);
            printf( ">>%s<<\r\n", tBuff);
            retVal = NCS_IsVirtualServer( sdkHandle, tBuff);
            printf(  " is %d \r\n", retVal);
            AnyKey();
            continue;

         class='cKeyword'>case 'f':      // Add resource filter

         class='cKeyword'>case 'F':
            printf(  "\r\nCase Sensitive Resource name add:");
            GetString( tBuff);

            retVal = NCS_FilterChange( sdkHandle, tBuff, TRUE);
            printf(  " is %d \r\n", retVal);
            AnyKey();
            
            continue;

         class='cKeyword'>case 'g':      // remove resource filter

         class='cKeyword'>case 'G':
            printf(  "\r\nCase Sensitive Resource name del:");
            GetString( tBuff);

            retVal = NCS_FilterChange( sdkHandle, tBuff, FALSE);
            printf(  " is %d \r\n", retVal);
            AnyKey();
            continue;

         class='cKeyword'>case 'h':      // cluster join

         class='cKeyword'>case 'H':
            retVal = NCS_ClusterJoin( sdkHandle);
            continue;

         class='cKeyword'>case 'i':      // cluster leave

         class='cKeyword'>case 'I':
            retVal = NCS_ClusterLeave( sdkHandle );
            continue;

         class='cKeyword'>case 'j':
         class='cKeyword'>case 'J':
            printf( "\r\nVolume Name:");
            GetString( tBuff);
            memset( bigBuff, 0, sizeof( NCS_POOL_INFO));
            retVal = NCS_FindVirtualServer( sdkHandle, tBuff, (NCS_POOL_INFO *)bigBuff);
            if( retVal == 0){
               pPool = (NCS_POOL_INFO *) bigBuff;
               memcpy( curResource, &pPool->ResourceIP, 4);
               printf( "\r\nIP=%d:%d:%d:%d VirtName=%s ", curResource[0], curResource[1], curResource[2],
                  curResource[3], unitoloc( pPool->VirtServFDN));
               printf( "\r\nPoolName=%s ", unitoloc( pPool->PoolFDN));
               printf( "\r\nRes Name=%s %s ", unitoloc( pPool->ResFDN), pPool->ResName);
            }else{
               printf(  " ret=%d \r\n", retVal);
            }
            AnyKey();
            continue;

// This is just a sample of what can be done. Spice to taste. Scripts can also

// be modified.


         class='cKeyword'>case 'k':
         class='cKeyword'>case 'K':
            if( thisResource < 0){
               printf( "\r\nSelect a Resource first\r\n");
               AnyKey();
               continue;
            }
            printf( "\r\nFor Resource %s, enter new load Timeout (%d):",
               pRes->name, pRes->loadWait);
            GetString( tBuff);
            pRes->loadWait = atoi( tBuff);
            
            retVal = NCS_UpdateResource( sdkHandle, pRes);
            printf( " ret=%d\r\n", retVal );
            AnyKey();
            continue;
         class='cKeyword'>case 'm':
         class='cKeyword'>case 'M':
            retVal = NCS_Query_Epoch( sdkHandle, &retVal2, &tempUI);
            if( retVal == 0){
               printf(  "\r\n Epoch %d Members %x\r\n",
                  retVal2, tempUI);
               
            }else{
               printf(  " ret=%d \r\n", retVal);
            }
            AnyKey();
            continue;
         class='cKeyword'>case 'n':
         class='cKeyword'>case 'N':
            retVal = NCS_Rebuild_Database( sdkHandle);
            printf(  " ret=%d \r\n", retVal);
            AnyKey();
            continue;
         class='cKeyword'>case 'o':
         class='cKeyword'>case 'O':      // set Maint mode on or off

            printf( "\r\nSet Maint Mode to :");
            GetString( tBuff);
            tempUI = atoi( tBuff);   
            retVal = NCS_MaintenanceMode( sdkHandle, 1, (int*)&tempUI);
            printf(  " ret=%d \r\n", retVal);
            AnyKey();
            continue;
         class='cKeyword'>case 'p':
         class='cKeyword'>case 'P':      // get Maint mode

            retVal = NCS_MaintenanceMode( sdkHandle, 0, (int*) &tempUI);
            printf(  " ret=%d mode =%d \r\n", retVal, tempUI);
            AnyKey();
            continue;

         class='cKeyword'>case 'r':
         class='cKeyword'>case 'R':
            retVal = NCS_Revision( sdkHandle, &tempUI );
            if( retVal == 0){
               printf(  "Revision=%d \r\n", tempUI);
            }else{
               printf(  "\r\nError =%d \r\n", retVal);
            }
            AnyKey();
            continue;

         class='cKeyword'>case 's':
         class='cKeyword'>case 'S':
            tempUI = 79;
            retVal = NCS_ClusterName( sdkHandle, tBuff, &tempUI );
            if( retVal == 0){
               printf(  "Name=%s len=%d \r\n", tBuff, tempUI);
            }else{
               printf(  "\r\nError =%d \r\n", retVal);
            }
            AnyKey();
            continue;
         class='cKeyword'>case 't':
         class='cKeyword'>case 'T':
            retVal = NCS_NodeNumber( sdkHandle, &tempUI );

            retVal2 = NCS_MyNodeIPAddress( sdkHandle, (UINT32 *)&tempIO );
            if( retVal == 0 ){
               retVal = NCS_NodeNumToName( sdkHandle, tempUI, tBuff );
               printf(  "Num=%d IP=%d.%d.%d.%d Name=%s\r\n",
                  tempUI, tempIO[0], tempIO[1], tempIO[2], tempIO[3], tBuff);
            }else{
               printf(  "\r\nError =%d, %d \r\n", retVal, retVal2);
            }
            AnyKey();
            continue;

         class='cKeyword'>case 'v':
         class='cKeyword'>case 'V':      // Resource State

            if( pRes != NULL && numRess != 0){
               retVal = NCS_ResourceControl( sdkHandle, NCS_MAPI_STATE,
                  pRes, NULL);
               if( retVal == 0){
                  printf(  "\r\nRes=%s Inc=%d State=%d Alert=%d Loc=%d\r\n",
                     pRes->name, pRes->incarnation, pRes->state, pRes->alert, pRes->location);
   
                  printf(  "FromTo=%d FailCnt=%d \r\n",
                     pRes->fromTo, pRes->res_fail_cnt);
         
               }else{
                  printf(  "\r\nError =%d \r\n", retVal);
               }
            }
            AnyKey();
         
            continue;

         class='cKeyword'>case 'w':
         class='cKeyword'>case 'W':
            printf( "\r\nEnter Node Number: ");
            GetString( tBuff);
            tempUI = atoi( tBuff);
            retVal = NCS_NodeNumToName( sdkHandle, tempUI, tBuff );
            if( retVal == 0){
               printf(  "Num=%d Name=%s\r\n", tempUI, tBuff);
            }else{
               printf(  "\r\nError =%d, %d \r\n", retVal);
            }
            AnyKey();
            continue;

         class='cKeyword'>case 'x':
         class='cKeyword'>case 'X':
            continue;

         class='cKeyword'>case 'y':
         class='cKeyword'>case 'Y':
            retVal = NCS_ClusterDown( sdkHandle );
            continue;

         class='cKeyword'>case 'z':
         class='cKeyword'>case 'Z':
            continue;

         class='cKeyword'>case '|':
            done = TRUE;
            delay( 5000);
            continue;
         }
      }
      waitCount++;
   }
   if( sdkHandle != 0){
      NCS_Deregister( sdkHandle);
   }

}


void GetString( UINT8 *aString){
   gets( (class='cKeyword'>char*)aString);
}

void AnyKey( void){
   UINT32 done =FALSE;
   BYTE kVal;

   printf(  "\r\nCR to Continue");
   while( !done ){
      kVal = 0;
      kVal = getchar();
      done = TRUE;
   }
}

void myEpochCback( IN NCS_HANDLE Handle, IN UINT32 GroupEpoch, 
   IN UINT32 Members ){
   UINT32 oldGroupID;
   if( !cssToggle){
      return;
   }
   oldGroupID = GetThreadGroupID();
   SetThreadGroupID( myGroupID);   

   printf(  "\r\nEpoch Callback =%d Members=%x\r\n",
      GroupEpoch, Members);
   SetThreadGroupID( oldGroupID);   

}

UINT32 myCrmCback(NCS_MAPI crmMapi, NCS_RESOURCE *pRes,  void * cxt){

   UINT32 oldGroupID;

   if( !crmToggle){
      return 0;
   }
   oldGroupID = GetThreadGroupID();
   SetThreadGroupID( myGroupID);   
   
   printf(  "\r\nCRM Callback Res=%s Inc=%d State=%d Alert=%d Loc=%d\r\n",
      pRes->name, pRes->incarnation, pRes->state, pRes->alert, pRes->location);
   
   printf(  "FromTo=%d FailCnt=%d \r\n",
      pRes->fromTo, pRes->res_fail_cnt);
   SetThreadGroupID( oldGroupID);   
   return 0;
}


class='cKeyword'>char *unitoloc( UINT16 *uStr){
   static class='cKeyword'>char aBuff[256];
   UINT32 len;

   memset( aBuff, 0, 256);
   // size_t is nuint32

   NWUnicodeToLocal(NULL, aBuff, 256, uStr, '.', (size_t *)&len);
   return aBuff;

}

UINT16 *loctouni( class='cKeyword'>char *aStr){
   static UINT16 aUni[256];
   UINT32 len;
   
   NWLocalToUnicode(NULL, aUni, sizeof( aUni), aStr, '.', (size_t *)&len);
   return aUni;
}