void slowPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE ]; MODULEENTRY moduleEntry; GLOBALENTRY globalEntry; TASKENTRY taskEntry; int count; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Walk the global heap getting information on each entry in it. This retrieves the objects linear address, size, handle, lock count, owner, object type, and segment type */ count = 0; globalEntry.dwSize = sizeof( GLOBALENTRY ); if( GlobalFirst( &globalEntry, GLOBAL_ALL ) ) do { addRandomData( randomState, &globalEntry, sizeof( GLOBALENTRY ) ); count++; } while( count < 70 && GlobalNext( &globalEntry, GLOBAL_ALL ) ); /* Walk the module list getting information on each entry in it. This retrieves the module name, handle, reference count, executable path, and next module */ count = 0; moduleEntry.dwSize = sizeof( MODULEENTRY ); if( ModuleFirst( &moduleEntry ) ) do { addRandomData( randomState, &moduleEntry, sizeof( MODULEENTRY ) ); count++; } while( count < 20 && ModuleNext( &moduleEntry ) ); /* Walk the task list getting information on each entry in it. This retrieves the task handle, parent task handle, instance handle, stack segment and offset, stack size, number of pending events, task queue, and the name of module executing the task. We also call TaskGetCSIP() for the code segment and offset of each task if it's safe to do so (note that this call can cause odd things to happen in debuggers and runtime code checkers because of the way TaskGetCSIP() is implemented) */ count = 0; taskEntry.dwSize = sizeof( TASKENTRY ); if( TaskFirst( &taskEntry ) ) do { addRandomData( randomState, &taskEntry, sizeof( TASKENTRY ) ); if( taskEntry.hTask != GetCurrentTask() ) addRandomValue( randomState, TaskGetCSIP( taskEntry.hTask ) ); count++; } while( count < 100 && TaskNext( &taskEntry ) ); /* Flush any remaining data through */ endRandomData( randomState, 100 ); }
BOOL MyTaskNext( TASKENTRY *te ) { te->dwSize = sizeof( TASKENTRY ); return( TaskNext( te ) ); } /* MyTaskNext */
/************************************************************************** * Function: DWORD FAR PASCAL UTProc(LPVOID, DWORD) * * * * Purpose: Dispatch routine called by 32-bit UT DLL * **************************************************************************/ DWORD FAR PASCAL UTProc (LPVOID lpBuf, DWORD dwFunc) { switch (dwFunc) { case SYNCHSPAWN: { UINT hInst; LPCSTR lpszCmdLine; UINT nCmdShow; /* Retrieve the command line arguments stored in buffer */ lpszCmdLine = (LPSTR) ((LPDWORD)lpBuf)[0]; nCmdShow = (UINT) ((LPDWORD)lpBuf)[1]; /* Start the application with WinExec(). Note that there is a massive bug * with WIN32s in that the environment is not inherited by the command shell. * hence all work with win32s is done through a BAT file. To add to our wows * CreateProcess() in the win32 environment cannot determine when the spawned process has finished. Hence this 16-bit thunk. */ hInst = WinExec (lpszCmdLine, nCmdShow); if( hInst < 32 ) return 0; /* Error - cannot spawn process */ else { TASKENTRY te; int found = 0; te.dwSize = sizeof (TASKENTRY); /* Iterate until the process has finished */ while (found == 0) { found = 1; /* Give processing resouce back to windows */ Yield (); /* See if we can find the process. If not then we have finished */ if (TaskFirst (&te) == FALSE) break; do { /* Found the task; back to the top */ if (te.hInst == hInst) { found = 0; break; } } while (TaskNext (&te)); } } return 1; /* OK status */ } } /* switch (dwFunc) */ return( (DWORD)-1L ); /* We should never get here. */ } /* UTProc() */
static HTASK GetTaskHdl( HANDLE instance ) { TASKENTRY taskinfo; BOOL ret; memset( &taskinfo, 0, sizeof( TASKENTRY ) ); taskinfo.dwSize = sizeof( TASKENTRY ); ret = TaskFirst( &taskinfo ); while( ret ) { if( taskinfo.hInst == instance ) { return( taskinfo.hTask ); } ret = TaskNext( &taskinfo ); } return( NULL ); }
// pre-process input file, creating a tmp file // In order to get the return code of the C pre-processor, I'm // spawing a batch file that invokes CL, and creates a signal file // if it is successful. VOID NEAR DoPreProcess ( ) { char szBuffer[255]; HANDLE hInstCpp; TASKENTRY taskentry; FILE * hFile; CHAR * szTempBatch; CHAR * szTempSig; CHAR * szTempRoot; ERR err = ERR_CPP; // assume error int cbTempFilenames; char * szComSpec; // figure out the names of the temp files // (note: uses OEM char set) szTempRoot = tempnam(".", "~mkt"); // get base name for temp files hFile = fopen(szTempRoot, "w"); // create the file now, to if (hFile == NULL) // reserve this set of names ParseError(ERR_CPP); fclose(hFile); cbTempFilenames = strlen(szTempRoot)+1+3+1; // base name + ext + null szTempBatch = malloc(cbTempFilenames); // for .BAT file strcpy(szTempBatch, szTempRoot); strcat(szTempBatch, ".bat"); szTempSig = malloc(cbTempFilenames); // for .SIG file strcpy(szTempSig, szTempRoot); strcat(szTempSig, ".sig"); szTempFile = malloc(cbTempFilenames); // for pre-processed oupput strcpy(szTempFile, szTempRoot); strcat(szTempFile, ".inp"); // CONSIDER: Check for existence of any of these files, if any exist, then // CONSIDER: try a different base name for the files. // open the temp .BAT file hFile = fopen(szTempBatch, "w"); if (hFile == NULL) goto cleanup2; // all errors after this point should go to 'cleanup' if (fputs(szBatchStart, hFile) < 0) // write the first part goto cleanup; sprintf(szBuffer, "%s %s%s %s>", szCppExe, szCppOpts, szCppDefs, szInputFile); // convert this string to the OEM char set AnsiToOem(szBuffer, szBuffer); // append szTempFile strcat(szBuffer, szTempFile); strcat(szBuffer, "\n"); if (fputs(szBuffer, hFile) < 0) // write the CPP command goto cleanup; sprintf(szBuffer, szBatchEnd, szTempSig); if (fputs(szBuffer, hFile) < 0) // write the error check code goto cleanup; fclose(hFile); hFile = NULL; // file no longer open szComSpec = getenv("COMSPEC"); if (szComSpec == NULL) szComSpec = "command.com"; sprintf(szBuffer, "%s /c %s", szComSpec, szTempBatch); hInstCpp = WinExec(szBuffer, SW_SHOWMINIMIZED); // shell the pre-processor if (hInstCpp < 32) // if error spawning pre-processor goto cleanup; Yield(); // give it a chance to start // find task associated with this instance. In extreme cases it may have // finished even before we're executing this code. taskentry.dwSize = sizeof(TASKENTRY); if (TaskFirst(&taskentry) == 0) { goto taskdone; } while (taskentry.hInst != hInstCpp) { if (TaskNext(&taskentry) == 0) { goto taskdone; } } hTaskCpp = taskentry.hTask; while (IsTask(hTaskCpp)) { SideAssert(TaskFindHandle(&taskentry, hTaskCpp) != 0); if (taskentry.hInst != hInstCpp) { // different hInst associated with this htask, // so the app must have terminated break; } Yield(); // wait until it's done } taskdone: // If signal file doesn't exist, then there was a problem pre-processing // the input file. If it exists, then it worked. if (!MyRemove(szTempSig)) err = ERR_NONE; // it worked! cleanup: if (hFile) // close tmp batch file if fclose(hFile); // error during write SideAssert(MyRemove(szTempBatch) == 0); // delete tmp batch file cleanup2: SideAssert(MyRemove(szTempRoot) == 0); // delete placeholder file if (err != ERR_NONE) // report any error ParseError(err); }