INT main( int argc, char **argv ) { QMSG qmsg; /* Message from message queue */ ULONG flCreate; /* Window creation control flags*/ TID tid; ULONG height; ULONG width; DosExitList( EXLST_ADD, (PFNEXITLIST)CleanUp ); if( argc >= 3 ) { InStream = *argv[1] - ADJUST_HFILE; OutStream = *argv[2] - ADJUST_HFILE; } AbortIf( ( Hab = WinInitialize( 0 )) == 0L ); AbortIf( ( Hmq = WinCreateMsgQueue( Hab, 0 ) ) == 0L ); AbortIf( !WinRegisterClass( Hab, (PSZ)"MyWindow", (PFNWP)MyWindowProc, CS_SIZEREDRAW, 0 ) ); flCreate = FCF_TITLEBAR | FCF_MENU | FCF_SIZEBORDER | FCF_ACCELTABLE | FCF_SHELLPOSITION | FCF_TASKLIST; height = WinQuerySysValue( HWND_DESKTOP, SV_CYMENU ) + 2*WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) + 2*WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ) + WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ); AbortIf( ( hwndFrame = WinCreateStdWindow( HWND_DESKTOP, 0L, &flCreate, "MyWindow", "", 0L, 0, ID_WINDOW, &hwndClient ) ) == 0L ); WinSetWindowText( hwndFrame, TRP_The_WATCOM_Debugger ); width = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); AbortIf( !WinSetWindowPos( hwndFrame, HWND_TOP, 0, WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - height, width / 3, height, SWP_MOVE | SWP_SHOW | SWP_SIZE | SWP_ACTIVATE ) ); AbortIf( DosCreateThread( (PFNTHREAD)ServiceRequests, &tid, stack + STACK_SIZE ) ); while( WinGetMsg( Hab, &qmsg, 0L, 0, 0 ) ) { WinDispatchMsg( Hab, &qmsg ); } WinDestroyWindow(hwndFrame); WinDestroyMsgQueue( Hmq ); WinTerminate( Hab ); return( 1 ); }
VOID Launcher_StartThread( VOID ) { // Сбрасываем переменную для ответа от потока. Thread_responds.Thread_is_created = 0; // Если поток уже создан - выход. CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!Krnl!Launcher"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) return; else DosCreateMutexSem( Semaphore_name, &hmtxAlreadyRunning, DC_SEM_SHARED, 1 ); // Создаем поток. APIRET Thread_is_created = DosCreateThread( &Enhancer.Modules.Launcher->Thread, (PFNTHREAD) Launcher_LauncherThread, 0, 0, THREAD_STACK_SIZE ); // Если он создан - ждем, пока в нем будет создана очередь сообщений. if( Thread_is_created == NO_ERROR ) while( Thread_responds.Thread_is_created == 0 ) { Retard(); } // Если поток создать не удалось - возврат. if( Thread_is_created != NO_ERROR || Thread_responds.Thread_is_created == -1 ) { Enhancer.Modules.Launcher->Thread = 0; return; } // Устанавливаем приоритет потока. WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_PRIORITY, (MPARAM) PRTYC_REGULAR, (MPARAM) PRTYD_QUICK ); // Возврат. return; }
/***************************************************************************** * * Initialize a monitor thread. * *****************************************************************************/ void NEAR StartThread(NPSZ npName) { int rc; NPULONG FAR *pnpParam; TID tid; /* * Allocate the stack. Using malloc here gets us a stack in the data * segment so ss=ds for all routines. */ pnpParam = (NPULONG FAR *) ((char FAR *) malloc(STACKSIZE) + STACKSIZE); /* Push the parameter on the stack. */ *--pnpParam = (NPULONG) npName; /* Create the new thread. */ if (rc = DosCreateThread((PFNTHREAD) MonitorThread, &tid, (void FAR *) pnpParam)) ERRORCHK("DosCreateThread", rc); }
/*--------------------------------------------------------------------------------------*\ * Procedure to create/close a secondary thread. * * Req: * * bCreate ....... Create/close a thread * * pUPS_Thread ... Pointer to a function implementing the thread * * Returns: * * TRUE/FALSE .... If called sucessfully/unsucessfully * \*--------------------------------------------------------------------------------------*/ BOOL UPS_ThreadCreate(BOOL bCreate, PFNTHREAD pUPS_Thread) { static ULONG ulThreadArg=0; static ULONG ulThreadFlag=0; static ULONG ulStackSize=8192; static TID tidThread; if(bCreate==TRUE) { DosCreateThread( /* Create a secondary thread */ &tidThread, /* Thread ID of created thread */ pUPS_Thread, /* Pointer to thread */ ulThreadArg, /* Thread arguments */ ulThreadFlag, /* Thread flags */ ulStackSize); /* Thread's stack size */ return(TRUE); } else { DosKillThread( /* Kill the secondary thread */ tidThread); /* Thread ID of thread to be killed */ return(TRUE); } }
VOID StartInstallerThread( ULONG Action ) { // Если поток уже работает - возврат. if( Installer_Thread.Processing ) return; // Запоминаем, что надо сделать. bzero( &Installer_Thread, sizeof( Installer_Thread ) ); if( Action == NIA_INSTALL ) { Installer_Thread.Install_Enhancer = 1; } else { Installer_Thread.Uninstall_Enhancer = 1; } // Узнаем рабочий каталог. { ULONG Current_drive = 0; ULONG Drive_map = 0; ULONG Length = SIZE_OF_PATH - 3; DosQueryCurrentDisk( &Current_drive, &Drive_map ); Installer_Thread.Current_directory[ 0 ] = (CHAR) Current_drive + 64; Installer_Thread.Current_directory[ 1 ] = ':'; Installer_Thread.Current_directory[ 2 ] = '\\'; DosQueryCurrentDir( 0, &Installer_Thread.Current_directory[ 3 ], &Length ); } // Создаем поток. DosCreateThread( &Installer_Thread.Installer, (PFNTHREAD) Installer_InstallerThread, 0, 0, 32768 ); // Запоминаем, что он работает. Installer_Thread.Processing = 1; // Возврат. return; }
_WCRTLINK int _WCFAR _beginthread( thread_fn *start_address, void _WCFAR *stack_bottom, unsigned stack_size, void _WCFAR *arglist ) /*****************************************************/ { TID tid; APIRET rc; DosSemRequest( &data_sem, -1L ); Routine = start_address; Argument = arglist; StackBottom = stack_bottom; rc = DosCreateThread( begin_thread_helper, (PTID)&tid, (PBYTE)((char _WCFAR *)stack_bottom + stack_size) ); if( rc != 0 ) { DosSemClear( &data_sem ); return( -1 ); } if( tid > __MaxThreads ) { return( -1 ); } return( tid ); }
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; }
static grPMSurface* init_surface( grPMSurface* surface, grBitmap* bitmap ) { PBITMAPINFO2 bit; SIZEL sizl = { 0, 0 }; LONG palette[256]; LOG(( "Os2PM: init_surface( %08lx, %08lx )\n", (long)surface, (long)bitmap )); LOG(( " -- input bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); /* create the bitmap - under OS/2, we support all modes as PM */ /* handles all conversions automatically.. */ if ( grNewBitmap( bitmap->mode, bitmap->grays, bitmap->width, bitmap->rows, bitmap ) ) return 0; LOG(( " -- output bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); bitmap->pitch = -bitmap->pitch; surface->root.bitmap = *bitmap; /* create the image and event lock */ DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE ); DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE ); /* create the image's presentation space */ surface->image_dc = DevOpenDC( gr_anchor, OD_MEMORY, (PSZ)"*", 0L, 0L, 0L ); surface->image_ps = GpiCreatePS( gr_anchor, surface->image_dc, &sizl, PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); GpiSetBackMix( surface->image_ps, BM_OVERPAINT ); /* create the image's PM bitmap */ bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) ); surface->bitmap_header = bit; bit->cbFix = sizeof( BITMAPINFOHEADER2 ); bit->cx = surface->root.bitmap.width; bit->cy = surface->root.bitmap.rows; bit->cPlanes = 1; bit->argbColor[0].bBlue = 255; bit->argbColor[0].bGreen = 0; bit->argbColor[0].bRed = 0; bit->argbColor[1].bBlue = 0; bit->argbColor[1].bGreen = 255; bit->argbColor[1].bRed = 0; bit->cBitCount = (bitmap->mode == gr_pixel_mode_gray ? 8 : 1 ); if (bitmap->mode == gr_pixel_mode_gray) { RGB2* color = bit->argbColor; int x, count; count = bitmap->grays; for ( x = 0; x < count; x++, color++ ) { color->bBlue = color->bGreen = color->bRed = (((count-x)*255)/count); } } else { RGB2* color = bit->argbColor; color[0].bBlue = color[0].bGreen = color[0].bRed = 0; color[1].bBlue = color[1].bGreen = color[1].bRed = 255; } surface->os2_bitmap = GpiCreateBitmap( surface->image_ps, (PBITMAPINFOHEADER2)bit, 0L, NULL, NULL ); GpiSetBitmap( surface->image_ps, surface->os2_bitmap ); bit->cbFix = sizeof( BITMAPINFOHEADER2 ); GpiQueryBitmapInfoHeader( surface->os2_bitmap, (PBITMAPINFOHEADER2)bit ); surface->bitmap_header = bit; /* for gr_pixel_mode_gray, create a gray-levels logical palette */ if ( bitmap->mode == gr_pixel_mode_gray ) { int x, count; count = bitmap->grays; for ( x = 0; x < count; x++ ) palette[x] = (((count-x)*255)/count) * 0x010101; /* create logical color table */ GpiCreateLogColorTable( surface->image_ps, (ULONG) LCOL_PURECOLOR, (LONG) LCOLF_CONSECRGB, (LONG) 0L, (LONG) count, (PLONG) palette ); /* now, copy the color indexes to surface->shades */ for ( x = 0; x < count; x++ ) surface->shades[x] = GpiQueryColorIndex( surface->image_ps, 0, palette[x] ); } /* set up the blit points array */ surface->blit_points[1].x = surface->root.bitmap.width; surface->blit_points[1].y = surface->root.bitmap.rows; surface->blit_points[3] = surface->blit_points[1]; /* Finally, create the event handling thread for the surface's window */ DosCreateThread( &surface->message_thread, (PFNTHREAD) RunPMWindow, (ULONG) surface, 0UL, 32920 ); /* wait for the window creation */ LOCK(surface->image_lock); UNLOCK(surface->image_lock); surface->root.done = (grDoneSurfaceFunc) done_surface; surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle; surface->root.set_title = (grSetTitleFunc) set_title; surface->root.listen_event = (grListenEventFunc) listen_event; /* convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows ); */ return surface; }
int bd_rix(void) { void BuildFieldListRix(FIELDDESCTYPE fieldList[]); #pragma pack(1) ACCESSPACK AP; DOSFILEPACK DFP; CREATEDATAPACK CDP; CREATEINDEXPACK CIP; HANDLEPACK HP; OPENPACK OP; QUERYSETPACK QSP; STATINDEXPACK SIP; // for separate thread reindex percentage done struct EmpRecType { CHAR tag; // record tag, init to SPACE, * means deleted CHAR empID[9]; // SSN (not 0T string) CHAR empLN[16]; // last name CHAR empFN[16]; // first name CHAR empHire[8]; // "YYYYMMDD" (not 0T string) CHAR empDept[6]; // department assigned }; // 56 bytes struct EmpRecType EmpRec; #pragma pack() // no more Bullet-accessed data structures follow time_t startTime, endTime; int display = 0; // display results or not flag int thread = 1; // dispatch reindex in a thread flag int lastNameVar; // used to construct on-the-fly data record... int lastFourVar; // ...that is unique LONG rez; // return value from Bullet CHAR nameIX3[] = ".\\$bd_rix.ix3"; // name of index file created ULONG indexID=0; // handle of index file CHAR keyExpression[128]; // key expression string buffer (159 max) CHAR keyBuffer[68]; // buffer used to store/receive key values CHAR nameData[] = ".\\$bd_rix.dbf";// name of data file created ULONG dataID=0; // handle of data file FIELDDESCTYPE fieldList[5]; // 5 fields used in data record LONG i; // counter CHAR tmpStr[128]; // misc stuff, non-Bullet related CHAR putStr[128]; ULONG tmpU; SIP.func = 0; // init+ref it for DOSX32 compile // set field descriptor info for DBF data file created later memset(fieldList,0,sizeof(fieldList)); // init unused bytes to 0 (required) BuildFieldListRix(fieldList); // Use 300K for workspace in reindex module (min is 48K, max is whatever you want) // Note: larger is not necessarily faster; it depends on the data order #define NEW_XBUFF_SIZE (300*1024) QSP.func = SET_SYSVARS_XB; QSP.item = REINDEX_BUFFER_SIZE; QSP.itemValue = NEW_XBUFF_SIZE; rez = BULLET(&QSP); if (rez) { sprintf(putStr,"Failed SET_SYSVARS_XB #%d (reindex buffer size) call. Err: %d\n",QSP.item,rez); PutMsg(putStr); goto Abend; } tmpU = QSP.itemValue; // 0=default, or 144KB total buffer space if (tmpU == 0) tmpU = (144*1024); sprintf(putStr,"Bullet reindex tmp buffer was %d KB, now %d KB\n", tmpU/1024, NEW_XBUFF_SIZE/1024); PutMsg(putStr); // Delete previous files from any previous run (disregard any error return) DFP.func = DELETE_FILE_DOS; DFP.filenamePtr = nameData; rez = BULLET(&DFP); DFP.filenamePtr = nameIX3; rez = BULLET(&DFP); // Create the data file, a standard DBF (ID=3) as defined in fieldList above. CDP.func = CREATE_DATA_XB; CDP.filenamePtr = nameData; CDP.noFields = 5; CDP.fieldListPtr = fieldList; CDP.fileID = 0x03; rez = BULLET(&CDP); if (rez) { sprintf(putStr,"Failed data file create. Err: %d\n",rez); PutMsg(putStr); goto Abend; } // Open the data file (required before creating an index file for it) OP.func = OPEN_DATA_XB; OP.filenamePtr = nameData; OP.asMode = READWRITE | DENYNONE; rez = BULLET(&OP); if (rez) { sprintf(putStr,"Failed data file open. Err: %d\n",rez); PutMsg(putStr); goto Abend; } dataID = OP.handle; // Create an index file for the data file opened above. // This example uses a multi-part key composed of parts of last name and SSN. strcpy(keyExpression,"SUBSTR(LNAME,1,4)+SUBSTR(SSN,6,4)"); CIP.func = CREATE_INDEX_XB; CIP.filenamePtr = nameIX3; CIP.keyExpPtr = keyExpression; CIP.xbLink = dataID; // the handle of the data file CIP.sortFunction = NLS_SORT | SORT_SET; // sort by NLS (SORT_SET defined in PLATFORM.H) CIP.codePage = CODEPAGE; // code page to use, or 0 for system default CIP.countryCode = CTRYCODE; // country code... CIP.collatePtr = collateTable; // (see #define INT2165xxNS above) CIP.nodeSize = 512; // 512-byte node size (or 1024, 2048 bytes) rez = BULLET(&CIP); if (rez) { sprintf(putStr,"Failed index file create. Err: %d\n",rez); PutMsg(putStr); goto Abend; } // Open the index file (what we just created above). // As with the index-create, the index-open requires the handle of the data // file which this index file indexes. OP.func = OPEN_INDEX_XB; OP.filenamePtr = nameIX3; OP.asMode = READWRITE | DENYNONE; OP.xbLink = dataID; rez = BULLET(&OP); if (rez) { sprintf(putStr,"Failed index file open. Err: %d\n",rez); PutMsg(putStr); goto Abend; } indexID = OP.handle; PutMsg("Display all data accessed (slower results)? (y/N) "); GetMsg(tmpStr); if (*tmpStr=='y') display = 1; #if PLATFORM == ON_OS2 || PLATFORM == ON_WIN32 && FOR_WINDOWS == 0 PutMsg(" Dispatch REINDEX_XB in a separate thread? (Y/n) "); GetMsg(tmpStr); if (*tmpStr=='n') thread = 0; #else thread = 0; #endif PutMsg(" How many records do you want for this test run? "); GetMsg(tmpStr); recs2add = atol(tmpStr); if (recs2add < 1) recs2add = 1; // would you rather end the test? if (recs2add > 9999999) recs2add = 1; // why wait around for 10M? // Add the data records, which are created here, on-the-fly, varying enough // to make unique records. lastFourVar = 1; // 0001 start (as used in strncpy() below) lastNameVar = 0; // 0000 start EmpRec.tag = ' '; // set to not-deleted strncpy(EmpRec.empID,"465990001",9); // only changing last 4 in test strcpy(EmpRec.empLN,"0000LastNameNum"); // only changing first 4 in test strcpy(EmpRec.empFN,"YourFirstName"); // everyone has this first name! strncpy(EmpRec.empHire,"19950527",8); // YYYYMMDD DBF form, no \0 on date strcpy(EmpRec.empDept,"MIS"); // everyone works for MIS! sprintf(putStr," Adding %d records... ",recs2add); PutMsg(putStr); time(&startTime); AP.func = ADD_RECORD_XB; AP.handle = dataID; AP.recPtr = &EmpRec; for (i = 1; i <= recs2add; i++) { sprintf(tmpStr,"%4.4i",lastFourVar++); strncpy(EmpRec.empID+5,tmpStr,4); // update last 4 of empID rez = BULLET(&AP); // AP. already setup if (rez) { sprintf(putStr,"Failed while adding record %d. Err: %d\n",i,rez); PutMsg(putStr); goto Abend; } if (lastFourVar > 9999) { // changes every 10,000 adds lastFourVar = 0; // where name takes carry ... sprintf(tmpStr,"%4.4i",++lastNameVar); strncpy(EmpRec.empLN,tmpStr,4); // update first 4 of empLN } #if FOR_WINDOWS == 1 // deal with message queue every now and then if (i % Q_ADD == 0) DoWinThing(0); // 0=no waiting around #endif } time(&endTime); sprintf(putStr,"took %u secs.\n",(endTime - startTime)); PutMsg(putStr); // Reindex sprintf(putStr,"Reindexing %d records... \r",recs2add); PutMsg(putStr); time(&startTime); AP.func = REINDEX_XB; // this is all there is to reindexing even... AP.handle = indexID; // ...million-record databases AP.keyPtr = keyBuffer; // if dup key error...(see manual for details) AP.nextPtr = NULL; // just this one index file if (thread) { #if PLATFORM == ON_DOSX32 PutMsg(" Threads are not supported on this OS\n"); goto Abend; #elif PLATFORM == ON_OS2 rez = DosCreateThread(&tidRix, (PFNTHREAD) &ThreadRix, (ULONG) &AP, CREATE_READY | STACK_SPARSE, 32768); // min is 8K stack if (rez) { sprintf(putStr,"Could not start reindex thread. Err: %d\n",rez); PutMsg(putStr); goto Abend; } DosSleep(32); // wait a bit to let reindex code set progress to non-zero // could also use a callback routine to put out a reindex % number SIP.func = STAT_INDEX_XB; SIP.handle = indexID; rez = BULLET(&SIP); while (rez==0) { DosSleep(100); sprintf(putStr,"Reindexing %d records... %3.3u%%\r",recs2add,SIP.progress); PutMsg(putStr); rez = BULLET(&SIP); if (SIP.progress==0) { sprintf(putStr,"Reindexing %d records... ",recs2add); PutMsg(putStr); break; } } if (rez) { sprintf(putStr,"Failed progress check. Err: %d\n",rez); PutMsg(putStr); } // continue // Can actually get here _before_ the reindex thread fully exits, but // won't get here until SIP.progress is back to 0. time(&endTime); // It's likely that the thread has exited completely by now, but if // it was blocked after setting SIP.progress to 0 (hung up in the cache, // etc.), then it's possible to get here well before Bullet has exited. // Since calling Bullet while Bullet is busy (for most routines) results // in a rc=640 being returned (mutex timeout), just call this to wait // for the thread to exit completely. Note that this has only been seen // under Win95 (done, but blocked), but this little routine won't hurt. // Ignore any error, which there will be if the thread has indeed exited. // Another option is to use a non-0 mutex-timeout value, via SET_SYSVARS_XB. rez = DosWaitThread(&tidRix,DCWW_WAIT); // ignore error (such as "invalid thread ID") DosSleep(1); // allow the reindex thread to exit BULLET() (and set rez) rez = rezRix; // get return code set by ThreadRix() if (rez) { // rez is already AP.stat sprintf(putStr,"Failed reindex. Err: %d\n",rez); PutMsg(putStr); goto Abend; } sprintf(putStr,"took %u secs.\n",(endTime - startTime)); PutMsg(putStr); #elif PLATFORM == ON_WIN32 hRix = CreateThread(NULL, 32768, // 8KB min. (LPTHREAD_START_ROUTINE) &ThreadRix, (PACCESSPACK) &AP, 0, // immediate start &tidRix); if (hRix==0) { rez = GetLastError(); sprintf(putStr,"Could not start reindex thread. Err: %d\n",rez); PutMsg(putStr); goto Abend; } Sleep(32); // wait a bit to let reindex code set progress to non-zero SIP.func = STAT_INDEX_XB; SIP.handle = indexID; rez = BULLET(&SIP); while (rez==0) { Sleep(100); sprintf(putStr,"Reindexing %d records... %3.3u%%\r",recs2add,SIP.progress); PutMsg(putStr); rez = BULLET(&SIP); if (SIP.progress==0) { sprintf(putStr,"Reindexing %d records... ",recs2add); PutMsg(putStr); break; } } if (rez) { sprintf(putStr,"Failed progress check. Err: %d\n",rez); PutMsg(putStr); } // continue // Can actually get here _before_ the reindex thread fully exits, but // won't get here until SIP.progress is back to 0. time(&endTime); // It's likely that the thread has exited completely by now, but if // it was blocked after setting SIP.progress to 0 (hung up in the cache, // etc.), then it's possible to get here well before Bullet has exited. // Since calling Bullet while Bullet is busy (for most routines) results // in a rc=640 being returned (mutex timeout), just call this to wait // for the thread to exit completely. Note that this has only been seen // under Win95 (done, but blocked), but this little routine won't hurt. // Ignore any error, which there will be if the thread has indeed exited. // Another option is to use a non-0 mutex-timeout value, via SET_SYSVARS_XB. // Error code 640 is documented in BULLET_2.H. rez = WaitForSingleObject(hRix,10*1000); // 10 secs plenty of flush time // ignore error Sleep(32); // allow the reindex thread to exit BULLET() (and set rez) // why 32ms? Only because OS/2 min std resolution is 32ms rez = rezRix; // get return code set by ThreadRix() if (rez) { // rez is already AP.stat sprintf(putStr,"Failed reindex. Err: %d\n",rez); PutMsg(putStr); goto Abend; } sprintf(putStr,"took %u secs.\n",(endTime - startTime)); PutMsg(putStr); #endif } else { // no separate thread, so use callback (especially useful for DOSX32 and Win32s) QSP.func = SET_SYSVARS_XB; QSP.item = CALLBACK_PTR; QSP.itemValue = (ULONG) &CallbackRix; rez = BULLET(&QSP); if (rez) { sprintf(putStr,"Failed SET_SYSVARS_XB #%d (callback address) call. Err: %d\n",QSP.item,rez); PutMsg(putStr); goto Abend; } // now make actual REINDEX_XB call, set up above rez = BULLET(&AP); // rez=0 if okay, or =1 if pack failed with ecode in AP.stat if (rez) { rez = AP.stat; sprintf(putStr,"Failed reindex. Err: %d\n",rez); PutMsg(putStr); goto Abend; } time(&endTime); sprintf(putStr,"Reindexing %d records... took %u secs.\n",recs2add,(endTime - startTime)); PutMsg(putStr); // turn off callback QSP.func = SET_SYSVARS_XB; QSP.item = CALLBACK_PTR; QSP.itemValue = 0; rez = BULLET(&QSP); if (rez) { sprintf(putStr,"Failed SET_SYSVARS_XB #%d (callback clear) call. Err: %d\n",QSP.item,rez); PutMsg(putStr); goto Abend; } } // Get key data memset(keyBuffer,0,sizeof(keyBuffer)); sprintf(putStr," Accessing %d keys... ",recs2add); PutMsg(putStr); if (display) PutMsg("\n"); time(&startTime); AP.func = FIRST_KEY_XB; AP.handle = indexID; AP.keyPtr = keyBuffer; rez = BULLET(&AP); i=0; while (rez==0) { if (display) { sprintf(putStr,"%s %9.9lu\r", keyBuffer, AP.recNo); PutMsg(putStr); } i++; AP.func = NEXT_KEY_XB; rez = BULLET(&AP); #if FOR_WINDOWS == 1 // deal with message queue every now and then if (i % Q_KEY == 0) DoWinThing(0); // 0=no waiting around #endif } time(&endTime); if (display) PutMsg("\n..."); // expected rez is EXB_END_OF_FILE if (rez == EXB_END_OF_FILE) rez=0; if (rez) { sprintf(putStr,"Failed KEY access. Err: %d\n",rez); PutMsg(putStr); goto Abend; } sprintf(putStr,"took %u secs. for %d keys\n",(endTime - startTime),i); PutMsg(putStr); // Get key and record data sprintf(putStr," Accessing %d keys+recs...",recs2add); PutMsg(putStr); if (display) PutMsg("\n"); time(&startTime); AP.func = GET_FIRST_XB; AP.handle = indexID; AP.keyPtr = keyBuffer; AP.recPtr = &EmpRec; rez = BULLET(&AP); i=0; while (rez==0) { if (display) { sprintf(putStr,"%s %9.9lu %s\r", keyBuffer, AP.recNo, &EmpRec); // partial show PutMsg(putStr); } i++; AP.func = GET_NEXT_XB; rez = BULLET(&AP); #if FOR_WINDOWS == 1 // deal with message queue every now and then if (i % Q_GET == 0) DoWinThing(0); // 0=no waiting around #endif } time(&endTime); if (display) PutMsg("\n..."); // expected rez is EXB_END_OF_FILE if (rez == EXB_END_OF_FILE) rez=0; if (rez) { sprintf(putStr,"Failed GET access. Err: %d\n",rez); PutMsg(putStr); goto Abend; } sprintf(putStr,"took %u secs. for %d keys & records\n",(endTime - startTime),i); PutMsg(putStr); // Fatal errors above come straight to here Abend: // Close files if (indexID) { HP.func = CLOSE_INDEX_XB; HP.handle = indexID; rez = BULLET(&HP); if (rez) { sprintf(putStr,"Failed index file close. Err: %d\n",rez); PutMsg(putStr); } } // Unlikely the above could fail, considering how far it has gotten so far! // But logic says that we want to continue closing other open files... if (dataID) { HP.func = CLOSE_DATA_XB; HP.handle = dataID; rez = BULLET(&HP); if (rez) { sprintf(putStr,"Failed data file close. Err: %d\n",rez); PutMsg(putStr); } } return rez; // module exit }
/************************************************************************** * * Name : MyWindowProc * * Description: The window procedure associated with the client area in * the standard frame window. It processes all messages * either sent or posted to the client area, depending on * the message command and parameters. * * Concepts : * * API's : WinLoadString * WinInvalidateRegion * WinPostMsg * WinDefWindowProc * WinBeginPaint * GpiSetColor * GpiSetBackColor * GpiSetBackMix * GpiCharStringAt * WinEndPaint * * Parameters : hwnd = window handle * msg = message code * mp1 = first message parameter * mp2 = second message parameter * * Return : depends on message sent * *************************************************************************/ MRESULT EXPENTRY MyWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) { TID tid; switch( msg ) { case WM_CREATE: /* * Window initialization is performed here in WM_CREATE processing * WinLoadString loads strings from the resource file. */ WinLoadString( Hab, (HMODULE)0L, IDS_HELLO, STRINGLENGTH, szHello ); WinLoadString( Hab, (HMODULE)0L, IDS_1, STRINGLENGTH, sz1 ); WinLoadString( Hab, (HMODULE)0L, IDS_2, STRINGLENGTH, sz2 ); WinLoadString( Hab, (HMODULE)0L, IDS_3, STRINGLENGTH, sz3 ); strcpy( szString, szHello ); /* Copy text Hello into szString*/ break; case WM_COMMAND: /* * When the user chooses option 1, 2, or 3 from the Options pull- * down, the text string is set to 1, 2, or 3, and * WinInvalidateRegion sends a WM_PAINT message. * When Exit is chosen, the application posts itself a WM_CLOSE * message. */ { USHORT command; /* WM_COMMAND command value */ command = SHORT1FROMMP(mp1); /* Extract the command value */ switch (command) { case ID_OPTION1: strcpy( szString, sz1 ); WinInvalidateRegion( hwnd, 0L, FALSE ); strcpy( szString, "Task Started?" ); DosCreateThread( &tid, (PFNTHREAD)DebugIt, 0, 0, STACK_SIZE ); break; case ID_OPTION2: strcpy( szString, sz2 ); WinInvalidateRegion( hwnd, 0L, FALSE ); break; case ID_OPTION3: strcpy( szString, sz3 ); WinInvalidateRegion( hwnd, 0L, FALSE ); break; case ID_EXITPROG: WinPostMsg( hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0 ); break; default: return WinDefWindowProc( hwnd, msg, mp1, mp2 ); } break; } case WM_ERASEBACKGROUND: /* * Return TRUE to request PM to paint the window background * in SYSCLR_WINDOW. */ return (MRESULT)( TRUE ); case WM_PAINT: /* * Window contents are drawn here in WM_PAINT processing. */ { HPS hps; /* Presentation Space handle */ RECTL rc; /* Rectangle coordinates */ POINTL pt; /* String screen coordinates */ char buff[256]; /* Create a presentation space */ hps = WinBeginPaint( hwnd, 0L, &rc ); pt.x = 0; pt.y = 50; /* Set the text coordinates, */ GpiSetColor( hps, CLR_NEUTRAL ); /* colour of the text, */ GpiSetBackColor( hps, CLR_BACKGROUND ); /* its background and */ GpiSetBackMix( hps, BM_OVERPAINT ); /* how it mixes, */ /* and draw the string...*/ GpiCharStringAt( hps, &pt, (LONG)strlen( szString ), szString ); WinEndPaint( hps ); /* Drawing is complete */ break; } case WM_CLOSE: /* * This is the place to put your termination routines */ WinPostMsg( hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 );/* Cause termination*/ break; default: /* * Everything else comes here. This call MUST exist * in your window procedure. */ return WinDefWindowProc( hwnd, msg, mp1, mp2 ); } return (MRESULT)FALSE; } /* End of MyWindowProc */
INT main( INT argc, PCHAR argv[] ) { // Сбрасываем свойства приложения. bzero( &Enhancer, sizeof( ENHANCER ) ); // Определяем приложение в системе. Enhancer.Application = WinInitialize( 0 ); // Если это сделать не удалось - выход. if( Enhancer.Application == NULLHANDLE ) { // Звук - ошибка. WinAlarm( HWND_DESKTOP, WA_ERROR ); // Выход. DosExit( EXIT_PROCESS, 0 ); } // Создаем очередь сообщений. HMQ Message_queue = WinCreateMsgQueue( Enhancer.Application, 0 ); // Если очередь создать не удалось - выход. if( Message_queue == NULLHANDLE ) { // Звук - ошибка. WinAlarm( HWND_DESKTOP, WA_ERROR ); // Выход. WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Проверяем системные настройки. CheckSystemConfig(); // Запускаем составляющие приложения. StdLib_Start(); Strings_Start(); Files_Start(); Environment_Start(); EnhancerProperties_Start(); Loader_Start(); Launcher_Start(); // Узнаем, что надо сделать. if( argc == 2 ) { if( stristr( "hide", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "mini", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "launch", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "enhance", argv[ 1 ] ) ) Enhancer.Enhancer_mode = 1; } // Возможно, надо вызвать окно настроек. if( argc == 2 ) { if( strstr( "ControlCenter", argv[ 1 ] ) ) { CHAR Path_to_ControlCenter[ SIZE_OF_PATH ] = ""; GetCurrentPath( Path_to_ControlCenter ); strcat( Path_to_ControlCenter, "\\Nice-eCS.exe" ); Execute( Path_to_ControlCenter, argv[ 1 ] ); WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Если действие не распознано - выход. if( !Enhancer.Enhancer_mode && !Enhancer.Launcher_mode ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Если окно приложения уже есть - выход. { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!L"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( Enhancer.Enhancer_mode ) Semaphore_name[ strlen( Semaphore_name ) - 1 ] = 'E'; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } else { DosCreateMutexSem( Semaphore_name, &hmtxAlreadyRunning, DC_SEM_SHARED, 1 ); } } // Загрузчик должен запускаться до расширителя. if( Enhancer.Launcher_mode ) { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!E"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Расширитель должен запускаться после загрузчика if( Enhancer.Enhancer_mode ) { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!L"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) != NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Если надо вызвать загрузчик: if( Enhancer.Launcher_mode ) { // Создаем поток для запуска расширителя. DosCreateThread( &Threads.Launcher, (PFNTHREAD) LauncherThread, 0, 0, STACK_SIZE ); } // Если надо вызвать расширитель: if( Enhancer.Enhancer_mode ) { // Пробуем найти окно загрузчика. HWND Launcher_window = NULLHANDLE; CHAR Launcher_title[] = "Nice-OS2!L"; { // Перебираем окна в окне рабочего стола. HENUM Enumeration = WinBeginEnumWindows( WinQueryDesktopWindow( Enhancer.Application, NULLHANDLE ) ); HWND Window = NULLHANDLE; while( ( Window = WinGetNextWindow( Enumeration ) ) != NULLHANDLE ) { // Узнаем заголовок окна. CHAR Window_title[ SIZE_OF_TITLE ] = ""; WinQueryWindowText( WinWindowFromID( Window, FID_TITLEBAR ), SIZE_OF_TITLE, Window_title ); // Если это окно расширителя - запоминаем его. if( strc( Window_title, Launcher_title ) ) { Launcher_window = Window; break; } } WinEndEnumWindows( Enumeration ); } // Если загрузчика нет - выход. // Вообще-то он должен быть, раз найден семафор, но кто знает... if( !Launcher_window ) { WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Создаем потоки, устанавливаем обработчики событий. BYTE Success = NiceLoadEnhancer( Enhancer.Application, 0, Launcher_window ); // Если это сделать не удалось - выход. if( !Success ) { WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Читаем настройки и загружаем изображения в расширитель. // Этот метод выполняется внутри Nice-os2.dll, но так как DLL использует // адресное пространство приложения, все данные остаются в этом приложении. NiceReadSettings( 0 ); // Включаем слежение за сообщениями. NiceRunEnhancer(); } // Создаем окно рабочей области. CHAR Class_name[] = "NiceOS2WndClass!L"; if( Enhancer.Enhancer_mode ) Class_name[ strlen( Class_name ) - 1 ] = 'E'; WinRegisterClass( Enhancer.Application, Class_name, (PFNWP) Enhancer_MainWindowProc, 0, 0 ); // Создаем окно рамки. CHAR MainWindow_title[] = "Nice-OS2!L"; if( Enhancer.Enhancer_mode ) Class_name[ strlen( Class_name ) - 1 ] = 'E'; ULONG Creation_flags = FCF_TITLEBAR | FCF_SYSMENU; Enhancer.Frame_window = WinCreateStdWindow( HWND_DESKTOP, CS_FRAME, &Creation_flags, Class_name, MainWindow_title, 0, NULLHANDLE, 0, &Enhancer.Client_window ); WinShowWindow( Enhancer.Frame_window, 0 ); // Выбираем сообщения из очереди. QMSG Message; bzero( &Message, sizeof( QMSG ) ); while( WinGetMsg( Enhancer.Application, &Message, 0, 0, 0 ) ) WinDispatchMsg( Enhancer.Application, &Message ); // Закрываем окна. WinDestroyWindow( Enhancer.Client_window ); WinDestroyWindow( Enhancer.Frame_window ); // Если вызван расширитель: if( Enhancer.Enhancer_mode ) { // Отключаем обработчики событий, завершаем работу потоков. NiceReleaseEnhancer( Enhancer.Application, 0 ); } // Удаляем файлы отладочной версии. DosForceDelete( "_log.txt" ); DosForceDelete( "XTest.exe" ); // Сбрасываем очередь сообщений. WinDestroyMsgQueue( Message_queue ); // Выход. WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); }
/************************************************************************* * Name : PlayTheWave * * Description : This function initially opens the wave file to be played * and tells the MCD information about the file * that is about to be played. The Samples Per Second, * Bits Per Sample, and the number of channels with which * the waveform file was created has to be told to the MCD. * This function initially fills up the allocated buffer * of the playlist with the wave file. For 0 - MAXBUFF * the wave file is filled into the memory. The Wave file * is read in continously from 0 -MAXBUFF. * This same buffer is dynamically re-filled again and again * by the PlayThread thread. * * Concepts : The wave file is first opened and then continuously read * into the buffer. If the end of the wave file is reached * then we seek to the starting of the wave and keep on reading * the wave file till the buffer fills up. This displays the * double buffering concept because, while the playlist is * continuously looping and playing the wave file, the * playlist buffers are constantly being filled with data from * the wave file in the PlayThread thread. * * * * MMPM/2 API's : mmioOpen * mmioGetHeader * mmioRead * mmioSeek * mciSendCommand * MCI_SET * MCI_CUE * * Parameters : None. * * Return : ulReturn * *************************************************************************/ ULONG PlayTheWave() { MCI_WAVE_SET_PARMS lpWaveSet; ULONG ulReturn; MMAUDIOHEADER mmHeader; int i; long ulBytesRead; memset ( &lpWaveSet, 0, sizeof( MCI_WAVE_SET_PARMS ) ); /* Open the Wave File MyWave.Wav for Reading */ hmmioFileHandle = mmioOpen(WAVE_FILE_NAME, (PMMIOINFO) NULL, MMIO_READ); /* If the Wave File could not be opened */ if (!hmmioFileHandle) { ShowAMessage( IDS_ERROR_TITLE, IDS_CANT_OPEN_WAVE, MB_OK | MB_INFORMATION | MB_MOVEABLE | MB_HELP | MB_APPLMODAL, FALSE ); return ( TRUE ); } /* * Get the Header Information for the file so that we can set the channels, * Samples Per Second and Bits Per Sample to play the memory playlist. */ ulReturn = mmioGetHeader(hmmioFileHandle, (PVOID) &mmHeader, sizeof(MMAUDIOHEADER), (PLONG) &ulBytesRead, (ULONG) NULL, (ULONG) NULL); if (ulReturn != 0 ) return ( ulReturn ); /* Set the WaveSet Structure */ lpWaveSet.ulLevel = 100; lpWaveSet.ulSamplesPerSec = mmHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec; lpWaveSet.usBitsPerSample = mmHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample; lpWaveSet.usChannels = mmHeader.mmXWAVHeader.WAVEHeader.usChannels; lpWaveSet.ulAudio = MCI_SET_AUDIO_ALL; lpWaveSet.hwndCallback = (HWND) NULL; /* Set the Channels for the MCD */ ulReturn = mciSendCommand(usWaveDeviceId, MCI_SET, MCI_WAIT | MCI_WAVE_SET_CHANNELS, (PVOID) &lpWaveSet, (USHORT)NULL); if (ulReturn != 0 ) return ( ulReturn ); /* Set the Samples Per Second */ ulReturn = mciSendCommand(usWaveDeviceId, MCI_SET, MCI_WAIT | MCI_WAVE_SET_SAMPLESPERSEC, (PVOID) &lpWaveSet, (USHORT)NULL); if (ulReturn != 0 ) return ( ulReturn ); /* Set the Bits per Sample */ ulReturn = mciSendCommand(usWaveDeviceId, MCI_SET, MCI_WAIT | MCI_WAVE_SET_BITSPERSAMPLE, (PVOID) &lpWaveSet, (USHORT)NULL); if (ulReturn != 0 ) return ( ulReturn ); /* From 0 - MAXBUFF, fill the memory Playlist buffer with the wave file. */ for (i=0; i<MAXBUFF; i++) { ulBytesRead = mmioRead(hmmioFileHandle, (HPSTR) achDataBuffer[i], MAXSIZE); /* * If the end of the wave file is reached then Seek to the starting * of the wave file and start reading the wave into the appropriate * buffer */ if (ulBytesRead < MAXSIZE) { mmioSeek(hmmioFileHandle, 0, SEEK_SET); ulBytesRead = mmioRead(hmmioFileHandle, (HPSTR) achDataBuffer[i], MAXSIZE); } } /* * Create the thread that will maintain the playlist buffer */ fEndPlay = FALSE; if ( DosCreateThread ( &tidPlayThread, (PFNTHREAD) PlayThread, 0L, 0L, 8192L)) return ( TRUE ); return ( FALSE ); }
void StartProg( const char *cmd, const char *prog, char *full_args, char *dos_args ) { const char *src; char *dst; USHORT drive; ULONG map; USHORT len; USHORT tid; USHORT rc; char buff[BSIZE]; seg_offset where; char *cmd_tail; /* unused parameters */ (void)cmd; MaxThread = 0; GrowArrays( 1 ); src = prog; dst = UtilBuff; DosQCurDisk( &drive, &map ); if( src[0] == '\0' || src[1] == '\0' || src[1] != ':' ) { *dst++ = drive - 1 + 'A'; *dst++ = ':'; } else { *dst++ = *src++; *dst++ = *src++; } if( src[0] != '\\' ) { ++dst; len = BUFF_SIZE - ( dst - UtilBuff ); DosQCurDir( drive, (PBYTE)dst, &len ); dst[-1] = '\\'; if( *dst == '\\' || *dst == '\0' ) { *dst = '\0'; } else { while( *dst != '\0' ) { ++dst; } *dst++ = '\\'; } } strcpy( dst, src ); dst = UtilBuff + strlen( UtilBuff ) + 1; cmd_tail = dst; strcpy( dst, full_args ); dst += strlen( dst ); *++dst = '\0'; /* Need two nulls at end */ LoadProg( UtilBuff, cmd_tail ); Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] ); Output( UtilBuff ); Output( "\r\n" ); Buff.pid = Pid; Buff.tid = 1; Buff.cmd = PT_CMD_STOP; LibLoadPTrace( &Buff ); if( OSVer < 0x1400 ) { /* OS/2 2.x already dumped out MainMod as a Module load */ CodeLoad( &Buff, MainMod, ExeName, SAMP_MAIN_LOAD ); } InitialCS = Buff.u.r.CS; rc = DosCreateThread( Sleeper, (PUSHORT)&tid, Stack + STACK_SIZE ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] ); } rc = DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] ); } Buff.pid = Pid; Buff.tid = 1; for( ;; ) { Buff.cmd = PT_CMD_GO; if( LibLoadPTrace( &Buff ) != 0 ) { InternalError( MsgArray[MSG_SAMPLE_7 - ERR_FIRST_MESSAGE] ); } if( Buff.cmd == PT_RET_BREAK && Buff.u.r.DX != 0 ) { /* a mark */ len = 0; Buff.segv = Buff.u.r.DX; Buff.offv = Buff.u.r.AX; for( ;; ) { Buff.cmd = PT_CMD_READ_MEM_D; DosPTrace( &Buff ); buff[len] = Buff.value; if( Buff.cmd != PT_RET_SUCCESS ) buff[len] = '\0'; if( len == BSIZE ) buff[len] = '\0'; if( buff[len] == '\0' ) break; ++len; Buff.offv++; } where.segment = Buff.u.r.CS; where.offset = Buff.u.r.IP; WriteMark( buff, where ); Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } else if( Buff.cmd == PT_RET_BREAK ) { /* common info pass */ CommonAddr.segment = Buff.u.r.CX; CommonAddr.offset = Buff.u.r.BX; Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } if( Buff.cmd == PT_RET_FUNERAL ) break; if( Buff.cmd != PT_RET_LIB_LOADED && Buff.cmd != PT_RET_STOPPED && Buff.cmd != PT_RET_TRD_TERMINATE ) { InternalError( MsgArray[MSG_SAMPLE_6 - ERR_FIRST_MESSAGE] ); break; } RecordSample( Buff.u.r.IP, Buff.u.r.CS, Buff.tid ); } report(); }
unsigned int CallDosDebug( dos_debug __far *buff ) { QMSG qmsg; int num_paints; int i; struct { RECTL rcl; HWND hwnd; } paints[MAX_PAINTS]; HPS ps; char class_name[80]; TID tid; if( !IsPMDebugger() ) { return( Call32BitDosDebug( buff ) ); } switch( buff->Cmd ) { case DBG_C_ClearWatch: case DBG_C_Freeze: case DBG_C_LinToSel: case DBG_C_NumToAddr: case DBG_C_ReadCoRegs: case DBG_C_ReadMemBuf: case DBG_C_ReadMem_D: case DBG_C_ReadReg: case DBG_C_SelToLin: case DBG_C_SetWatch: case DBG_C_ThrdStat: case DBG_C_WriteCoRegs: case DBG_C_WriteMemBuf: case DBG_C_WriteMem_D: case DBG_C_WriteReg: return( Call32BitDosDebug( buff ) ); } switch( buff->Cmd ) { case DBG_C_Go: case DBG_C_SStep: case DBG_C_Term: ReleaseQueue( buff->Pid, buff->Tid ); } DebugReqBuff = buff; StopBuff = *buff; DosSemSet( &DebugDoneSem ); DosSemClear( &DebugReqSem ); num_paints = 0; if( IsPMDebugger() ) { while( WinGetMsg( HabDebugger, &qmsg, 0L, 0, 0 ) || InDosDebug ) { WinQueryClassName( qmsg.hwnd, MAX_CLASS_NAME, class_name ); switch( qmsg.msg ) { case WM_CHAR: if( ( SHORT1FROMMP( qmsg.mp1 ) & KC_VIRTUALKEY ) && ( SHORT2FROMMP( qmsg.mp2 ) == VK_BREAK ) ) { SetBrkPending(); DosCreateThread( StopApplication, &tid, stack2 + STACK_SIZE ); DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 10, tid ); WakeThreads( StopBuff.Pid ); DosSemWait( &StopDoneSem, SEM_INDEFINITE_WAIT ); DosSemSet( &StopDoneSem ); } break; case WM_COMMAND: CantDoIt(); break; default: if( strcmp( class_name, "GUIClass" ) == 0 || strcmp( class_name, "WTool" ) == 0 ) { switch( qmsg.msg ) { case WM_PAINT: if( num_paints >= MAX_PAINTS ) --num_paints; paints[num_paints].hwnd = qmsg.hwnd; ps = WinBeginPaint( qmsg.hwnd, 0, &paints[ num_paints ].rcl ); GpiErase( ps ); WinEndPaint( ps ); num_paints++; break; case WM_BUTTON1DOWN: case WM_BUTTON2DOWN: case WM_BUTTON3DOWN: CantDoIt(); break; case WM_MOUSEMOVE: { HPOINTER hourglass = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ); if( WinQueryPointer( HWND_DESKTOP ) != hourglass ) { WinSetPointer( HWND_DESKTOP, hourglass ); } break; } default: WinDefWindowProc( qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2 ); } } else { WinDispatchMsg( HabDebugger, &qmsg ); } } } } else { DosSemWait( &DebugDoneSem, SEM_INDEFINITE_WAIT ); } switch( buff->Cmd ) { case DBG_N_Exception: case DBG_N_AsyncStop: case DBG_N_Watchpoint: AssumeQueue( buff->Pid, buff->Tid ); break; } for( i = 0; i < num_paints; ++i ) { WinInvalidateRect( paints[i].hwnd, &paints[i].rcl, FALSE ); } return( DebugReqResult ); }
static void initialize_mousetype(SCREEN *sp) { T((T_CALLED("initialize_mousetype()"))); /* Try gpm first, because gpm may be configured to run in xterm */ #if USE_GPM_SUPPORT if (allow_gpm_mouse()) { if (!sp->_mouse_gpm_loaded) { #ifdef HAVE_LIBDL load_gpm_library(sp); #else /* !HAVE_LIBDL */ sp->_mouse_gpm_found = TRUE; sp->_mouse_gpm_loaded = TRUE; #endif } /* * The gpm_fd file-descriptor may be negative (xterm). So we have to * maintain our notion of whether the mouse connection is active * without testing the file-descriptor. */ if (sp->_mouse_gpm_found && enable_gpm_mouse(sp, TRUE)) { sp->_mouse_type = M_GPM; sp->_mouse_fd = *(my_gpm_fd); T(("GPM mouse_fd %d", sp->_mouse_fd)); returnVoid; } } #endif /* USE_GPM_SUPPORT */ /* OS/2 VIO */ #if USE_EMX_MOUSE if (!sp->_emxmouse_thread && strstr(TerminalOf(sp)->type.term_names, "xterm") == 0 && key_mouse) { int handles[2]; if (pipe(handles) < 0) { perror("mouse pipe error"); returnVoid; } else { int rc; if (!sp->_emxmouse_buttons[0]) { char *s = getenv("MOUSE_BUTTONS_123"); sp->_emxmouse_buttons[0] = 1; if (s && strlen(s) >= 3) { sp->_emxmouse_buttons[1] = s[0] - '0'; sp->_emxmouse_buttons[2] = s[1] - '0'; sp->_emxmouse_buttons[3] = s[2] - '0'; } else { sp->_emxmouse_buttons[1] = 1; sp->_emxmouse_buttons[2] = 3; sp->_emxmouse_buttons[3] = 2; } } sp->_emxmouse_wfd = handles[1]; M_FD(sp) = handles[0]; /* Needed? */ setmode(handles[0], O_BINARY); setmode(handles[1], O_BINARY); /* Do not use CRT functions, we may single-threaded. */ rc = DosCreateThread((unsigned long *) &sp->_emxmouse_thread, mouse_server, (long) sp, 0, 8192); if (rc) { printf("mouse thread error %d=%#x", rc, rc); } else { sp->_mouse_type = M_XTERM; } returnVoid; } } #endif /* USE_EMX_MOUSE */ #if USE_SYSMOUSE { struct mouse_info the_mouse; char *the_device = 0; if (isatty(sp->_ifd)) the_device = ttyname(sp->_ifd); if (the_device == 0) the_device = "/dev/tty"; sp->_mouse_fd = open(the_device, O_RDWR); if (sp->_mouse_fd >= 0) { /* * sysmouse does not have a usable user interface for obtaining * mouse events. The logical way to proceed (reading data on a * stream) only works if one opens the device as root. Even in * that mode, careful examination shows we lose events * occasionally. The interface provided for user programs is to * establish a signal handler. really. * * Take over SIGUSR2 for this purpose since SIGUSR1 is more * likely to be used by an application. getch() will have to * handle the misleading EINTR's. */ signal(SIGUSR2, SIG_IGN); the_mouse.operation = MOUSE_MODE; the_mouse.u.mode.mode = 0; the_mouse.u.mode.signal = SIGUSR2; if (ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) { signal(SIGUSR2, handle_sysmouse); the_mouse.operation = MOUSE_SHOW; ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse); #if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) /* FreeBSD > 2.x */ { #ifndef FBIO_GETMODE /* FreeBSD 3.x */ #define FBIO_GETMODE CONS_GET #define FBIO_MODEINFO CONS_MODEINFO #endif /* FBIO_GETMODE */ video_info_t the_video; if (ioctl(sp->_mouse_fd, FBIO_GETMODE, &the_video.vi_mode) != -1 && ioctl(sp->_mouse_fd, FBIO_MODEINFO, &the_video) != -1) { sp->_sysmouse_char_width = the_video.vi_cwidth; sp->_sysmouse_char_height = the_video.vi_cheight; } } #endif /* defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) */ if (sp->_sysmouse_char_width <= 0) sp->_sysmouse_char_width = 8; if (sp->_sysmouse_char_height <= 0) sp->_sysmouse_char_height = 16; sp->_mouse_type = M_SYSMOUSE; returnVoid; } } } #endif /* USE_SYSMOUSE */ #ifdef USE_TERM_DRIVER CallDriver(sp, initmouse); #else /* we know how to recognize mouse events under "xterm" */ if (key_mouse != 0) { if (!strcmp(key_mouse, xterm_kmous) || strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { init_xterm_mouse(sp); } } else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } #endif returnVoid; }
static void initialize_mousetype(void) { static const char *xterm_kmous = "\033[M"; /* Try gpm first, because gpm may be configured to run in xterm */ #if USE_GPM_SUPPORT /* GPM: initialize connection to gpm server */ gpm_connect.eventMask = GPM_DOWN | GPM_UP; gpm_connect.defaultMask = ~(gpm_connect.eventMask | GPM_HARD); gpm_connect.minMod = 0; gpm_connect.maxMod = ~((1 << KG_SHIFT) | (1 << KG_SHIFTL) | (1 << KG_SHIFTR)); if (Gpm_Open(&gpm_connect, 0) >= 0) { /* returns the file-descriptor */ mousetype = M_GPM; SP->_mouse_fd = gpm_fd; return; } #endif /* OS/2 VIO */ #ifdef USE_EMX_MOUSE if (!mouse_thread && strstr(cur_term->type.term_names, "xterm") == 0 && key_mouse) { int handles[2]; if (pipe(handles) < 0) { perror("mouse pipe error"); return; } else { int rc; if (!mouse_buttons[0]) { char *s = getenv("MOUSE_BUTTONS_123"); mouse_buttons[0] = 1; if (s && strlen(s) >= 3) { mouse_buttons[1] = s[0] - '0'; mouse_buttons[2] = s[1] - '0'; mouse_buttons[3] = s[2] - '0'; } } mouse_wfd = handles[1]; M_FD(SP) = handles[0]; /* Needed? */ setmode(handles[0], O_BINARY); setmode(handles[1], O_BINARY); /* Do not use CRT functions, we may single-threaded. */ rc = DosCreateThread((unsigned long *) &mouse_thread, mouse_server, 0, 0, 8192); if (rc) { printf("mouse thread error %d=%#x", rc, rc); return; } else { mousetype = M_XTERM; return; } } } #endif /* we know how to recognize mouse events under "xterm" */ if (key_mouse != 0) { if (!strcmp(key_mouse, xterm_kmous)) { mousetype = M_XTERM; return; } } else if (strstr(cur_term->type.term_names, "xterm") != 0) { (void) _nc_add_to_try(&(SP->_keytry), xterm_kmous, KEY_MOUSE); mousetype = M_XTERM; return; } }
#ifdef EXTENDED_LOG char idLog[4]; char extLog[0x0100]; #endif memset(&p,0,sizeof(struct parm)); p.flag = TRUE; p.start_address = start_address; p.sz = sz; p.thd.icq = icq; p.thd.parm = arglist; strncpy(p.thd.id,id,3); rc = DosCreateThread(&p.thd.tid, (PFNTHREAD) &tidLoader, (ULONG) &p, 0x00000002, stack_size); DBGTrace(rc); if(rc) { icqWriteSysRC(icq,PROJECT,rc,"Error starting thread"); return -rc; } /* Aguarda ate 6 segundos para que a thread inicie */ for(f=0;f<600 && p.flag;f++) DosSleep(10); if(p.flag) { /* Thread nao iniciou */
MRESULT EXPENTRY fnwpNotifyDlg(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2) { static MSG *pMessage; NOTIFYLST *pNotify; ULONG ulSubNumber; ULONG ulGroupNumber; int iMsgLen; USHORT usLength; USHORT usSubCount; ULONG *pulSubNum; char szMessage[80]; int iIndex; static TID tid; BYTE *pData; switch (msg) { case WM_INITDLG: pMessage = (MSG *)mp2; bNotifyLoop = FALSE; WinSendDlgItemMsg(hwnd,NOTIFY_SUB_NUMBER, SPBM_SETLIMITS, (MPARAM)usSubscriberListCount, (MPARAM)1); WinSendDlgItemMsg(hwnd,NOTIFY_MESSAGE,MLM_FORMAT,(MPARAM)MLFIE_WINFMT,(MPARAM)NULL); break; case WM_COMMAND: switch(SHORT1FROMMP(mp1)) { case DID_OK: if (bNotifyLoop) break; WinSendDlgItemMsg(hwnd,NOTIFY_SUB_NUMBER,SPBM_QUERYVALUE,&ulSubNumber,MPFROM2SHORT(0,SPBQ_DONOTUPDATE)); iMsgLen = WinQueryDlgItemTextLength(hwnd,NOTIFY_MESSAGE); // iMsgLen = (int)WinSendDlgItemMsg(hwnd,NOTIFY_MESSAGE,MLM_QUERYTEXTLENGTH,(MPARAM)NULL,(MPARAM)NULL); if (iMsgLen <= 0) { sprintf(szMessage,"Message is too short, length = %u",iMsgLen); MessageBox(hwnd,szMessage); break; } if (astSubList[ulSubNumber].usMaxMsgLen < iMsgLen) { sprintf(szMessage,"Message is to long for defined subscriber, remove at least %u characters.",(iMsgLen - astSubList[ulSubNumber].usMaxMsgLen)); MessageBox(hwnd,szMessage); break; } pNotify = (NOTIFYLST *)&pMessage->byData; pNotify->usSubCount = 1; pNotify->usGroupCount = 0; pNotify->usMsgLen = (USHORT)iMsgLen; pData = &pNotify->byData; iMsgLen = WinQueryDlgItemText(hwnd,NOTIFY_MESSAGE,(iMsgLen + 1),pData); pulSubNum = (ULONG *)(pData + iMsgLen); usSubCount = 0; for (iIndex = 0;iIndex < pNotify->usSubCount;iIndex++) { usSubCount++; *pulSubNum = (ULONG)ulSubNumber; pulSubNum++; } for (iIndex = 0;iIndex < pNotify->usGroupCount;iIndex++) { usSubCount++; *pulSubNum = (ULONG)ulGroupNumber; pulSubNum++; } usLength = ((sizeof(ULONG) * usSubCount) + (USHORT)iMsgLen); pMessage->cbDataSize = (usLength + sizeof(NOTIFYLST) - 1); if (Checked(hwnd,NOTIFY_CONTINUOUSLY)) { pMessage->fMessageType = REQ_NOTIFY; pMessage->cbSize = (pMessage->cbDataSize + sizeof(MSG) - 1); bNotifyLoop = TRUE; pNotifyLoopMsg = pMessage; DosCreateThread(&tid,(PFNTHREAD)NotifyLoopThread,(ULONG)pMessage,0,8192); } else WinDismissDlg(hwnd,TRUE); break; case DID_CANCEL: if (bNotifyLoop) DosKillThread(tid); WinDismissDlg(hwnd,FALSE); break; default: return(WinDefDlgProc(hwnd,msg,mp1,mp2)); } break; default: return(WinDefDlgProc(hwnd,msg,mp1,mp2)); } return(FALSE); }
INT main(INT iArgc, PSZ rgArgv[]) { APIRET rc; ULONG ulParmSize; ULONG ulDataSize; BYTE bPrevPrio; DoCheckDisk(FALSE); InitProg(iArgc, rgArgv); if (fActive) DosExit(EXIT_PROCESS, 0); if (fForeGround) { DoCheckDisk(TRUE); if (!f32Parms.usCacheSize) printf("Cache size has been set to zero, lazy writer will not be started!\n"); else if (fLoadDeamon) StartMe(rgArgv[0]); DosExit(EXIT_PROCESS, 0); } rc = DosFSCtl(NULL, 0, &ulDataSize, NULL, 0, &ulParmSize, FAT32_STOPLW, "FAT32", -1, FSCTL_FSDNAME); rc = DosFSCtl(NULL, 0, &ulDataSize, NULL, 0, &ulParmSize, FAT32_STARTLW, "FAT32", -1, FSCTL_FSDNAME); if (rc) { printf("Starting LW failed, rc = %d\n", rc); exit(1); } signal(SIGBREAK, Handler); signal(SIGTERM, Handler); signal(SIGINT, Handler); rc = DosCreateThread(&pOptions->ulEMTID, EMThread, 0L, 0, 8196); if (rc) printf("DosCreateThread failed, rc = %d\n", rc); rc = DosCreateThread(&pOptions->ulLWTID, LWThread, 0L, 0, 8196); if (rc) printf("DosCreateThread failed, rc = %d\n", rc); ulParmSize = sizeof f32Parms; rc = DosFSCtl( NULL, 0, &ulDataSize, (PVOID)&f32Parms, ulParmSize, &ulParmSize, FAT32_SETPARMS, "FAT32", -1, FSCTL_FSDNAME); bPrevPrio = pOptions->bLWPrio; while (!pOptions->fTerminate) { if (bPrevPrio != pOptions->bLWPrio) { DosSetPriority(PRTYS_THREAD, pOptions->bLWPrio, 0, pOptions->ulLWTID); bPrevPrio = pOptions->bLWPrio; } DosSleep(5000); } DosExit(EXIT_PROCESS, 0); return 0; }