Exemple #1
0
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
                                         apr_size_t reqsize,
                                         const char *filename,
                                         apr_pool_t *pool)
{
    int rc;
    apr_shm_t *newm = (apr_shm_t *)apr_palloc(pool, sizeof(apr_shm_t));
    char *name = NULL;
    ULONG flags = PAG_COMMIT|PAG_READ|PAG_WRITE;

    newm->pool = pool;

    if (filename) {
        name = apr_pstrcat(pool, "\\SHAREMEM\\", filename, NULL);
    }

    if (name == NULL) {
        flags |= OBJ_GETTABLE;
    }

    rc = DosAllocSharedMem(&(newm->memblock), name, reqsize, flags);

    if (rc) {
        return APR_OS2_STATUS(rc);
    }

    *m = newm;
    return APR_SUCCESS;
}
Exemple #2
0
void clipsrv(void *foo) {
    HAB hab;
    HMQ hmq;
    ULONG Cmd;
    ULONG len;
    char *text;
    void *shmem = "the text";
    
    hab = NULLHANDLE;

    if ((WinOpenClipbrd(hab) == TRUE) &&
        ((text = (char *) WinQueryClipbrdData(hab, CF_TEXT)) != 0))
    {
        DosGetSharedMem(text, PAG_READ);
        len = strlen(text);
        puts(text);
    }
    WinCloseClipbrd(hab);
    
    len = strlen(shmem);
    if (len) {
        DosAllocSharedMem((void **)&text,
                          0,
                          len + 1,
                          PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE);
        strcpy(text, shmem);
    }
    
    if (WinOpenClipbrd(hab) == TRUE) {
        if (!WinSetClipbrdData(hab, (ULONG) text, CF_TEXT, CFI_POINTER))
            DosBeep(100, 1500);
        WinCloseClipbrd(hab);
    }
}
/*---------------------------------------------------------------------------
                                  CmdCopy
---------------------------------------------------------------------------*/
void CmdCopy( WNDATTR *wndattr )
{
 LPELEM *elem;
 ULONG   length;
 void   *text;

   length = 0;
   elem = wndattr->list->nextmk;
   while (elem != wndattr->list) {
      length += strlen( elem->data );
      elem = elem->nextmk;
   }
   if (length == 0)
      return;

   DosAllocSharedMem( &text, NULL, length,
                      PAG_COMMIT | OBJ_GIVEABLE | PAG_WRITE );
   elem = wndattr->list->next;
   while (elem != wndattr->list) {
      if (elem->nextmk != NULL) {
         strcat( text, elem->data );
         strcat( text, "\r\n" );
      };
      elem = elem->next;
   }

   WinOpenClipbrd( wndattr->hab );
   WinSetClipbrdData( wndattr->hab, ( ULONG )text, CF_TEXT, CFI_POINTER );
   WinCloseClipbrd( wndattr->hab );

   return;
}
Exemple #4
0
void put_clipboard (char *s)
{
    int   len, rc;
    char  *mem;

    len = strlen (s);
    if (len == 0) return;

    create_pm ();
    if (WinOpenClipbrd (hab0) == TRUE)
    {
        WinEmptyClipbrd (hab0);
    
        rc = DosAllocSharedMem ((void **)&mem, NULL, len+1,
                                PAG_READ|PAG_WRITE|PAG_COMMIT|OBJ_GIVEABLE);
        if (rc == 0)
        {
            strcpy (mem, s);
            WinSetClipbrdData (hab0, (ULONG)mem, CF_TEXT, CFI_POINTER);
        }
    }
    
    WinCloseClipbrd (hab0);
    destroy_pm ();
}
Exemple #5
0
/*
 * _CopyAllLines - copy lines to clipboard
 */
void _CopyAllLines( LPWDATA w )
{
    LPLDATA     ld;
    ULONG       total;
    unsigned    len;
    char        *data;
    char        *ptr;
    unsigned    slen;
    LONG        rc;

    /*
     * get number of bytes
     */
    total = 0;
    for( ld = w->LineHead; ld != NULL; ld = ld->next ) {
        total += strlen( ld->data ) + 2;
    }
    if( total > MAX_BYTES ) {
        len = (unsigned) MAX_BYTES;
    } else {
        len = total;
    }

    /*
     * get memory block
     */
    rc = PAG_COMMIT | OBJ_GIVEABLE | PAG_WRITE;
    rc = DosAllocSharedMem( (PPVOID)&data, NULL, len + 1, rc );
    if( rc ) {
        _Error( NULLHANDLE, "Copy to Clipboard Error", "Out of Memory" );
        return;
    }

    /*
     * copy data into block
     */
    total = 0;
    ptr = data;
    for( ld = w->LineHead; ld != NULL; ld = ld->next ) {
        slen = strlen( ld->data ) + 2;
        if( total + slen > MAX_BYTES )
            break;
        memcpy( &ptr[total], ld->data, slen - 2 );
        ptr[total + slen - 2] = 0x0d;
        ptr[total + slen - 1] = 0x0a;
        total += slen;
    }
    ptr[total] = 0;

    /*
     * dump data to the clipboard
     */
    if( WinOpenClipbrd( _AnchorBlock ) ) {
        WinEmptyClipbrd( _AnchorBlock );
        WinSetClipbrdData( _AnchorBlock, (ULONG)data, CF_TEXT, CFI_POINTER );
        WinCloseClipbrd( _AnchorBlock );
    }

} /* _CopyAllLines */
Exemple #6
0
void main(void) {
        initFileTable();
        initProcess(0,0);
        initMemory();
        
        APIRET rc;
        PVOID pv;
        rc = DosAllocSharedMem(&pv, "\\SHAREMEM\\Ivan", 8192, PAG_COMMIT|PAG_READ|PAG_WRITE);
        if(rc==0)
                rc = DosFreeMem(pv);
        printf("rc=%d\n",rc);
}
Exemple #7
0
int main (VOID)
{
   PVOID  pvShrObject = NULL;      /* Pointer to shared memory object      */
   PSZ    pszMemName  = "\\SHAREMEM\\MYTOOL\\APPLICAT.DAT"; /* Object name */
   PVOID  pvAltObject = NULL;      /* Alternate pointer to shared memory   */
   APIRET rc          = NO_ERROR;  /* Return code                          */
   ULONG  ulObjSize   = 1024;   /* Size (system rounds to 4096 - page bdy) */

   rc = DosAllocSharedMem(&pvShrObject,   /* Pointer to object pointer     */
                          pszMemName,     /* Name for shared memory        */
                          ulObjSize,      /* Desired size of object        */
                          PAG_COMMIT |    /* Commit memory                 */
                          PAG_WRITE );    /* Allocate memory as read/write */

   if (rc != NO_ERROR) {
      printf("DosAllocSharedMem error:  return code = %u\n",rc);
      return 1;
   }

   strcpy(pvShrObject, "Write your shared application data here.");

      /* Get the address of the shared memory and reference it that way.
         (Done for illustrative purposes only, this is how another process
         would go about accessing the named shared memory.)            */

   rc = DosGetNamedSharedMem(&pvAltObject,  /* Pointer to pointer of object */
                             pszMemName,    /* Name of shared memory        */
                             PAG_READ);     /* Want read-only access        */

   if (rc != NO_ERROR) {
      printf("DosGetNamedSharedMem error:  return code = %u\n",rc);
      return 1;
   }

   printf("Shared data read was \"%s\"\n",pvAltObject);

   rc = DosFreeMem(pvShrObject);

   if (rc != NO_ERROR) {
      printf("DosFreeMem error:  return code = %u\n",rc);
      return 1;
   }

   return NO_ERROR;
}
Exemple #8
0
VOID storeMsg( char *format, ... )
{
    static char buf[ 257 ] = { 0, };
    PVOID msg = NULL;

    va_list arg;

    va_start( arg, format );
    vsprintf( buf, format, arg );
    va_end( arg );

    DosAllocSharedMem( &msg, NULL, strlen( buf ) + 1, fALLOCSHR );
    strcpy( msg, buf );

    WinSendMsg( hwndKHS, KHSM_STOREMSG, ( MPARAM )msg, 0 );

    DosFreeMem( msg );
}
Exemple #9
0
MRESULT khs_wmCreate( HWND hwnd, MPARAM mp1, MPARAM mp2 )
{
    PKHSCD  pkhscd;

    WinSetWindowPtr( hwnd, 0, 0 );

    if( DosAllocMem(( PPVOID )&pkhscd, sizeof( KHSCD ), fALLOC ) != 0 )
        return MRFROMLONG( TRUE );

    if( DosAllocSharedMem(( PPVOID )&pkhscd->pCursorPos, NULL, sizeof( RECTL ), fALLOCSHR ) != 0 )
    {
        DosFreeMem( pkhscd );

        return MRFROMLONG( TRUE );
    }

    if( DosAllocMem(( PPVOID )&pkhscd->pQTopLevel, DOSQSS_BUFSIZE, fALLOC ) != 0 )
    {
        DosFreeMem( pkhscd->pCursorPos );
        DosFreeMem( pkhscd );

        return MRFROMLONG( TRUE );
    }

    pkhscd->list = hwndlistCreate();
    if( pkhscd->list == NULL )
    {
        DosFreeMem( pkhscd->pQTopLevel );
        DosFreeMem( pkhscd->pCursorPos );
        DosFreeMem( pkhscd );

        return MRFROMLONG( TRUE );
    }

#ifdef DEBUG
    pkhscd->fp = fopen("debug.log", "wt");
#endif
    pkhscd->exceptListBuf = exceptCreateListBuf( EXCEPT_LIST_FILE );

    WinSetWindowPtr( hwnd, 0, pkhscd );

    return FALSE;
}
Exemple #10
0
static DDESTRUCT *MakeDDEObject( HWND hwnd, char *item_name,
                                 USHORT fsStatus, USHORT usFormat,
                                 void *data, int data_len )
/****************************************************************/
{
    DDESTRUCT   *dde;
    int         item_len;
    PID         pid;
    TID         tid;

    if( item_name != NULL ) {
        item_len = strlen( item_name ) + 1;
    } else {
        item_len = 1;
    }
    if( !DosAllocSharedMem( (PPVOID)&dde, NULL, sizeof( DDESTRUCT ) +
                            item_len + data_len,
                            PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE ) ) {
        WinQueryWindowProcess( hwnd, &pid, &tid );
        DosGiveSharedMem( (PVOID)&dde, pid, PAG_READ | PAG_WRITE );
        dde->cbData = data_len;
        dde->fsStatus = fsStatus;
        dde->usFormat = usFormat;
        dde->offszItemName = sizeof( DDESTRUCT );
        if( (data_len != 0) && (data != NULL) ) {
            dde->offabData = (USHORT)(sizeof( DDESTRUCT ) + item_len);
        } else {
            dde->offabData = 0;
        }
        if( item_name != NULL ) {
            strcpy( (char *)DDES_PSZITEMNAME( dde ), item_name );
        } else {
            strcpy( (char *)DDES_PSZITEMNAME( dde ), "" );
        }
        if( data != NULL ) {
            memcpy( DDES_PABDATA( dde ), data, data_len );
        }
        return( dde );
    }
    return( NULL );
}
Exemple #11
0
static PDDESTRUCT MakeDDEObject (
   HWND Destination,                    // -> Destination window
   PSZ Item,                            // -> Item name or NULL.
   USHORT Status,                       // Status flags.
   USHORT Format,                       // Data format
   PVOID Data,                          // -> Data or NULL.
   ULONG DataLen                        // Data length in bytes.
) {

   ULONG ItemLen = Item ? strlen(PCHAR(Item))+1 : 1 ;

   PDDESTRUCT pBlock ;
   if ( DosAllocSharedMem ( PPVOID(&pBlock), 0, sizeof(DDESTRUCT) + ItemLen + DataLen,
      PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE ) )
      return ( 0 ) ;

   pBlock->cbData = DataLen ;
   pBlock->fsStatus = Status ;
   pBlock->usFormat = Format ;
   pBlock->offszItemName = sizeof(DDESTRUCT) ;

   if ( DataLen AND Data )
      pBlock->offabData = USHORT ( sizeof(DDESTRUCT) + ItemLen ) ;
   else
      pBlock->offabData = 0 ;

   if ( Item )
      strcpy ( PCHAR(DDES_PSZITEMNAME(pBlock)), PCHAR(Item) ) ;
   else
      strcpy ( PCHAR(DDES_PSZITEMNAME(pBlock)), "" ) ;

   if ( Data )
      memcpy ( DDES_PABDATA(pBlock), Data, size_t(DataLen) ) ;

   PID pid ; TID tid ;
   WinQueryWindowProcess ( Destination, &pid, &tid ) ;
   DosGiveSharedMem( (PVOID)pBlock, pid, PAG_READ | PAG_WRITE) ;

   return ( pBlock ) ;
}
Exemple #12
0
int PutClipText(ClipData *cd) {
    int rc;
    ULONG PostCount;
    char *mem;
    
    rc = DosOpenMutexSem(SEM_PREFIX "CLIPSYN", &hmtxSyn);
    if (rc != 0) return -1;
/*    rc = DosOpenEventSem(SEM_PREFIX "CLIPGET", &hevGet);*/
/*    if (rc != 0) return -1;*/
    rc = DosOpenEventSem(SEM_PREFIX "CLIPPUT", &hevPut);
    if (rc != 0) return -1;
    rc = DosOpenEventSem(SEM_PREFIX "CLIPEND", &hevEnd);
    if (rc != 0) return -1;
    
    DosRequestMutexSem(hmtxSyn, SEM_INDEFINITE_WAIT);
    DosResetEventSem(hevEnd, &PostCount);
    if (0 == DosAllocSharedMem((void **)&mem,
                               MEM_PREFIX "CLIPDATA",
                               cd->fLen + 5,
                               PAG_COMMIT | PAG_READ | PAG_WRITE))
    {
        ULONG L = cd->fLen;
        memcpy((void *)mem, (void *)&L, 4);
        strcpy(mem + 4, cd->fChar);
    }
    DosPostEventSem(hevPut);
    DosWaitEventSem(hevEnd, SEM_INDEFINITE_WAIT);
    DosPostEventSem(hevPut);
    DosReleaseMutexSem(hmtxSyn);
    DosCloseEventSem(hevPut);
/*    DosCloseEventSem(hevGet); */
    DosCloseEventSem(hevEnd);
    DosCloseMutexSem(hmtxSyn);
    if (mem)
        DosFreeMem(mem);
    return 0;
    
}
Exemple #13
0
void set_clip(char *text)
{
    if(!hab || !text)
        return;

    char *pByte = 0;

    //Calculate size of buffer

    int sz = strlen(text) + 1;
    int i;

    _inOpenClipbrd(hab);
    _inEmptyClipbrd(hab);

    if (!DosAllocSharedMem((PPVOID)&pByte, 0, sz,
        PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE))
    {
        memcpy(pByte, text, sz);
        _inSetClipbrdData(hab, (ULONG) pByte, CF_TEXT, CFI_POINTER);
    }
    _inCloseClipbrd(hab);
}
Exemple #14
0
static int SendExtQMsg
(
   USHORT usEvent,
   PVOID pData,
   ULONG ulLen
)
{
   USHORT res;
   ULONG ulPID;
   HQUEUE hQueue;
   PVOID pItem;

   res=DosOpenQueue(&ulPID, &hQueue, szExtQueue);
   if (res)
   {
      printf("AM4PM not running\n");
      return 2;
   }

   if (pData != NULL)
   {
      DosAllocSharedMem(&pItem, NULL, ulLen, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE);
      memcpy(pItem, pData, ulLen);
      DosGiveSharedMem(pItem, ulPID, PAG_READ | PAG_WRITE);
      DosFreeMem(pItem);
   }
   else
      pItem=NULL;

   res=DosWriteQueue(hQueue, usEvent, ulLen, pItem, 0);

   DosCloseQueue(hQueue);
   if (res)
      return 2;
   return 0;
}
Exemple #15
0
int main (int argc, char *argv[])
   {
   APIRET       rc;
   PCHAR        pcEnv;
   PRFPROFILE   prfProfile;

#ifdef DEBUG
   ulDebugMask = 0xFFFFFFFF;
#endif /* DEBUG */

   hab = WinInitialize(0);
   hmq = WinCreateMsgQueue(hab, 0);
   DebugS (1, "PM Interface initialized");

   /* Shared Memory organisieren */
   if (rc = DosGetNamedSharedMem ((PPVOID) &pShareInitOS2,
                                  SHARE_INITOS2,
                                  PAG_READ | PAG_WRITE))
      {
      if (rc = DosAllocSharedMem( (PPVOID) &pShareInitOS2,    // Pointer to shared mem
                                  SHARE_INITOS2,              // Name
                                  CCHSHARE_INITOS2,           // Size of shared mem
                                  PAG_COMMIT | PAG_READ | PAG_WRITE)) // Flags
         return(1);
      else
         {
         /* Shared Memory initialisieren */

         memset (pShareInitOS2, '\0', CCHSHARE_INITOS2);

         pShareInitOS2->pszRegFile       = (PCHAR) pShareInitOS2 +
                                          sizeof(*pShareInitOS2);
         strcpy (pShareInitOS2->pszRegFile,
                 DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);
         pShareInitOS2->pszRootUserIni   = pShareInitOS2->pszRegFile +
                                          strlen(pShareInitOS2->pszRegFile) + 1;
         pShareInitOS2->pszRootSystemIni = pShareInitOS2->pszRootUserIni + 1;
         pShareInitOS2->pszUserIni       = pShareInitOS2->pszRootSystemIni + 1;
         pShareInitOS2->pszSystemIni     = pShareInitOS2->pszUserIni   + CCHMAXPATH;
         pShareInitOS2->pszEnvironment   = pShareInitOS2->pszSystemIni + CCHMAXPATH;
         }
      }
   DebugS (1, "Shared Memory initialized");

   /* Semaphoren organisieren */
   rc = DosOpenEventSem (HEV_SAMMY, &hevSammy);

   if( rc )
      rc = DosCreateEventSem( HEV_SAMMY,   // Name
                              &hevSammy,   // Pointer to sem
                              0,           // Not used with named sems
                              FALSE);      // Initial state (FALSE = SET)

   else        /* Sammy ist bereits installiert */
      {
      pShareInitOS2->pszEnvironment[0] = '\0';
      pShareInitOS2->pszEnvironment[1] = '\0';
      pShareInitOS2->pszSystemIni[0]   = '\0';
      pShareInitOS2->pszUserIni[0]     = '\0';
      DosPostEventSem(hevSammy);
      goto Exit;
      }

   if( rc )
      {
      intSammyRetCode = rc;
      goto Exit;
      }

   rc = DosOpenEventSem (HEV_PRFRESETLOCK, &hevPrfResetLock);

   if( rc )
      rc = DosCreateEventSem( HEV_PRFRESETLOCK, // Name
                              &hevPrfResetLock, // Pointer to sem
                              0,                // Not used with named sems
                              TRUE);            // Initial state (TRUE = POSTED)

   if( rc )
      {
      intSammyRetCode = rc;
      goto Exit;
      }
   DebugS (1, "Semaphores initialized");

   ChangeWPS(pShareInitOS2->pszUserIni, pShareInitOS2->pszSystemIni);

   /* Hintergrundloop starten, das Shell mit aktueller Env. startet */

   DosCreateThread (&tid1,
                    (PFNTHREAD) thStartProg,
                    (ULONG) ((argc > 1) ? argv[1] : ""),
                    0,
                    THREADSTACK);
   DebugS (1, "Background loop started");

   /* Hintergrundloop starten, das jeweils nach L�schen einer Semaphore */
   /* einen prfReset initiiert                      */
   DosCreateThread (&tid2,
                    (PFNTHREAD) thSwitch,
                    (ULONG) 0,
                    0,
                    THREADSTACK);

   while (WinGetMsg (hab, &qmsg, 0, 0, 0))
      WinDispatchMsg (hab, &qmsg);

   if (intSammyRetCode)
      {
      DosKillThread (tid1);
      DosKillThread (tid2);

      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO");
      WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0);

      WinAlarm (HWND_DESKTOP, WA_ERROR);

      prfProfile.pszSysName  = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);
      prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv);

      prfProfile.cchUserName = strlen(prfProfile.pszUserName);
      prfProfile.cchSysName  = strlen(prfProfile.pszSysName);

      DosSleep (1000);
      DosKillProcess( DKP_PROCESSTREE, ulShellID );

      if ( !PrfReset(hab, &prfProfile))
         WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES");
      }
Exit:
   WinDestroyMsgQueue(hmq);
   WinTerminate(hab);

   DebugS (1, "Application terminated");

   return intSammyRetCode;
   }
 int EXPENTRY icqIPCSendCommand(ULONG uin, ICQQUEUEBLOCK *cmd)
 {
    /* Envia um comando */
    char                buffer[0x0100];
    int                 rc                      = 0;
    PID                 pid;
    HQUEUE              queue;
    ICQQUEUEBLOCK       *shr;
    int                 f;
    char                *src;
    char                *dst;
    USHORT              status;
    REQUESTDATA         req;
    int                 sz;

    if(cmd->szPrefix != sizeof(ICQQUEUEBLOCK) || cmd->sz < sizeof(ICQQUEUEBLOCK))
       return ERROR_INVALID_PARAMETER;

    if(!uin)
    {
       rc = icqIPCQueryInstance(&uin);
       if(rc)
          return rc;
    }

    sz = cmd->sz;

    /* Abre a fila */

    sprintf(buffer,"\\QUEUES\\PWICQ\\%lu",uin);
    rc = DosOpenQueue ( &pid,&queue, buffer);

    if(rc)
       return rc;

    rc = DosAllocSharedMem((PVOID) &shr, NULL, sz, PAG_COMMIT|OBJ_GETTABLE|PAG_READ|PAG_WRITE);

    if(!rc)
    {
       DBGTracex(shr);

       src = (char *) cmd;
       dst = (char *) shr;

       for(f=0;f<sz;f++)
          *(dst++) = *(src++);

       rc = DosWriteQueue(queue, 0, sizeof(ULONG), (PVOID) shr, 0);

       if(!rc)
       {
          DBGMessage("Mensagem escrita na fila");

          for(f=0;f<100 && shr->status == cmd->status;f++)
             DosSleep(10);

          DBGTrace(shr->status == cmd->status);

          src = (char *) shr;
          dst = (char *) cmd;

          for(f=0;f<sz;f++)
             *(dst++) = *(src++);
       }

       DosFreeMem(shr);
    }

    DosCloseQueue(queue);

    return rc;
 }
BOOL DDERequest(HWND hwndClient,
                PSZ pszItemString)
{
    ULONG           mem;
    PID             pid;
    TID             tid;
    PDDESTRUCT      pddeStruct;
    PSZ             pszDDEItemName;

    // get some sharable memory
    DosAllocSharedMem((PVOID)&mem,
                      NULL,
                      sizeof(DDESTRUCT) + 1000,
                      PAG_COMMIT |
                      PAG_READ |
                      PAG_WRITE |
                      OBJ_GIVEABLE);

    // get the server's ID and give it access
    // to the shared memory
    WinQueryWindowProcess(G_hServerWnd, &pid, &tid);
    DosGiveSharedMem(&mem, pid, PAG_READ | PAG_WRITE);

    /* here is definition for DDESTRUCT, for further reference:
     * typedef struct _DDESTRUCT {
     * ULONG    cbData;
     * This is the length of data that occurs after the offabData parameter. If no
     * data exists, this field should contain a zero (0).
     * USHORT   fsStatus;       /  Status of the data exchange.
     * DDE_FACK
     * Positive acknowledgement
     * DDE_FBUSY
     * Application is busy
     * DDE_FNODATA
     * No data transfer for advise
     * DDE_FACKREQ
     * Acknowledgements are requested
     * DDE_FRESPONSE
     * Response to WM_DDE_REQUEST
     * DDE_NOTPROCESSED
     * DDE message not understood
     * DDE_FAPPSTATUS
     * A 1-byte field of bits that are reserved for application-specific returns.
     * USHORT   usFormat;       /  Data format.
     * USHORT   offszItemName;  /  Offset to item name.
     * This is the offset to the item name from the start of this structure. Item
     * name is a null (0x00) terminated string. If no item name exists, there must
     * be a single null (0x00) character in this position. (That is, ItemName is
     * ALWAYS a null terminated string.)
     *
     * USHORT   offabData;      /  Offset to beginning of data.
     * This is the offset to the data, from the start of this structure. This field
     * should be calculated regardless of the presence of data. If no data exists,
     * cbData must be zero (0).
     *
     * For compatibility reasons, this data should not contain embedded pointers.
     * Offsets should be used instead.
     *
     * --  CHAR     szItemName[]    /  offset: offszItemName
     * --  BYTE     abData[]        /  offset: offabData
     * } DDESTRUCT; */

    // setup DDE data structures
    pddeStruct = (PDDESTRUCT) mem;
    pddeStruct->fsStatus = 0;   // DDE_FACKREQ;            // Status

    pddeStruct->usFormat = DDEFMT_TEXT;     // Text format

    // go past end of data structure for the item name
    pddeStruct->offszItemName = sizeof(DDESTRUCT);

    pszDDEItemName = ((BYTE*)pddeStruct) + pddeStruct->offszItemName;
    strcpy(pszDDEItemName, pszItemString);

    // go past end of data structure
    // (plus past the name) for the data
    pddeStruct->offabData = strlen(pszDDEItemName) + 1;
    // offset to BEGINNING of data
    pddeStruct->cbData = 500;
    // length of the data

    ShowMessage(__FUNCTION__ ": sending request \"%s\"",
                pszItemString);

    // post our request to the server program
    if (G_NetscapeFound = WinDdePostMsg(G_hServerWnd,
                                        hwndClient,
                                        WM_DDE_REQUEST,
                                        pddeStruct,
                                        0))
                    // WinDdePostMsg frees the shared mem!
        ShowMessage("    --> success");
    else
        ShowMessage("    --> failed");

    return G_NetscapeFound;
}
Exemple #18
0
// Set some data onto the clipboard
void nsClipboard::SetClipboardData(const char *aFlavor)
{
  void *pMozData = nsnull;
  PRUint32 NumOfBytes = 0;

  // Get the data from the transferable
  nsCOMPtr<nsISupports> genericDataWrapper;
#ifdef DEBUG
  nsresult errCode =
#endif
  mTransferable->GetTransferData( aFlavor, getter_AddRefs(genericDataWrapper), &NumOfBytes );
#ifdef DEBUG
  if (NS_FAILED(errCode)) printf( "nsClipboard:: Error getting data from transferable\n" );
#endif
  if (NumOfBytes == 0) return;
  nsPrimitiveHelpers::CreateDataFromPrimitive( aFlavor, genericDataWrapper, &pMozData, NumOfBytes );

  /* If creating the data failed, just return */
  if (!pMozData) {
    return;
  }

  ULONG ulFormatID = GetFormatID( aFlavor );

  if (strstr( aFlavor, "text/" ))  // All text/.. flavors are null-terminated
  {
    if (ulFormatID == CF_TEXT)     // CF_TEXT is one byte character set
    {
      char* pByteMem = nsnull;

      if (DosAllocSharedMem( reinterpret_cast<PPVOID>(&pByteMem), nsnull, NumOfBytes + sizeof(char), 
                             PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE ) == NO_ERROR)
      {
        memcpy( pByteMem, pMozData, NumOfBytes );       // Copy text string
        pByteMem[NumOfBytes] = '\0';                    // Append terminator

        // With Warp4 copying more than 64K to the clipboard works well, but
        // legacy apps cannot always handle it. So output an alarm to alert the
        // user that there might be a problem.
        if (strlen(pByteMem) > 0xFFFF) {
          WinAlarm(HWND_DESKTOP, WA_ERROR);
        }
        WinSetClipbrdData(0, reinterpret_cast<ULONG>(pByteMem), ulFormatID, CFI_POINTER);
      }
    }
    else                           // All other text/.. flavors are in unicode
    {
      UniChar* pUnicodeMem = nsnull;
      PRUint32 NumOfChars = NumOfBytes / sizeof(UniChar);
   
      if (DosAllocSharedMem( reinterpret_cast<PPVOID>(&pUnicodeMem), nsnull, NumOfBytes + sizeof(UniChar), 
                             PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE ) == NO_ERROR) 
      {
        memcpy( pUnicodeMem, pMozData, NumOfBytes );    // Copy text string
        pUnicodeMem[NumOfChars] = L'\0';                // Append terminator

        WinSetClipbrdData( 0, reinterpret_cast<ULONG>(pUnicodeMem), ulFormatID, CFI_POINTER );
      }

      // If the flavor is unicode, we also put it on the clipboard as CF_TEXT
      // after conversion to locale charset.

      if (!strcmp( aFlavor, kUnicodeMime ))
      {
        char* pByteMem = nsnull;

        if (DosAllocSharedMem(reinterpret_cast<PPVOID>(&pByteMem), nsnull,
                              NumOfBytes + 1, 
                              PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE ) == NO_ERROR) 
        {
          PRUnichar* uchtemp = (PRUnichar*)pMozData;
          for (PRUint32 i=0;i<NumOfChars;i++) {
            switch (uchtemp[i]) {
              case 0x2018:
              case 0x2019:
                uchtemp[i] = 0x0027;
                break;
              case 0x201C:
              case 0x201D:
                uchtemp[i] = 0x0022;
                break;
              case 0x2014:
                uchtemp[i] = 0x002D;
                break;
            }
          }

          nsAutoCharBuffer buffer;
          PRInt32 bufLength;
          WideCharToMultiByte(0, static_cast<PRUnichar*>(pMozData),
                              NumOfBytes, buffer, bufLength);
          memcpy(pByteMem, buffer.Elements(), NumOfBytes);
          // With Warp4 copying more than 64K to the clipboard works well, but
          // legacy apps cannot always handle it. So output an alarm to alert the
          // user that there might be a problem.
          if (strlen(pByteMem) > 0xFFFF) {
            WinAlarm(HWND_DESKTOP, WA_ERROR);
          }
          WinSetClipbrdData(0, reinterpret_cast<ULONG>(pByteMem), CF_TEXT, CFI_POINTER);
        }
      }
    }
  }
  else                             // Assume rest of flavors are binary data
  {
    PBYTE pBinaryMem = nsnull;

    if (DosAllocSharedMem( reinterpret_cast<PPVOID>(&pBinaryMem), nsnull, NumOfBytes + sizeof(PRUint32), 
                           PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE ) == NO_ERROR) 
    {
      *(reinterpret_cast<PRUint32*>(pBinaryMem)) = NumOfBytes;          // First DWORD contains data length
      memcpy( pBinaryMem + sizeof(PRUint32), pMozData, NumOfBytes );  // Copy binary data

      WinSetClipbrdData( 0, reinterpret_cast<ULONG>(pBinaryMem), ulFormatID, CFI_POINTER );
    }

    // If the flavor is image, we also put it on clipboard as CF_BITMAP
    // after conversion to OS2 bitmap

    if (strstr (aFlavor, "image/"))
    {
      //  XXX OS2TODO  Convert jpg, gif, png to bitmap
#ifdef DEBUG
      printf( "nsClipboard:: Putting image on clipboard; should also convert to BMP\n" );
#endif
    }
  }
  nsMemory::Free(pMozData);
}
Exemple #19
0
APIRET ProfileTest(void)
{
  APIRET rc;

  ULONG  ul1;
  ULONG  ul2;

  PVOID  pBuffer;
  PVOID  ppBuffer = &pBuffer;
#if 0
   /* DosProfile usType */
   #define PROF_SYSTEM           0
   #define PROF_USER             1
   #define PROF_USEDD            2
   #define PROF_KERNEL           4
   #define PROF_VERBOSE          8
   #define PROF_ENABLE          16

   /* DosProfile usFunc */
   #define PROF_ALLOC            0
   #define PROF_CLEAR            1
   #define PROF_ON               2
   #define PROF_OFF              3
   #define PROF_DUMP             4
   #define PROF_FREE             5

   /* DosProfile tic count granularity (DWORD) */
   #define PROF_SHIFT            2

   /* DosProfile module name string length */
   #define PROF_MOD_NAME_SIZE   10

   /* DosProfile error code for end of data */
   #define PROF_END_OF_DATA     13
#endif

  /* have to call system first, initialization */
  rc = DosAllocSharedMem(&pBuffer,
                         "\\SHAREMEM\\PROFILE",
                         8192,
                         PAG_READ | PAG_WRITE | PAG_COMMIT);
  fprintf (stderr,
           "\nDEBUG Dos32AllocMem (alloc) = %u",
           rc);


  rc = Dos32Profile(PROF_SYSTEM,
                    0,
                    getpid(),
                    (ULONG)pBuffer);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (alloc) = %u",
           rc);

  rc = Dos32Profile(PROF_KERNEL,
                    PROF_ALLOC,
                    getpid(),
                    (ULONG)0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (alloc) = %u",
           rc);


  rc = Dos32Profile(PROF_KERNEL,
                    PROF_CLEAR,
                    0,
                    0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (clear) = %u",
           rc);

  rc = Dos32Profile(PROF_KERNEL,
                    PROF_ON,
                    0,
                    0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (on) = %u",
           rc);

  rc = Dos32Profile(PROF_KERNEL,
                    PROF_OFF,
                    0,
                    0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (off) = %u",
           rc);

  rc = Dos32Profile(PROF_KERNEL,
                    PROF_DUMP,
                    0,
                    0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (dump) = %u",
           rc);


  rc = Dos32Profile(PROF_KERNEL,
                    PROF_FREE,
                    0,
                    0);
  fprintf (stderr,
           "\nDEBUG Dos32Profile (free) = %u",
           rc);
}
Exemple #20
0
int main (int argc, char *argv[])
{
  HQUEUE hq_server, hq_client;
  ULONG rc, len;
  PID owner_pid;
  PVOID data;
  REQUESTDATA request;
  BYTE priority;
  char buffer[1024], name[512], *p;
  long client_pid;

  if (argc == 1)
    {
      if (spawnl (P_NOWAIT, argv[0], argv[0], "-r", NULL) < 0)
	  {
	  perror ("spawn");
	  return (1);
	  }
      for (;;)
	{
	  if (fgets (buffer, sizeof (buffer), stdin) == 0)
	    return (0);
	  p = buffer;
	  while (*p != 0 && !(*p >= '0' && *p <= '9'))
	    ++p;
	  client_pid = strtol (p, NULL, 10);
	  (void)sprintf (name, "/queues/emacs/clients/%ld", client_pid);
	  rc = DosOpenQueue (&owner_pid, &hq_client, name);
	  if (rc == 0)
	    {
	      len = strlen (buffer) + 1;
	      rc = DosAllocSharedMem (&data, 0, len,
				      PAG_COMMIT | OBJ_GIVEABLE | PAG_READ
				      | PAG_WRITE);
	      ERROR ("DosAllocSharedMem");
	      rc = DosGiveSharedMem (data, client_pid, PAG_READ);
	      ERROR ("DosGiveSharedMem");
	      (void)memcpy (data, buffer, len);
	      rc = DosWriteQueue (hq_client, 0, len, data, 0);
	      ERROR ("DosWriteQueue");
	      rc = DosFreeMem (data);
	      ERROR ("DosFreeMem");
	      rc = DosCloseQueue (hq_client);
	      ERROR ("DosCloseQueue");
	    }
	}
    }
  else if (argc == 2 && strcmp (argv[1], "-r") == 0)
    {
      rc = DosCreateQueue (&hq_server, QUE_FIFO | QUE_CONVERT_ADDRESS,
			   "/queues/emacs/server");
      ERROR ("DosCreateQueue");
      for (;;)
	{
	  rc = DosReadQueue (hq_server, &request, &len, &data, 0,
			     DCWW_WAIT, &priority, 0);
	  ERROR ("DosReadQueue");
	  (void)printf ("Client: %d ", (int)request.pid);
	  (void)fputs (data, stdout);
	  (void)fflush (stdout);
	  rc = DosFreeMem (data);
	  ERROR ("DosFreeMem");
	}
    }
  else
    {
      (void)fprintf (stderr, "Usage: %s\n", argv[0]);
      return (1);
    }
}
Exemple #21
0
/**
 * Initializes the shared structures.
 */
static void shared_init()
{
  APIRET arc;
  int rc;

  arc = DosExitList(EXLST_ADD, ProcessExit);
  ASSERT_MSG(arc == NO_ERROR, "%ld", arc);

#if defined(TRACE_ENABLED) && !defined(TRACE_USE_LIBC_LOG)
  /*
   * Allocate a larger buffer to fit lengthy TRACE messages and disable
   * auto-flush on EOL (to avoid breaking lines by stdout operations
   * from other threads/processes).
   */
  setvbuf(stdout, NULL, _IOFBF, 0x10000);
#endif

  while (1)
  {
    /* First, try to open the mutex */
    arc = DosOpenMutexSem(MUTEX_LIBCX, &gMutex);
    TRACE("DosOpenMutexSem = %lu\n", arc);

    if (arc == NO_ERROR)
    {
      /*
       * Init is (being) done by another process, request the mutex to
       * guarantee shared memory is already alloated, then get access to
       * it and open shared heap located in that memory.
       */
      arc = DosRequestMutexSem(gMutex, SEM_INDEFINITE_WAIT);
      ASSERT_MSG(arc == NO_ERROR, "%ld", arc);

      if (arc == NO_ERROR)
      {
        arc = DosGetNamedSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, PAG_READ | PAG_WRITE);
        TRACE("DosGetNamedSharedMem = %lu\n", arc);
        if (arc)
        {
          /*
           * This failure means that another process was too fast to do what
           * it wanted and initiated global uninitialization before we got the
           * mutex so shared memory was already freed by this time. Retry.
           */
          DosReleaseMutexSem(gMutex);
          DosCloseMutexSem(gMutex);
          continue;
        }

        /*
         * It's an ordinary LIBCx process. Increase coutners.
         */

        TRACE("gpData->heap = %p\n", gpData->heap);
        ASSERT(gpData->heap);

        rc = _uopen(gpData->heap);
        ASSERT_MSG(rc == 0, "%d (%d)", rc, errno);

        ASSERT(gpData->refcnt);
        gpData->refcnt++;
        TRACE("gpData->refcnt = %d\n", gpData->refcnt);
      }

      break;
    }

    if (arc == ERROR_SEM_NOT_FOUND)
    {
      /* We are the first process, create the mutex */
      arc = DosCreateMutexSem(MUTEX_LIBCX, &gMutex, 0, TRUE);
      TRACE("DosCreateMutexSem = %ld\n", arc);

      if (arc == ERROR_DUPLICATE_NAME)
      {
        /* Another process is faster, attempt to open the mutex again */
        continue;
      }
    }

    ASSERT_MSG(arc == NO_ERROR, "%ld", arc);

    /*
     * It's a process that successfully created the main mutex, i.e. the first
     * LIBCx process. Proceed with the initial setup by allocating shared
     * memory and heap.
     */

    /* Allocate shared memory */
    arc = DosAllocSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, HEAP_SIZE,
                            PAG_READ | PAG_WRITE | OBJ_ANY);
    TRACE("DosAllocSharedMem(OBJ_ANY) = %ld\n", arc);

    if (arc && arc != ERROR_ALREADY_EXISTS)
    {
      /* High memory may be unavailable, try w/o OBJ_ANY */
      arc = DosAllocSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, HEAP_SIZE,
                              PAG_READ | PAG_WRITE);
      TRACE("DosAllocSharedMem = %ld\n", arc);
    }

    ASSERT_MSG(arc == NO_ERROR, "%ld", arc);

    TRACE("gpData %p\n", gpData);

    /* Commit the initial block */
    arc = DosSetMem(gpData, HEAP_INIT_SIZE, PAG_DEFAULT | PAG_COMMIT);
    ASSERT_MSG(arc == NO_ERROR, "%ld", arc);

    gpData->size = HEAP_INIT_SIZE;

    /* Create shared heap */
    gpData->heap = _ucreate(gpData + 1, HEAP_INIT_SIZE - sizeof(*gpData),
                            _BLOCK_CLEAN, _HEAP_REGULAR | _HEAP_SHARED,
                            mem_alloc, NULL);
    TRACE("gpData->heap = %p\n", gpData->heap);
    ASSERT(gpData->heap);

    rc = _uopen(gpData->heap);
    ASSERT_MSG(rc == 0, "%d (%d)", rc, errno);

    gpData->refcnt = 1;

    /* Initialize common structures */
    GLOBAL_NEW_ARRAY(gpData->procs, PROC_DESC_HASH_SIZE);
    TRACE("gpData->procs = %p\n", gpData->procs);
    ASSERT(gpData->procs);

    GLOBAL_NEW_ARRAY(gpData->files, FILE_DESC_HASH_SIZE);
    TRACE("gpData->files = %p\n", gpData->files);
    ASSERT(gpData->files);

    break;
  }

  /*
   * Perform common initialization (both for the first and ordinary processes).
   */

  /* Make sure a process description for this process is created */
  ProcDesc *proc = get_proc_desc(getpid());
  ASSERT(proc);

  /* Initialize individual components */
  mmap_init(proc);
  fcntl_locking_init(proc);

  /* Check if it's a spawn2 wrapper (e.g. spawn2-wrapper.c) */
  {
    char dll[CCHMAXPATH + sizeof(SPAWN2_WRAPPERNAME) + 1];
    if (get_module_name(dll, sizeof(dll)))
    {
      strcpy(_getname(dll), SPAWN2_WRAPPERNAME);

      char exe[CCHMAXPATH + 1];
      if (_execname(exe, sizeof(exe)) == 0 && stricmp(dll, exe) == 0)
      {
        proc->flags |= Proc_Spawn2Wrapper;
        TRACE("spawn2 wrapper\n");

        /* Make sure the semaphore is available (needed for spawn2-wrapper.c) */
        ASSERT(gpData->spawn2_sem);
        global_spawn2_sem(proc);
      }
    }
  }

  DosReleaseMutexSem(gMutex);

  TRACE("done\n");
}
Exemple #22
0
ULONG QueueWrite(
    PUCHAR name,
    ULONG argc,
    PRXSTRING args,
    PSZ queue,
    PRXSTRING result)
{
    HQUEUE handle;
    PQueue q;
    PCH dataString;
    ULONG length;
    PVOID data;
    ULONG request;
    ULONG priority;
    APIRET rc;
    ULONG cc;

    if (argc < 2 || argc > 4) return QUEUE_BADPARAM;

    if (!RxStringToUnsigned(args + 0, &handle)) return QUEUE_BADPARAM;
    q = (PQueue)handle;

    if (!RxStringIsValid(args + 1)) return QUEUE_BADPARAM;
    dataString = args[1].strptr;
    length = args[1].strlength;

    if (argc > 2 && RxStringIsPresent(args + 2)) {
        if (!RxStringToUnsigned(args + 2, &request)) return QUEUE_BADPARAM;
    }
    else request = 0;

    if (argc > 3 && RxStringIsPresent(args + 3)) {
        if (!RxStringToUnsigned(args + 3, &priority)) return QUEUE_BADPARAM;
    }
    else priority = 0;

    if (q->server == q->client) {
        data = malloc(length);
        if (data == NULL) return QUEUE_NOMEM;
        memcpy(data, dataString, length);
        rc = NO_ERROR;
    }
    else {
        rc = DosAllocSharedMem(
            &data, NULL, length,
            PAG_COMMIT | PAG_WRITE | PAG_READ | OBJ_GIVEABLE);
        if (rc != NO_ERROR) return QUEUE_NOMEM;
        memcpy(data, dataString, length);
        rc = DosGiveSharedMem(data, q->server, PAG_READ | PAG_WRITE);
    }

    if (rc == NO_ERROR) {
        rc = DosWriteQueue(q->handle, request, length, data, priority);
        if (rc == ERROR_SYS_INTERNAL) rc = NO_ERROR;
    }

    if (q->server != q->client) DosFreeMem(data);
    else if (rc != NO_ERROR) free(data);

    cc = UnsignedToRxResult(rc, result);
    return cc;
}
Exemple #23
0
static void *
tf (void *arg)
{
  if (pthread_mutex_lock (&lock))
    {
      puts ("1st locking of lock failed");
	  exit (1);
    }

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("fourth fcntl failed");
      exit (1);
    }

  pthread_mutex_unlock (&lock);

  pthread_mutex_lock (&lock2);

  return NULL;
}


static int
do_test (void)
{
  fd = create_temp_file("tst-flock2-", NULL);
  if (fd == -1)
    {
      puts ("create_temp_file failed");
      return 1;
    }

  int i;
  for (i = 0; i < 20; ++i)
    write (fd, "foobar xyzzy", 12);

  pthread_barrier_t *b;
#ifdef __EMX__
  APIRET arc;
  arc = DosAllocSharedMem ((PPVOID) &b, NULL, sizeof (pthread_barrier_t),
                           PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GETTABLE);
  if (arc)
    {
      puts ("DosAllocSharedMem failed");
      return 1;
    }
  b->hmtx = NULLHANDLE;
  arc = DosCreateMutexSem (NULL, &b->hmtx, DC_SEM_SHARED, FALSE);
  if (arc)
    {
      puts ("DosCreateMutexSem failed");
      return 1;
    }
  b->hev = NULLHANDLE;
  arc = DosCreateEventSem (NULL, &b->hev, DC_SEM_SHARED | DCE_AUTORESET, FALSE);
  if (arc)
    {
      puts ("DosCreateEventSem failed");
      return 1;
    }
  b->cnt = 0;
  b->cnt_max = 2;
#else
  b = mmap (NULL, sizeof (pthread_barrier_t), PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, 0);
  if (b == MAP_FAILED)
    {
      puts ("mmap failed");
      return 1;
    }

  pthread_barrierattr_t ba;
  if (pthread_barrierattr_init (&ba) != 0)
    {
      puts ("barrierattr_init failed");
      return 1;
    }

  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("barrierattr_setpshared failed");
      return 1;
    }

  if (pthread_barrier_init (b, &ba, 2) != 0)
    {
      puts ("barrier_init failed");
      return 1;
    }

  if (pthread_barrierattr_destroy (&ba) != 0)
    {
      puts ("barrierattr_destroy failed");
      return 1;
    }
#endif

  struct flock fl =
    {
      .l_type = F_WRLCK,
      .l_start = 0,
      .l_whence = SEEK_SET,
      .l_len = 10
    };
  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("first fcntl failed");
      return 1;
    }

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }

  if (pid == 0)
    {
#ifdef __EMX__
      arc = DosGetSharedMem (b, PAG_READ | PAG_WRITE);
      if (arc)
        {
          puts ("DosGetSharedMem failed");
          return 1;
        }
      arc = DosOpenMutexSem (NULL, &b->hmtx);
      if (arc)
        {
          puts ("DosOpenMutexSem failed");
          return 1;
        }
      arc = DosOpenEventSem (NULL, &b->hev);
      if (arc)
        {
          puts ("DosOpenEventSem failed");
          return 1;
        }
#endif
      /* Make sure the child does not stay around indefinitely.  */
      alarm (10);

      /* Try to get the lock.  */
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("child:  second flock succeeded");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_UNLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
	{
	  puts ("third fcntl failed");
	  return 1;
	}
    }

  pthread_barrier_wait (b);

  pthread_t th;
  if (pid == 0)
    {
      if (pthread_mutex_lock (&lock2) != 0)
	{
	  puts ("1st locking of lock2 failed");
	  return 1;
	}

      if (pthread_create (&th, NULL, tf, NULL) != 0)
	{
	  puts ("pthread_create failed");
	  return 1;
	}

      /* Let the new thread run.  */
      sleep (1);

      if (pthread_mutex_lock (&lock) != 0)
	{
	  puts ("2nd locking of lock failed");
	  return 1;
	}

      puts ("child locked file");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file locked by child");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      if (pthread_mutex_unlock (&lock2) != 0)
	{
	  puts ("unlock of lock2 failed");
	  return 1;
	}

      if (pthread_join (th, NULL) != 0)
	{
	  puts ("join failed");
	  return 1;
	}

      puts ("child's thread terminated");
    }

  pthread_barrier_wait (b);

  if (pid != 0)
    {
      fl.l_type = F_WRLCK;
      if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &fl)) == 0)
	{
	  puts ("fifth fcntl succeeded");
	  return 1;
	}

      puts ("file still locked");
    }

  pthread_barrier_wait (b);

  if (pid == 0)
    {
      _exit (0);
    }

  int status;
  if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
      puts ("waitpid failed");
      return 1;
    }
  puts ("child terminated");

  if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLKW, &fl)) != 0)
    {
      puts ("sixth fcntl failed");
      return 1;
    }

  return status;
}
extern int main ( int argc, char *argv[] ) {

  /**************************************************************************
   * Register self.                                                         *
   **************************************************************************/

   Sys_RegisterThread ( ) ;

  /**************************************************************************
   * Set a default exception filter.                                        *
   **************************************************************************/

   REGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Start the main block (for constructors/destructors).                   *
   **************************************************************************/

   {

  /**************************************************************************
   * Get the initial file path for loading files from command-line.         *
   **************************************************************************/

   char InitialPath [CCHMAXPATH] ;
   _fullpath ( InitialPath, ".", sizeof(InitialPath) ) ;
   strcat ( InitialPath, "\\" ) ;

  /**************************************************************************
   * Determine the home directory.                                          *
   **************************************************************************/

   char Drive [_MAX_DRIVE+1], Dir[_MAX_DIR+1], Fname[_MAX_FNAME+1], Ext[_MAX_EXT+1] ;
   strupr ( argv[0] ) ;
   _fullpath ( HomePath, argv[0], sizeof(HomePath) ) ;
   _splitpath ( HomePath, Drive, Dir, Fname, Ext ) ;
   if ( Dir[strlen(Dir)-1] == '\\' )
      Dir[strlen(Dir)-1] = 0 ;
   strcpy ( HomePath, Drive ) ;
   strcat ( HomePath, Dir ) ;

   _chdrive ( Drive[0] - 'A' + 1 ) ;
   _chdir ( "\\" ) ;
   _chdir ( Dir ) ;

  /**************************************************************************
   * Set the C RunTime Library error message file handle.                   *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Program started." ) ;
      _set_crt_msg_handle ( fileno(Logfile) ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program started." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Determine if another instance of this program is present.              *
   *   If so, pass the command-line information to it.                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Checking for another instance already loaded." ) ;
   #endif // DEBUG

   PublicMemory Memory ( MEMORY_NAME, sizeof(SHARED_MEMORY), TRUE ) ;
   if ( NOT Memory.QueryCreated() ) {

      // Get the main instance's window handle.  Wait up to 20 seconds if necessary.
      HWND MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      clock_t LastClock = clock ( ) ;
      while ( MainWindow == 0 ) {
         if ( ( ( clock() - LastClock ) / CLOCKS_PER_SEC ) > 20 ) {
            Log ( "ERROR: Unable to get previous instance window handle." ) ;
            return ( 1 ) ;
         } /* endif */
         DosSleep ( 100 ) ;
         MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      } /* endwhile */

      // If any command-line parameters were given . . .
      if ( argc > 1 ) {

         // Build a command-line string.
         char Parms [512] = { 0 } ;
         int ParmLength = 0 ;
         while ( --argc ) {
            strcpy ( Parms+ParmLength, *(++argv) ) ;
            ParmLength += strlen(*argv) + 1 ;
         } /* endwhile */
         Parms[++ParmLength] = 0 ;

         // Get the original process's ID.
         PID Process ;
         TID Thread ;
         if ( !WinQueryWindowProcess ( MainWindow, &Process, &Thread ) ) {
            char Message [512] ;
            Log ( "ERROR: Unable to query window process.  %s", InterpretWinError(0,Message) ) ;
            return ( 1 ) ;
         } /* endif */

         // Allocate shared memory to hold the current path.
         PVOID Memory1 ;
         APIRET Status = DosAllocSharedMem ( &Memory1, 0, strlen(InitialPath)+1, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         strcpy ( PCHAR(Memory1), InitialPath ) ;

         // Allocate shared memory to hold the command-line.
         PVOID Memory2 ;
         Status = DosAllocSharedMem ( &Memory2, 0, ParmLength, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         memcpy ( Memory2, Parms, ParmLength ) ;

         // Make both shared memory blocks available to the original process.
         Status = DosGiveSharedMem ( Memory1, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory1 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         Status = DosGiveSharedMem ( Memory2, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory2 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */

         // Pass the information to the original process.
         Sys_PostMessage ( MainWindow, WM_LOAD_FILE, MPFROMP(Memory1), MPFROMP(Memory2) ) ;

      } /* endif */

      // Bring the previous instance to the fore.
      Sys_SetActiveWindow ( MainWindow ) ;

      // We're outta here . . .
      return ( 0 ) ;

   } /* endif */

  /**************************************************************************
   * If the ISPELL environment variable isn't set, set it to the current    *
   *   directory, before we change it.  This assumes that the current       *
   *   directory is also the directory to which Escriba (and ISPELL) was    *
   *   installed.  This is true with the basic installation.                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Setting ISPELL environment variable." ) ;
   #endif // DEBUG

   {
      char *p = getenv ( "ISPELL" ) ;
      if ( p == 0 ) {
         static char SetString [_MAX_PATH+10] ;
         sprintf ( SetString, "ISPELL=%s", HomePath ) ;
         _putenv ( SetString ) ;
      } /* endif */
   }

  /**************************************************************************
   * Get application language module.                                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Loading default language." ) ;
   #endif // DEBUG

   char DefaultLanguage [80] = { 0 } ;

   { /* startblock */
      Profile IniFile ( PSZ(PROGRAM_NAME), 0, HomePath ) ;
      if ( IniFile.QueryHandle() ) 
         IniFile.GetString ( "Language", DefaultLanguage, sizeof(DefaultLanguage) ) ;
      else
         strcpy ( DefaultLanguage, "English" ) ;
   } /* endblock */

   Library = Language_Create ( PROGRAM_NAME, REVISION, IDS_TITLE1, DefaultLanguage ) ;
   if ( Library == 0 ) {
      Process Proc ( PROGRAM_NAME, HWND_DESKTOP, 0 ) ;
      Debug ( HWND_DESKTOP, "ERROR: Unable to find language module for %s, %s, %s.", PROGRAM_NAME, REVISION, DefaultLanguage ) ;
      return ( 1 ) ;
   } /* endif */

   LibraryHandle = Library->QueryHandle() ;

  /**************************************************************************
   * Get the program title.                                                 *
   **************************************************************************/

   ResourceString Title ( Library->QueryHandle(), IDS_TITLE ) ;

  /**************************************************************************
   * Determine the default codepage.                                        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Determining codepage to use." ) ;
   #endif // DEBUG

   PUSHORT pCodePage = Library->QueryCodepages() ;
   while ( *pCodePage ) {
      if ( !DosSetProcessCp ( *pCodePage ) )
         break ;
      pCodePage ++ ;
   } /* endwhile */

   if ( *pCodePage == 0 ) {
      ResourceString Format ( Library->QueryHandle(), IDS_WARNING_BADCODEPAGE ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), *Library->QueryCodepages() ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      return ( 1 ) ;
   } /* endif */
 
  /**************************************************************************
   * Initialize the process with an extra-large message queue.              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Connecting to PM." ) ;
   #endif // DEBUG

   Process Proc ( PCHAR(Title), HWND_DESKTOP, Library->QueryHandle(), 100, *pCodePage ) ;
   if ( Proc.QueryAnchor() == 0 ) 
      return ( 1 ) ;

  /**************************************************************************
   * Register the custom control classes.                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Registering custom control classes." ) ;
   #endif // DEBUG

   RegisterControls ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Open up debug timer.                                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Opening debug timer." ) ;
   #endif // DEBUG

   OpenTimer ( ) ;

  /**************************************************************************
   * Open the registration library, if it is present.                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open registration file." ) ;
   #endif // DEBUG

   char *RegistrationName = PROGRAM_NAME"R" ;
   Module *pRegistration = new Module ( RegistrationName, FALSE ) ;
   if ( pRegistration->QueryHandle() == 0 )
      RegistrationName = "PLUMAR" ;
   delete pRegistration, pRegistration = 0 ;

   Module Registration = Module ( RegistrationName, FALSE ) ;

  /**************************************************************************
   * Load any extenders (except spell-check).                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to load extenders." ) ;
   #endif // DEBUG

   AddonList.Build ( DefaultLanguage ) ;

  /**************************************************************************
   * Get the country information.                                           *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get country information." ) ;
   #endif // DEBUG

   GetCountryInfo ( 0, 0 ) ;

  /**************************************************************************
   * Set any language-specific globals.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to set language-specific globals." ) ;
   #endif // DEBUG

   ResourceString AllGraphicFiles ( LibraryHandle, IDS_ALL_GRAPHICS ) ;
   GraphicTypeList[0] = PSZ ( AllGraphicFiles ) ;

  /**************************************************************************
   * Check for command-line options and remove them from the argument list. *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to parse the command line." ) ;
   #endif // DEBUG

   ResourceString ResetCommand ( Library->QueryHandle(), IDS_PARMS_RESET ) ;
   BOOL Reset = FALSE ;

// ResourceString PrintCommand ( Library->QueryHandle(), IDS_PARMS_PRINT ) ;
// BOOL Print = FALSE ;

   ResourceString TrapCommand ( Library->QueryHandle(), IDS_PARMS_TRAP ) ;
   BOOL Trap = FALSE ;

   int i = 1 ;
   char **p = argv + 1 ;
   while ( i < argc ) {
      if ( **p == '-' ) {
         if ( !stricmp ( (*p)+1, PCHAR(ResetCommand) ) ) {
            Reset = TRUE ;
//       } else if ( !stricmp ( (*p)+1, PCHAR(PrintCommand) ) ) {
//          Print = TRUE ;
         } else if ( !stricmp ( (*p)+1, PCHAR(TrapCommand) ) ) {
            Trap = TRUE ;
         } else {
            Debug ( HWND_DESKTOP, "ERROR: Invalid command-line parameter '%s'.", (*p)+1 ) ;
            return ( 1 ) ;
         } /* endif */
         for ( int j=i+1; j<argc; j++ ) {
            argv[j-1] = argv[j] ;
         } /* endfor */
         argv[j] = 0 ;
         argc -- ;
         continue ;
      } /* endif */
      i ++ ;
      p ++ ;
   } /* endwhile */

  /**************************************************************************
   * Create the help instance.                                              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the help instance." ) ;
   #endif // DEBUG

   _splitpath ( Library->QueryName(), Drive, Dir, Fname, Ext ) ;
   char HelpFileName [CCHMAXPATH] ;
   sprintf ( HelpFileName, "%s.hlp", Fname ) ;

   ResourceString HelpTitle ( Library->QueryHandle(), IDS_HELPTITLE ) ;

   Help = new HelpWindow ( Proc.QueryAnchor(), 0, ID_MAIN, PSZ(HelpFileName), PSZ(HelpTitle) ) ;

   if ( Help->QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEHELP ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
   } /* endif */

  /**************************************************************************
   * Open/create the profile file.  Reset if requested.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open profile file." ) ;
   #endif // DEBUG

   Profile2 IniFile ( PSZ(PROGRAM_NAME), Proc.QueryAnchor(), Library->QueryHandle(),
      IDD_PROFILE_PATH, Help, Reset ) ;

   if ( IniFile.QueryHandle() == 0 ) {
      ResourceString Message ( Library->QueryHandle(), IDS_ERROR_PRFOPENPROFILE ) ;
      Log ( "%s", PSZ(Message) ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 2 ) ;
   } /* endif */

  /**************************************************************************
   * Get profile data. Try the OS2.INI first, then try for private INI.     *
   *   If obtained from OS2.INI, erase it afterwards and resave it.         *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get profile data." ) ;
   #endif // DEBUG

   INIDATA IniData ( Registration.QueryHandle() ) ;
   IniFile.GetIniData ( IniData ) ;

   if ( IniData.Language [0] == 0 ) 
      strcpy ( IniData.Language, DefaultLanguage ) ;

  /**************************************************************************
   * Activate the spell checker, if it is present.                          *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open the default dictionary." ) ;
   #endif // DEBUG

   char SpellerPath [ CCHMAXPATH ] = { 0 } ;
   if ( getenv ( "ISPELL" ) ) {
      strcpy ( SpellerPath, getenv ( "ISPELL" ) ) ;
      strcat ( SpellerPath, "\\" ) ;
   } /* endif */
   strcat ( SpellerPath, "ISPELLER.DLL" ) ;
   Dictionary *Speller = new Dictionary ( SpellerPath, DefaultLanguage ) ;
   if ( Speller->QueryLibrary() == 0 ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Could not find spellchecker.  Will try again through LIBPATH." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
      Speller = new Dictionary ( "ISPELLER", DefaultLanguage ) ;
   } /* endif */
   if ( Speller->Available() ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Adding dictionary object to extension list." ) ;
      #endif // DEBUG
      AddonList.Add ( Speller ) ;
   } else {
      #ifdef DEBUG
         Log ( "Escriba::main: Dictionary object could not be fully created." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
   } /* endif */

  /**************************************************************************
   * Create the frame window.                                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the frame window." ) ;
   #endif // DEBUG

   FRAMECDATA FrameControlData ;
   FrameControlData.cb = sizeof(FrameControlData) ;
   FrameControlData.flCreateFlags =
      FCF_TITLEBAR | FCF_MENU | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE | FCF_SYSMENU |
      ( Trap ? 0 : FCF_SIZEBORDER | FCF_MINMAX ) ;
   FrameControlData.hmodResources = USHORT ( Library->QueryHandle() ) ;
   FrameControlData.idResources = ID_MAIN ;

   Window Frame ( HWND_DESKTOP, WC_FRAME, PSZ(Title),
      IniData.Animate ? WS_ANIMATE : 0,
      0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_MAIN,
      &FrameControlData, NULL ) ;

   if ( Frame.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEFRAME ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 3 ) ;
   } /* endif */

  /**************************************************************************
   * Associate the help instance with the frame window.                     *
   **************************************************************************/

   Help->Associate ( Frame.QueryHandle() ) ;

  /**************************************************************************
   * Register the client window class.                                      *
   **************************************************************************/

   if ( !WinRegisterClass ( Proc.QueryAnchor(), PSZ(CLASS_NAME),
      MessageProcessor, CS_MOVENOTIFY, sizeof(PVOID) ) ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_WINREGISTERCLASS ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), CLASS_NAME, Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_WINREGISTERCLASS, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 4 ) ;
   } /* endif */

  /**************************************************************************
   * Build the presentation parameters for the main window.                 *
   **************************************************************************/

   COLOR BackColor = IniData.fMainColors[0] ? IniData.MainColors[0] :
      WinQuerySysColor ( HWND_DESKTOP, SYSCLR_APPWORKSPACE, 0 ) ;
   ULONG Ids[] = { PP_BACKGROUNDCOLOR } ;
   ULONG ByteCounts[] = { sizeof(BackColor) } ;
   PUCHAR Params[] = { PUCHAR(&BackColor) } ;

   PPRESPARAMS PresParams = BuildPresParams ( sizeof(Ids)/sizeof(Ids[0]),
     Ids, ByteCounts, Params ) ;

  /**************************************************************************
   * Create client window.  If this fails, destroy frame and return.        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the client window." ) ;
   #endif // DEBUG

   PARMS Parms ;
   Parms.Filler = 0 ;
   Parms.Library = Library ;
   Parms.Registration = & Registration ;
   Parms.IniFile = & IniFile ;
   Parms.IniData = & IniData ;
   Parms.Speller = Speller ;
   Parms.InitialPath = InitialPath ;
   Parms.argc = argc ;
   Parms.argv = argv ;
   Parms.Trap = Trap ;

   Window Client ( Frame.QueryHandle(), PSZ(CLASS_NAME), PSZ(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
      0, 0, 0, 0, Frame.QueryHandle(), HWND_BOTTOM, FID_CLIENT, &Parms, PresParams ) ;

   free ( PresParams ) ;

   if ( Client.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATECLIENT ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_CREATECLIENT, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer ( ) ;
      return ( 5 ) ;
   } /* endif */

   ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow = Client.QueryHandle() ;

  /**************************************************************************
   * Wait for and process messages to the window's queue.  Terminate        *
   *   when the WM_QUIT message is received.                                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to enter the main message loop." ) ;
   #endif // DEBUG

   Sys_ProcessMessages ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Discard all that had been requested of the system.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to close the HR Timer." ) ;
   #endif // DEBUG

   CloseTimer ( ) ;

  /**************************************************************************
   * Invoke nearly all the destructors.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Invoking most destructors." ) ;
   #endif // DEBUG

   } /* Invoke all destructors except the global ones. */

  /**************************************************************************
   * Invoke the remaining destructors.                                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the addon list." ) ;
   #endif // DEBUG

   AddonList.Clear ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the file type list." ) ;
   #endif // DEBUG

   ClearFileTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the graphic type list." ) ;
   #endif // DEBUG

   ClearGraphicTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the help instance." ) ;
   #endif // DEBUG

   if ( Help ) delete Help ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the language library instance." ) ;
   #endif // DEBUG

   if ( Library ) delete Library ;

  /**************************************************************************
   * Check to see if any memory remains allocated.                          *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Checking the heap." ) ;
      _dump_allocated ( 64 ) ;
      Log ( "Escriba::main: Program ended." ) ;
      fclose ( Logfile ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program ended." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Discard the exception filter.                                          *
   **************************************************************************/

   UNREGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Terminate the process.                                                 *
   **************************************************************************/

   return ( 0 ) ;
}
Exemple #25
0
//called to allocate memory and setup initial settings
BOOL CBZInit(HINI hIni, char szName[], char szClass[], PVOID * pData)
{
    PLUGINSHARE *pPluginShare;
    PLUGINSHARE *pPluginData;
    char szReadName[64];
    char szShareName[64];
    ULONG szData;

    // alloc window words for the plugin's data
    if ((DosAllocMem((PPVOID) (pData),
                     sizeof(PLUGINSHARE),
                     PAG_READ | PAG_WRITE | PAG_COMMIT)) != NO_ERROR)
    {
        return FALSE;
    }

    //initialize the plugin's data to zeros.
    memset(*pData, 0, sizeof(PLUGINSHARE));

    pPluginData = (PLUGINSHARE *) * pData;

    strcpy(szShareName, PLUGIN_SHARE);
    strcat(szShareName, szClass);

    //custom name was specified, try to load the custom config for it.
    if (strlen(szName) > 0)
    {
        strcpy(szReadName, szName);
        strcat(szReadName, "_");
        strcat(szReadName, szClass);
        strcat(szReadName, "_CBZLINESPlugin");
        szData = sizeof(PLUGINSHARE);

        // get shared mem
        if (!PrfQueryProfileData(hIni,
                                 "CustomOptionsData",
                                 szReadName,
                                 pPluginData,
                                 &szData))
        {
            // if shared mem is not available, use defaults!
            if (DosGetNamedSharedMem((PPVOID) & pPluginData, szShareName, PAG_READ) != NO_ERROR)
            {
                //use some defaults?
                pPluginData->lActiveLineColor = 121 * 65536 + 127;
                pPluginData->lActiveShadowColor = 255 * (65536 + 1);
                pPluginData->lInactiveLineColor = 100 * (65536 + 256 + 1);
                pPluginData->lInactiveShadowColor = 204 * (65536 + 256 + 1);
                pPluginData->bActiveEnabled = TRUE;
                pPluginData->bInactiveEnabled = TRUE;
                pPluginData->lLineStyle = 7;

                if (!PrfWriteProfileData(hIni,
                                         "CustomOptionsData",
                                         szReadName,
                                         pPluginData,
                                         sizeof(PLUGINSHARE)))
                {
                    //not a fatal error
                }
            }
        }

    }                           //end if (szName > 0)

    else
    {
        //Load defaults!  No custom name specified.

        // if shared mem is not available, try allocating it!
        if (DosGetNamedSharedMem((PPVOID) & pPluginShare, szShareName, PAG_READ) != NO_ERROR)
        {
            //try Allocating the SharedMem space for this plugin!
            if (DosAllocSharedMem((PPVOID) & pPluginShare,
                                  szShareName,
                                  sizeof(PLUGINSHARE),
                             PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR)
                return (FALSE); //ignore this plugin... It must be broken?

            // clear it
            memset(pPluginShare, 0, sizeof(PLUGINSHARE));

            szData = sizeof(PLUGINSHARE);

            // get shared mem
            strcpy(szReadName, szClass);
            strcat(szReadName, "_CBZLINESPlugin");
            if (!PrfQueryProfileData(hIni,
                                     "UserOptionsData",
                                     szReadName,
                                     pPluginShare,
                                     &szData))
            {
                pPluginShare->lActiveLineColor = 121 * 65536 + 127;
                pPluginShare->lActiveShadowColor = 255 * (65536 + 1);
                pPluginShare->lInactiveLineColor = 100 * (65536 + 256 + 1);
                pPluginShare->lInactiveShadowColor = 204 * (65536 + 256 + 1);
                pPluginShare->bActiveEnabled = TRUE;
                pPluginShare->bInactiveEnabled = TRUE;
                pPluginShare->lLineStyle = 7;

                if (!PrfWriteProfileData(hIni,
                                         "UserOptionsData",
                                         szReadName,
                                         pPluginShare,
                                         sizeof(PLUGINSHARE)))
                {
                    //not a fatal error.
                }
            }
        }                       //end if

        //copy from shared memory to each windows window words.
        pPluginData->lActiveLineColor = pPluginShare->lActiveLineColor;
        pPluginData->lActiveShadowColor = pPluginShare->lActiveShadowColor;
        pPluginData->lInactiveLineColor = pPluginShare->lInactiveLineColor;
        pPluginData->lInactiveShadowColor = pPluginShare->lInactiveShadowColor;
        pPluginData->bActiveEnabled = pPluginShare->bActiveEnabled;
        pPluginData->bInactiveEnabled = pPluginShare->bInactiveEnabled;
        pPluginData->lLineStyle = pPluginShare->lLineStyle;
    }                           //end else

    return TRUE;
}
Exemple #26
0
/* Main processing of the parent process
 * returns TRUE if restarting
 */
static char master_main()
{
    server_rec *s = ap_server_conf;
    ap_listen_rec *lr;
    parent_info_t *parent_info;
    char *listener_shm_name;
    int listener_num, num_listeners, slot;
    ULONG rc;

    printf("%s \n", ap_get_server_version());
    set_signals();

    if (ap_setup_listeners(ap_server_conf) < 1) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
                     "no listening sockets available, shutting down");
        return FALSE;
    }

    /* Allocate a shared memory block for the array of listeners */
    for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) {
        num_listeners++;
    }

    listener_shm_name = apr_psprintf(pconf, "/sharemem/httpd/parent_info.%d", getpid());
    rc = DosAllocSharedMem((PPVOID)&parent_info, listener_shm_name,
                           sizeof(parent_info_t) + num_listeners * sizeof(listen_socket_t),
                           PAG_READ|PAG_WRITE|PAG_COMMIT);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure allocating shared memory, shutting down");
        return FALSE;
    }

    /* Store the listener sockets in the shared memory area for our children to see */
    for (listener_num = 0, lr = ap_listeners; lr; lr = lr->next, listener_num++) {
        apr_os_sock_get(&parent_info->listeners[listener_num].listen_fd, lr->sd);
    }

    /* Create mutex to prevent multiple child processes from detecting
     * a connection with apr_poll()
     */

    rc = DosCreateMutexSem(NULL, &ap_mpm_accept_mutex, DC_SEM_SHARED, FALSE);

    if (rc) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, APR_FROM_OS_ERROR(rc), s,
                     "failure creating accept mutex, shutting down");
        return FALSE;
    }

    parent_info->accept_mutex = ap_mpm_accept_mutex;

    /* Allocate shared memory for scoreboard */
    if (ap_scoreboard_image == NULL) {
        void *sb_mem;
        rc = DosAllocSharedMem(&sb_mem, ap_scoreboard_fname,
                               ap_calc_scoreboard_size(),
                               PAG_COMMIT|PAG_READ|PAG_WRITE);

        if (rc) {
            ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf,
                         "unable to allocate shared memory for scoreboard , exiting");
            return FALSE;
        }

        ap_init_scoreboard(sb_mem);
    }

    ap_scoreboard_image->global->restart_time = apr_time_now();
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		"%s configured -- resuming normal operations",
		ap_get_server_version());
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
		"Server built: %s", ap_get_server_built());
#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
		"AcceptMutex: %s (default: %s)",
		apr_proc_mutex_name(accept_mutex),
		apr_proc_mutex_defname());
#endif
    if (one_process) {
        ap_scoreboard_image->parent[0].pid = getpid();
        ap_mpm_child_main(pconf);
        return FALSE;
    }

    while (!restart_pending && !shutdown_pending) {
        RESULTCODES proc_rc;
        PID child_pid;
        int active_children = 0;

        /* Count number of active children */
        for (slot=0; slot < HARD_SERVER_LIMIT; slot++) {
            active_children += ap_scoreboard_image->parent[slot].pid != 0 &&
                !ap_scoreboard_image->parent[slot].quiescing;
        }

        /* Spawn children if needed */
        for (slot=0; slot < HARD_SERVER_LIMIT && active_children < ap_daemons_to_start; slot++) {
            if (ap_scoreboard_image->parent[slot].pid == 0) {
                spawn_child(slot);
                active_children++;
            }
        }

        rc = DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &proc_rc, &child_pid, 0);

        if (rc == 0) {
            /* A child has terminated, remove its scoreboard entry & terminate if necessary */
            for (slot=0; ap_scoreboard_image->parent[slot].pid != child_pid && slot < HARD_SERVER_LIMIT; slot++);

            if (slot < HARD_SERVER_LIMIT) {
                ap_scoreboard_image->parent[slot].pid = 0;
                ap_scoreboard_image->parent[slot].quiescing = 0;

                if (proc_rc.codeTerminate == TC_EXIT) {
                    /* Child terminated normally, check its exit code and
                     * terminate server if child indicates a fatal error
                     */
                    if (proc_rc.codeResult == APEXIT_CHILDFATAL)
                        break;
                }
            }
        } else if (rc == ERROR_CHILD_NOT_COMPLETE) {
            /* No child exited, lets sleep for a while.... */
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL);
        }
    }

    /* Signal children to shut down, either gracefully or immediately */
    for (slot=0; slot<HARD_SERVER_LIMIT; slot++) {
      kill(ap_scoreboard_image->parent[slot].pid, is_graceful ? SIGHUP : SIGTERM);
    }

    DosFreeMem(parent_info);
    return restart_pending;
}
ULONG CopyTempFileData2ClipBoard(void)
{
  APIRET rc;
  ULONG Result = NO_ERROR, MsgID;
  PSZ pszMem, p;
  FILE *fp;
  int c;

  if (NULL == (fp = fopen(TempOutFile, "rb")))
  {
   /* result handled by MainDlgProc() */
   return ERROR_OPEN_FAILED;
  }
  else
  {
    rc = DosAllocSharedMem((PVOID) &pszMem,
                           NULL, (ULONG)FileSize(fp, NULL)+1,
                           PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE);

    if (NO_ERROR != rc)
    {
     Result = ERROR_OPEN_FAILED;
    }
    else
    {
     p = pszMem;
     while (EOF != (c = fgetc(fp)))
      *p++ = (CHAR) c;
    }

    fclose(fp);

    *p = 0; /* signal end of data! */

    if (WinOpenClipbrd(Hab))
    {

      WinEmptyClipbrd(Hab);
      if (FALSE == WinSetClipbrdData(Hab,
                                     (ULONG) pszMem,
                                     CF_TEXT,
                                     CFI_POINTER))
       Result = ERROR_ACCESS_DENIED;

      WinCloseClipbrd(Hab);

    }
    else
     Result = ERROR_ACCESS_DENIED;

  }
  if (NO_ERROR != Result)
  {
     switch(Result)
     {

      case ERROR_ACCESS_DENIED:
        MsgID = IDS_NO_CLIPBOARD_ACCESS;
       break;

      default:
        MsgID = IDS_GENERAL_PROCESS_FAILURE;
       break;

     }

     Len = WinLoadString(Hab, hRessourceModule, MsgID,
                         MSGSTRN_MAXLEN, Msg);
     WinMessageBox(HWND_DESKTOP, hwndMainDialog, Msg, NULL, 0L, MB_ERROR | MB_OK);
  }

  return Result;
}
Exemple #28
0
VOID InitProg(INT iArgc, PSZ rgArgv[])
{
APIRET    rc;
BYTE      szTranslate[256];
INT       iArg;
ULONG     ulLVB;
USHORT    uscbLVB;
ULONG     ulDataSize;
ULONG     ulParmSize;
BOOL      fSetParms = FALSE;
ULONG     ulParm;


   memset(szTranslate, 0, sizeof szTranslate);

   /*
      Determine if we run in the foreground
   */
   rc = VioGetBuf(&ulLVB, &uscbLVB, (HVIO)0);
   if (rc)
      fForeGround = FALSE;
   else
      fForeGround = TRUE;

   if (fForeGround)
      printf("FAT32 cache helper version %s.\n", FAT32_VERSION);
   else
      WriteLogMessage("FAT32 task detached");

   rc = DosGetNamedSharedMem((PVOID *)&pOptions, SHAREMEM, PAG_READ|PAG_WRITE);
   if (!rc)
      {
      fActive = TRUE;
      WriteLogMessage("Shared memory found!");
      }
   else
      {
      rc = DosAllocSharedMem((PVOID *)&pOptions, SHAREMEM, sizeof (LWOPTS), PAG_COMMIT|PAG_READ|PAG_WRITE);
      if (rc)
         DosExit(EXIT_PROCESS, 1);
      memset(pOptions, 0, sizeof pOptions);
      pOptions->bLWPrio = PRTYC_IDLETIME;
      WriteLogMessage("Shared memory allocated!");
      }

   ulDataSize = sizeof f32Parms;
   rc = DosFSCtl(
      (PVOID)&f32Parms, ulDataSize, &ulDataSize,
      NULL, 0, &ulParmSize,
      FAT32_GETPARMS, "FAT32", -1, FSCTL_FSDNAME);
   if (rc)
      {
      printf("DosFSCtl, FAT32_GETPARMS failed, rc = %d\n", rc);
      DosExit(EXIT_PROCESS, 1);
      }
   if (strcmp(f32Parms.szVersion, FAT32_VERSION))
      {
      printf("ERROR: FAT32 version (%s) differs from CACHEF32 version (%s)\n", f32Parms.szVersion, FAT32_VERSION);
      DosExit(EXIT_PROCESS, 1);
      }

   for (iArg = 1; iArg < iArgc; iArg++)
      {
      strupr(rgArgv[iArg]);
      if (rgArgv[iArg][0] == '/' || rgArgv[iArg][0] == '-')
         {
         switch (rgArgv[iArg][1])
            {
            case '?' :
               printf("USAGE: CACHEF32 [options]\n");
               printf("/Q (Quit)\n");
               printf("/N do NOT load lazy write deamon.\n");
               printf("/D:diskidle in millisecs.\n");
               printf("/B:bufferidle in millisecs.\n");
               printf("/M:maxage in millisecs.\n");
               printf("/R:d:,n sets read ahead sector count for drive d: to n.\n");
               printf("/FS use short file names internally.\n");
               printf("/FL use long file names internally.\n");
               printf("/L:on|off set lazy writing on or off.\n");
               printf("/P:1|2|3|4 Set priority of Lazy writer\n");
               DosExit(EXIT_PROCESS, 0);
               break;

            case 'P':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("Missing : after /P\n");
                  DosExit(EXIT_PROCESS, 1);
                  }
               if (rgArgv[iArg][3] < '1' ||
                   rgArgv[iArg][3] > '4')
                  {
                  printf("Lazy write priority should be from 1 to 4!\n");
                  DosExit(EXIT_PROCESS, 1);
                  }
               pOptions->bLWPrio = rgArgv[iArg][3] - '0';
               break;


            case 'N':
               fLoadDeamon = FALSE;
               break;

            case 'T':
               printf("The /T option is no longer supported.\n");
               printf("Please read the documentation.\n");
               break;

            case 'Q' :
               if (fActive)
                  {
                  if (pOptions->fTerminate)
                     printf("Terminate request already set!\n");
                  pOptions->fTerminate = TRUE;
                  printf("Terminating CACHEF32.EXE...\n");
                  DosExit(EXIT_PROCESS, 0);
                  }
               printf("/Q is invalid, CACHEF32 is not running!\n");
               DosExit(EXIT_PROCESS, 1);
               break;
            case 'D':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulDiskIdle = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'B':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulBufferIdle = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'M':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulMaxAge = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'R':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               SetRASectors(&rgArgv[iArg][3]);
               break;
            case 'F':
               if (rgArgv[iArg][2] == 'S')
                  f32Parms.fUseShortNames = TRUE;
               else if (rgArgv[iArg][2] == 'L')
                  f32Parms.fUseShortNames = FALSE;
               else
                  {
                  printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               fSetParms = TRUE;
               break;

            case 'L':
               if (!stricmp(&rgArgv[iArg][2], ":ON"))
                  {
                  rc = DosFSCtl(NULL, 0, NULL,
                              NULL, 0, NULL,
                     FAT32_STARTLW, "FAT32", -1, FSCTL_FSDNAME);
                  if (rc)
                     printf("Warning: Lazy writing is already active or cachesize is 0!\n");
                  }
               else if (!stricmp(&rgArgv[iArg][2], ":OFF"))
                  {
                  rc = DosFSCtl(NULL, 0, NULL,
                              NULL, 0, NULL,
                     FAT32_STOPLW, "FAT32", -1, FSCTL_FSDNAME);
                  if (rc)
                     printf("Warning: Lazy writing is not active!\n");
                  }
               else
                  {
                  printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               break;

            default :
               printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
               DosExit(EXIT_PROCESS, 1);
               break;
            }

         }
      }

   if (LoadTranslateTable())
      fSetParms = TRUE;

   if (fSetParms)
      {
      if (f32Parms.ulDiskIdle < f32Parms.ulBufferIdle)
         {
         printf("DISKIDLE must be greater than BUFFERIDLE\n");
         DosExit(EXIT_PROCESS, 1);
         }

      ulParmSize = sizeof f32Parms;
      rc = DosFSCtl(
         NULL, 0, &ulDataSize,
         (PVOID)&f32Parms, ulParmSize, &ulParmSize,
         FAT32_SETPARMS, "FAT32", -1, FSCTL_FSDNAME);
      if (rc)
         {
         printf("DosFSCtl FAT32_SETPARMS, failed, rc = %d\n", rc);
         DosExit(EXIT_PROCESS, 1);
         }
      }

   ulDriveMap = GetFAT32Drives();
   if (!fActive)
      {
      if (!ulDriveMap)
         {
         printf("FAT32: No FAT32 partitions found, aborting...\n");
         DosExit(EXIT_PROCESS, 1);
         }
      }



   /*
      Query parms
   */

   if (fActive || !f32Parms.usCacheSize)
      {
      if (fActive)
         {
         printf("CACHEF32 is already running.\n");
         printf("Current priority is %s.\n", rgPriority[pOptions->bLWPrio]);
         }

      if (!f32Parms.fLW)
         printf("LAZY WRITING is NOT active!\n\n");
      else
         {
         printf("\n");
         printf("DISKIDLE  : %lu milliseconds.\n", f32Parms.ulDiskIdle * TIME_FACTOR);
         printf("BUFFERIDLE: %lu milliseconds.\n", f32Parms.ulBufferIdle * TIME_FACTOR);
         printf("MAXAGE    : %lu milliseconds.\n", f32Parms.ulMaxAge * TIME_FACTOR);
         }

      printf("\n");
      ShowRASectors();
      printf("\n");
      printf("CACHE has space for %u sectors\n", f32Parms.usCacheSize);
      printf("CACHE contains %u sectors\n", f32Parms.usCacheUsed);
      printf("There are %u dirty sectors in cache.\n", f32Parms.usDirtySectors);
      if (f32Parms.usPendingFlush > 0)
         printf("%u sectors are in pending flush state.\n", f32Parms.usPendingFlush);
      printf("The cache hits ratio is %3d%%.\n",
         f32Parms.ulTotalHits * 100 / f32Parms.ulTotalReads);
      if (f32Parms.fUseShortNames)
         {
         printf("Internally, short names are used.\n");
         printf("All files are visible in DOS sessions.\n");
         }
      else
         {
         printf("Internally, long names are used.\n");
         printf("Files and directories with long names are hidden for DOS.\n");
         }
      printf("FAT32.IFS has currently %u GDT segments allocated.\n",
         f32Parms.usSegmentsAllocated);
      }

   return;
}
/*********************************************************************
 *  Name: EditCopy
 *
 *  Description : Processes the Edit menu's Copy item.
 *
 *  Concepts : Called whenever Copy from the Edit menu is selected
 *             Sends a MLM_COPY message to the MLE control.
 *
 *  API's : WinSendMsg
 *
 *  Parameters : mp1 - Message parameter
 *             : mp2 - Message parameter
 *
 *  Returns: Void
 *
 ****************************************************************/
VOID EditCopy(MPARAM mp1, MPARAM mp2)
{
   HAB hab;
   PCHAR pchClipText, pText;
   APIRET rc;
   ULONG  BidiAttr;
   BOOL   fSetClipAttr;
   LONG   Offset =0;

      rc = DosAllocSharedMem ( (PPVOID) &pchClipText,
                    NULL,
                    sizeof(szPasteText),
                    (PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE) );

      if (rc) {
          DosBeep(100,100);
          return;
          } /* endif */

      hab =  WinQueryAnchorBlock( hwndMain);

//BIDI
//
// Load the national strings from the resource file.
// These will be copied to the clipbaord.
//
      if (WinQueryCp(HMQ_CURRENT) == 864) Offset = ARA_OFF;

      WinLoadString( hab, NULLHANDLE, IDS_COPYVISUALTEXT+Offset,
                     127, szCopyVisualText);
      WinLoadString( hab, NULLHANDLE, IDS_COPYIMPLICITTEXT+Offset,
                     127, szCopyImplicitText);

      //
      // Check if we have to SET the Clipboard Bidi Attribute
      // and if so, with which value.
      //
      switch(SHORT1FROMMP(mp1)) {
      case IDM_EDITCOPY_NOCONV:
         BidiAttr     = 0L;
         pText        = szCopyImplicitText;
         fSetClipAttr = TRUE;
         break;

      case IDM_EDITCOPY_CONV_VISUAL:
         BidiAttr     = BDA_TEXTTYPE_VISUAL | BDA_INIT | BDA_LEVEL ;
         pText        = szCopyVisualText;
         fSetClipAttr = TRUE;
         break;

      case IDM_EDITCOPY_CONV_IMPLICIT:
         BidiAttr     = BDA_TEXTTYPE_IMPLICIT | BDA_INIT | BDA_LEVEL;
         pText        = szCopyImplicitText;
         fSetClipAttr = TRUE;
         break;

      case IDM_EDITCOPY_AUTOCONV:
      default:
         pText        = szCopyImplicitText;
         fSetClipAttr = FALSE;
         break;

      }  /* end switch*/

      //
      // Copy the 'relevant' text to the memory that we are
      // going to hand to the clipboard.
      //
      strcpy(pchClipText, pText );

      /* Now, make give this text to the clipboard. */
      hab =  WinQueryAnchorBlock( hwndMain);
      WinOpenClipbrd  ( hab ) ;
      WinEmptyClipbrd ( hab ) ;
      WinSetClipbrdData ( hab, (ULONG) pchClipText, CF_TEXT, CFI_POINTER) ;


      //
      // If conversion is required, mark what kind of conversion
      // (or none) is required.
      //
      if (fSetClipAttr)
          WinSetLangInfo (NULLHANDLE,
                          LI_BD_CLIP_ATTR,
                          BidiAttr,
                          0L,
                          (ULONG)CF_TEXT,
                          0L);


      WinCloseClipbrd ( hab ) ;


}   /*   End of EditCopy()                                              */