Exemplo n.º 1
0
void cide(struct kill_list *klp)
{
    int pidi, rc;

    if (klp->sigval == SIG_KILL)
      for (pidi = 0; klp->pid[pidi] && pidi < MAXPID; pidi++)
        if ( (rc = DosKillProcess(1, klp->pid[pidi])) )
          {
             printf("kill: DosKillProcess(1, %d) failed.  rc = %d\n",
                     klp->pid[pidi], rc);
             return;
          }
        else
          printf("KillProcess sent to process %d\n", klp->pid[pidi]);
#ifdef I16
    else
      if (klp->sigval == SIG_PFLG_A || klp->sigval == SIG_PFLG_B ||
          klp->sigval == SIG_PFLG_C)
        for (pidi = 0; klp->pid[pidi] && pidi < MAXPID; pidi++)
          if ((rc=DosFlagProcess(klp->pid[pidi],1,klp->sigval-SIG_PFLG_A,0)))
            {
               printf("kill: DosFlagProcess(%d, 1, %d, 0) failed. rc = %d\n",
                      klp->pid[pidi], rc);
               return;
            }
          else
            printf("User flag %c sent to process %d\n",
                   'A' + klp->sigval - SIG_PFLG_A, klp->pid[pidi]);
#endif
}
Exemplo n.º 2
0
/* Closes/kills process. The handle is still valid until you
 * catch it with hb_fsProcessValue.
 */
HB_BOOL hb_fsProcessClose( HB_FHANDLE hProcess, HB_BOOL fGentle )
{
   HB_BOOL fResult = HB_FALSE;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessClose(%p, %d)", ( void * ) ( HB_PTRDIFF ) hProcess, fGentle ) );

#if defined( HB_OS_WIN )
{
   HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess );

   if( hProc )
   {
      if( TerminateProcess( hProc, fGentle ? 0 : 1 ) )
         fResult = HB_TRUE;
      hb_fsSetIOError( fResult, 0 );
      /* hProc has to be closed by hb_fsProcessValue() */
      /* CloseHandle( hProc ); */
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif ( defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) ) || \
      ( defined( HB_OS_OS2 ) && defined( __GNUC__ ) )
{
   pid_t pid = ( pid_t ) hProcess;
   if( pid > 0 )
   {
      if( kill( pid, fGentle ? SIGTERM : SIGKILL ) == 0 )
         fResult = HB_TRUE;
      hb_fsSetIOError( fResult, 0 );
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_OS2 )
{
   PID pid = ( PID ) hProcess;

   HB_SYMBOL_UNUSED( fGentle );

   if( pid > 0 )
   {
      if( DosKillProcess( DKP_PROCESS, pid ) == NO_ERROR )
         fResult = HB_TRUE;
      hb_fsSetIOError( fResult, 0 );
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#else
{
   int iTODO; /* TODO: for given platform */

   HB_SYMBOL_UNUSED( hProcess );
   HB_SYMBOL_UNUSED( fGentle );
   hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#endif
   return fResult;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
   APIRET   rc;
   short    i = 1;
   PID      pid;

   if(argc < 2)
   {
      puts("Usage: Kill <pid> [pid] ...");
      puts("Note: The 'pid' must be specified in hex (same as pstat uses).");
      return 1;
   }

   while(i < argc)
   {
      pid = hex2long(argv[i]);
      if((rc = DosKillProcess(1, pid)) != 0)
      {
         printf("Error: DosKillProcess() returned %u\n", rc);
      }
      else
      {
         printf("Process %04x killed successfully.\n", pid);
      }
      i++;
   }

   return 0;
}
Exemplo n.º 4
0
/* Closes/kills process. The handle is still valid until you
 * catch it with hb_fsProcessValue.
 */
HB_BOOL hb_fsProcessClose( HB_FHANDLE hProcess, HB_BOOL fGentle )
{
   HB_BOOL fResult = HB_FALSE;

   HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessClose(%p, %d)", ( void * ) ( HB_PTRUINT ) hProcess, fGentle ) );

#if defined( HB_OS_WIN )
{
   HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess );

   if( hProc )
   {
      fResult = TerminateProcess( hProc, fGentle ? 0 : 1 ) != 0;
      hb_fsSetIOError( fResult, 0 );
      /* hProc has to be closed by hb_fsProcessValue() */
      #if 0
      CloseHandle( hProc );
      #endif
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_OS2 )
{
   PID pid = ( PID ) hProcess;

   if( pid > 0 )
   {
      APIRET ret = DosKillProcess( fGentle ? DKP_PROCESS : DKP_PROCESSTREE, pid );

      fResult = ret == NO_ERROR;
      hb_fsSetError( ( HB_ERRCODE ) ret );
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN )
{
   pid_t pid = ( pid_t ) hProcess;
   if( pid > 0 )
   {
      fResult = kill( pid, fGentle ? SIGTERM : SIGKILL ) == 0;
      hb_fsSetIOError( fResult, 0 );
   }
   else
      hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#else
{
   int iTODO; /* TODO: for given platform */

   HB_SYMBOL_UNUSED( hProcess );
   HB_SYMBOL_UNUSED( fGentle );
   hb_fsSetError( ( HB_ERRCODE ) FS_ERROR );
}
#endif
   return fResult;
}
Exemplo n.º 5
0
PRStatus _PR_KillOS2Process(PRProcess *process)
{
   ULONG ulRetVal;
    if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) {
	return PR_SUCCESS;
    }
    PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
    return PR_FAILURE;
}
Exemplo n.º 6
0
MRESULT EXPENTRY
fnwpWxTaskWidget( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
  MRESULT mrc = 0;
  // get widget data from QWL_USER (stored there by WM_CREATE)
  PXCENTERWIDGET pWidget = (PXCENTERWIDGET)WinQueryWindowPtr( hwnd, QWL_USER );
  // this ptr is valid after WM_CREATE

  switch( msg )
  {
    /*
     * WM_CREATE:
     *      as with all widgets, we receive a pointer to the
     *      XCENTERWIDGET in mp1, which was created for us.
     *
     *      The first thing the widget MUST do on WM_CREATE
     *      is to store the XCENTERWIDGET pointer (from mp1)
     *      in the QWL_USER window word by calling:
     *
     *          WinSetWindowPtr(hwnd, QWL_USER, mp1);
     *
     *      We could use XCENTERWIDGET.pUser for allocating
     *      another private memory block for our own stuff,
     *      for example to be able to store fonts and colors.
     *      We ain't doing this in the minimal sample.
     */

    case WM_CREATE:
      WinSetWindowPtr(hwnd, QWL_USER, mp1);
      pWidget = (PXCENTERWIDGET)mp1;
      if(( !pWidget ) || ( !pWidget->pfnwpDefWidgetProc )) {
        // shouldn't happen... stop window creation!!
        mrc = (MPARAM)TRUE;
      }

      hwndMenu = WinCreateWindow( hwnd, WC_MENU, 0, 0, 0, 0, 0, 0,
                                  hwnd, HWND_TOP, ID_MENU_TASKS, 0, 0 );

      ico_tasks  = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_TASKS  );
      ico_detach = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_DETACH );
      ico_dos    = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_DOS    );
      ico_os2fs  = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_OS2FS  );
      ico_os2vio = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_OS2VIO );
      ico_pm     = WinLoadPointer( HWND_DESKTOP, hmodMe, ID_ICON_PM     );
      break;

    /*
     * WM_BUTTON1CLICK:
     *      clicked on the window
     */

    case WM_BUTTON1CLICK:
    {
      mrc = (MPARAM)WgtControl( pWidget, mp1, mp2 );

      RECTL  rcl;
      POINTL ptl;
      SWP    swp;

      // Check if Ctrl is pressed
      if( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 ) {
        bType = TRUE;
      } else {
        bType = FALSE;
      }

      // Fill it with items
      FillMenu( hwndMenu );

      // Place popup according to xCenter position
      if( pWidget->pGlobals->ulPosition == XCENTER_BOTTOM )
      {
        WinQueryWindowRect( hwnd, &rcl );
        ptl.y = rcl.yTop + 1;
        ptl.x = rcl.xLeft;
        WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 0 );
      }
      else
      {
        WinQueryWindowRect( hwnd, &rcl );
        ptl.y = rcl.yBottom;
        ptl.x = rcl.xLeft;
        WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 0 );
        memset( &swp, 0, sizeof(SWP));
        swp.fl = SWP_SIZE;
        WinSendMsg( hwndMenu, WM_ADJUSTWINDOWPOS, MPFROMP(&swp), 0 );
        ptl.y -= swp.cy;
      }

      // Show menu
      WinPopupMenu( hwnd, hwnd, hwndMenu, ptl.x, ptl.y, 0,
                    PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_HCONSTRAIN | PU_VCONSTRAIN );
      break;
    }

    case WM_COMMAND:
    {
      char      szPid[1024];
      MENUITEM  mi;
      SHORT     id;
      TASKDATA* data;

      // Get menu id and data
      id = SHORT1FROMMP(mp1);
      WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT( id, FALSE ), MPFROMP( &mi ));
      data = (TASKDATA*)mi.hItem;

      // Is it "our" item ??
      if( id >= ID_ITEM_FIRST && id < 10000 )
      {
        if( bType )
        {
          // Ctrl was pressed on icon, kill pid
          if( WinGetKeyState( HWND_DESKTOP, VK_CTRL ) & 0x8000 )
          {
            // Ctrl was pressed on menu item, use external kill
            sprintf( szPid, "Kill this process (%d) using fastio$ ?", data->pid );

            if( WinMessageBox( HWND_DESKTOP, hwnd, szPid, "xCenter", 0,
                               MB_ICONQUESTION | MB_YESNO    |
                               MB_APPLMODAL    | MB_MOVEABLE | MB_DEFBUTTON2 ) == MBID_YES )
            {
              DosKillFastIo( data->pid );
            }
          } else {
            sprintf( szPid, "Are you sure that you want to kill this process (%d)?", data->pid );

            if( WinMessageBox( HWND_DESKTOP, hwnd, szPid, "xCenter", 0,
                               MB_ICONQUESTION | MB_YESNO    |
                               MB_APPLMODAL    | MB_MOVEABLE | MB_DEFBUTTON2) == MBID_YES )
            {
              DosKillProcess( DKP_PROCESS, data->pid );
            }
          }
        } else {
          // No Ctrl, its a switch to task
          SwitchTo( data );
        }
      } else {
        // Its Ulrichs menu, forward
        mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 );
      }

      break;
    }

    /*
     * WM_CONTROL:
     *      process notifications/queries from the XCenter.
     */

    case WM_CONTROL:
      mrc = (MPARAM)WgtControl( pWidget, mp1, mp2 );
      break;

    /*
     * WM_PAINT:
     *      well, paint the widget.
     */

    case WM_PAINT:
      WgtPaint( hwnd, pWidget );
      break;

    /*
     * WM_PRESPARAMCHANGED:
     *      A well-behaved widget would intercept
     *      this and store fonts and colors.
     */

    case WM_PRESPARAMCHANGED:
      break;

    case WM_MEASUREITEM:
      return MeasureMenuItem((POWNERITEM)mp2 );

    case WM_DRAWITEM:
      return DrawMenuItem((POWNERITEM)mp2 );

    /*
     * WM_DESTROY:
     *      clean up. This _must_ be passed on to
     *      ctrDefWidgetProc.
     */

    case WM_DESTROY:
      // If we had any user data allocated in WM_CREATE
      // or elsewhere, we'd clean this up here.
      // We _MUST_ pass this on, or the default widget proc
      // cannot clean up.
      WinDestroyWindow ( hwndMenu   );
      WinDestroyPointer( ico_tasks  );
      WinDestroyPointer( ico_detach );
      WinDestroyPointer( ico_dos    );
      WinDestroyPointer( ico_os2fs  );
      WinDestroyPointer( ico_os2vio );
      WinDestroyPointer( ico_pm     );

      mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 );
      break;

    default:
      mrc = pWidget->pfnwpDefWidgetProc( hwnd, msg, mp1, mp2 );
  }

  return (mrc);
}
Exemplo n.º 7
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;
   }
Exemplo n.º 8
0
BOOL ChangeWPS(PCHAR pszUserIni, PCHAR pszSystemIni)
   {
   PCHAR        pcEnv;
   PRFPROFILE   prfProfile;
   BOOL         bSuccess;

   if (*pszSystemIni == '\0')
      prfProfile.pszSysName = pShareInitOS2->pszRootSystemIni;
   else
      prfProfile.pszSysName = pszSystemIni;

   if (*prfProfile.pszSysName == '\0')
      prfProfile.pszSysName = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);

   if (*pszUserIni == '\0')
      {
      prfProfile.pszUserName = pShareInitOS2->pszRootUserIni;
      pShareInitOS2->ulFlag  = pShareInitOS2->ulFlag_Root; // ulFlag f�r Rootdesktop
      }
   else
      prfProfile.pszUserName = pszUserIni;

   if (*prfProfile.pszUserName == '\0')
      prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv);

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

   if (ulOldFlag & CLOSEAPPL)
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=YES");
   else
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO");

   WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0);
   DebugS (1, "HWND_DESKTOP closed");

   if( hevPrfResetLock )
      {
      DosWaitEventSem (hevPrfResetLock, SEM_INDEFINITE_WAIT);
      DosSleep(1000);
      DebugS (1, "hevPrfResetLock released");
      }
   else
      DosSleep(20000);

   bSuccess = PrfReset(hab, &prfProfile);
   DebugULd (1, "PrfReset", "return", bSuccess);

/*
 *  Beim Umschalten auf den Root, egal ob von Sammy oder von WPSamF ausgel�st,
 *  wird die Shell vom PrfReset nicht geschlossen.
 *  Solange die Ursache nicht bekannt ist, bleibt nichts anderes �brig,
 *  als an dieser Stelle symptomatisch vorzugehen und die Shell abzuschie�en.
 */
   if (*pszUserIni == '\0')
      {
      DosSuspendThread (tid1);
      DosKillProcess( DKP_PROCESSTREE, ulShellID );   // sog. Budnik'scher Arschtritt
      DebugS (1, "Shell killed");
      DosResumeThread (tid1);
      }

   if( !bSuccess )
      {
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES");
      DebugS (1, "Desktop set to <WP_DESKTOP>");
      intSammyRetCode = 250;
      WinPostQueueMsg (hmq, WM_QUIT, 0L, 0L);
      }
   else
      ulOldFlag = pShareInitOS2->ulFlag;

   return( bSuccess );
   }
Exemplo n.º 9
0
int main(USHORT argc, PCHAR argv[]) {



   PSZ         szQueueName  = "\\QUEUES\\OF\\DATA\\WAITING\\FOR\\SERVICE";

   HQUEUE      hqSpecialQue = NULLHANDLE; /* Queue handle                   */

   REQUESTDATA Request      = {0};        /* Reques */

   PID         pidOwner     = 0;

   APIRET      rc           = NO_ERROR;   /* Return code                    */



   rc = DosCreateQueue(&hqSpecialQue,    /* Queue handle                    */

             QUE_FIFO |                  /* First-In First-Out order        */

             QUE_CONVERT_ADDRESS,        /* Convert 16-bit addresses to 32  */

             szQueueName);               /* Name of the queue to create     */



   if (rc!= NO_ERROR) {

      printf ("DosCreateQueue error: return code = %u\n", rc);

      return 1;       }



   rc = DosOpenQueue (&pidOwner,         /* PID of queue owner              */

                      &hqSpecialQue,     /* Handle for created queue        */

                      szQueueName);      /* Name of the queue to open       */



   if (rc!= NO_ERROR) {

      printf ("DosOpenQueue error: return code = %u\n", rc);

      return 1;       }



           /* Kill the queue owner (which is us) */



   rc = DosKillProcess(0, pidOwner);

   if (rc != NO_ERROR) {

      printf("DosKillProcess error: return code = %u\n", rc);

      return 1;

   }



   rc = DosSleep(45000L);    /* Dead code */



   return NO_ERROR;

}
Exemplo n.º 10
0
static void ProcessConnection( void )
{
    char                buff[MAX_TRANS];
    ULONG               bytes_read;
    unsigned long       max;
    struct _AVAILDATA   BytesAvail;
    ULONG               PipeState;
    APIRET              rc;
    RESULTCODES         res;
    PID                 dummy;
    char                *dir;

    for( ;; ) {
        DosRead( LnkHdl, buff, sizeof( buff ), &bytes_read );
        if( bytes_read == 0 ) break;
        buff[bytes_read] = '\0';
        switch( buff[0] ) {
        case LNK_CWD:
            rc = 0;
            dir = &buff[1];
            if( isalpha( dir[0] ) && dir[1] == ':' ) {
                rc = DosSetDefaultDisk( toupper( dir[0] ) - ('A' - 1) );
                dir += 2;
            }
            if( rc == 0 && dir[0] != '\0' ) {
                rc = DosSetCurrentDir( dir );
            }
            SendStatus( rc );
            break;
        case LNK_RUN:
            DosSetNPHState( RedirHdl, NP_NOWAIT | NP_READMODE_BYTE );
            DosConnectNPipe( RedirHdl );
            DosSetNPHState( RedirHdl, NP_WAIT | NP_READMODE_BYTE );
            RunCmd( &buff[1] );
            break;
        case LNK_QUERY:
            max = *(unsigned long *)&buff[1];
            if( max > sizeof( buff ) ) max = sizeof( buff );
            --max;
            rc = DosPeekNPipe(RedirHdl, buff, 0, &bytes_read,
                        &BytesAvail, &PipeState );
            if( rc == 0 && BytesAvail.cbpipe != 0 ) {
                DosRead( RedirHdl, &buff[1], max, &bytes_read );
                buff[0] = LNK_OUTPUT;
                DosWrite( LnkHdl, buff, bytes_read + 1, &bytes_read );
            } else {
                rc = DosWaitChild( DCWA_PROCESS, DCWW_NOWAIT, &res,
                                        &dummy, ProcId );
                if( rc != ERROR_CHILD_NOT_COMPLETE ) {
                    DosDisConnectNPipe( RedirHdl );
                    SendStatus( res.codeResult );
                    ProcId = 0;
                } else {
                    /* let someone else run */
                    DosSleep( 1 );
                    buff[0] = LNK_NOP;
                    DosWrite( LnkHdl, buff, 1, &bytes_read );
                }
            }
            break;
        case LNK_CANCEL:
            DosSendSignalException( ProcId, XCPT_SIGNAL_INTR );
            break;
        case LNK_ABORT:
            DosKillProcess( DKP_PROCESSTREE, ProcId );
            break;
        case LNK_DONE:
            return;
        case LNK_SHUTDOWN:
            exit( 0 );
            break;
        }
    }
}
MRESULT EXPENTRY MyWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
   RECTL    clientrect;                     /* Rectangle coordinates        */
   HPS      hpsPaint;
   POINTL   pt;                            /* String screen coordinates    */
   BOOL     Invalid;
   int      Line;
   ERRORID  Err;
   HWND     Focus,Active;
   HMQ      hmqDeb;
   PID      pid,cpid;
   TID      tid,ctid;
   switch( msg )
   {
   case WM_CREATE:
      WinStartTimer(hab,hwnd,1234,500);
      break;                                /* end the application.     */
   case WM_TIMER:
      rc=DosOpen("KBD$", &hKbd, &Action, 0, FILE_NORMAL, FILE_OPEN,
                 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
                 OPEN_FLAGS_FAIL_ON_ERROR, 0);
      if (rc) {
         char Buf[80];
         sprintf(Buf,"Open rc = %d",rc);
         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
                       Buf,
                       "TRAPIT",
                        1234,
                        MB_OK);
      } /* endif */
      Dlen= sizeof(State);
      rc = DosDevIOCtl( hKbd, 4, 0x73, 0, 0, 0, &State, sizeof(State), &Dlen );
      Shift=(USHORT)State;
      DosClose(hKbd);
      Invalid=FALSE;
      if ((State&0x0500)==0x0500) {
         if (Color!=CLR_RED) {
            Color=CLR_RED;
            Invalid=TRUE;
         } /* endif */
         Focus=WinQueryFocus(HWND_DESKTOP);
         Active=WinQueryActiveWindow(HWND_DESKTOP);
         WinQueryWindowProcess(Focus,&pid,&tid);
         hmqDeb=(HMQ)WinQueryWindowULong(Focus,QWL_HMQ);
         if (hmqDeb==hmq) {
            sprintf(Buffer,"Sorry Can't unhang Myself");
         } else {
            DosKillProcess(DKP_PROCESS,pid);
         } /* endif */
      } else {
         if ((State&0x0A00)==0x0A00) {
            if (Color!=CLR_BLUE) {
               Color=CLR_BLUE;
               Invalid=TRUE;
            } /* endif */
            Focus=WinQueryFocus(HWND_DESKTOP);
            Active=WinQueryActiveWindow(HWND_DESKTOP);
            WinQueryWindowProcess(Focus,&pid,&tid);
            hmqDeb=(HMQ)WinQueryWindowULong(Focus,QWL_HMQ);
            if (hmqDeb==hmq) {
               sprintf(Buffer,"Sorry Can't trap Myself");
            } else {
               HENUM hEnum;
               CHAR Class[20];
               HWND Child;
               hEnum = WinBeginEnumWindows(HWND_OBJECT);
               while ( (Child=WinGetNextWindow(hEnum)) != 0) {
                   WinQueryWindowProcess(Child,&cpid,&ctid);
                   if (cpid==pid) {
                       Class[0]=0;
                       WinQueryClassName(Child,sizeof(Class)-1,Class);
                       if (strcmp(Class,"Killer")==0) {
                           if (WinPostMsg(Child,WM_USER+1,0,0)) {
                              DosBeep(1800,80);
                              DosBeep(600,80);
                              DosBeep(1800,80);
                           }
                       } /* endif */
                   } /* endif */
               }
               WinEndEnumWindows(hEnum);
            } /* endif */
         } else {
            if (Color!=CLR_BACKGROUND) {
               Color=CLR_BACKGROUND;
               Invalid=TRUE;
            }
         } /* endif */
      } /* endif */
      if (Invalid) {
            WinInvalidateRect( hwnd, NULL, TRUE );
      } /* endif */
      break;
   case WM_PAINT:
      hpsPaint=WinBeginPaint( hwnd,0, &clientrect );
      WinFillRect( hpsPaint, &clientrect,Color );/* Fill invalid rectangle       */
      pt.x = 10; pt.y = 190;                    /* Set the text coordinates,    */
      GpiCharStringAt( hpsPaint, &pt, (LONG)strlen(Buffer),Buffer);
      for (Line=0;Line<8;Line++ ) {
         pt.x = 10; pt.y = 170-(20*Line);   /* Set the text coordinates,    */
         GpiCharStringAt( hpsPaint, &pt, (LONG)strlen(LabelText[Line]),LabelText[Line]);
      } /* endfor */
      WinEndPaint( hpsPaint );                        /* Drawing is complete   */
      break;
    case WM_CLOSE:
      /******************************************************************/
      /* This is the place to put your termination routines             */
      /******************************************************************/
      WinPostMsg( hwnd, WM_QUIT, 0L, 0L );  /* Cause termination        */
      break;
    default:
      /******************************************************************/
      /* Everything else comes here.  This call MUST exist              */
      /* in your window procedure.                                      */
      /******************************************************************/
      return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  }
  return FALSE;
}