1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-31 21:05:37 +02:00

Commit support for i18n from Alex Chapiro.

updates spawner and starter
This commit is contained in:
Alain Magloire 2004-04-29 15:54:32 +00:00
parent b984f9d6ea
commit 79f4e89182
9 changed files with 233 additions and 201 deletions

View file

@ -1,3 +1,7 @@
2004-04-29 Alex Chapiro
Support for I18N within spawner.
2004-03-25 David Inglis 2004-03-25 David Inglis
Added platform attribute to processlist extension Added platform attribute to processlist extension

View file

@ -32,9 +32,6 @@
#define MAX_PROCS (100) // Maximum number of simultaneiously runnig processes #define MAX_PROCS (100) // Maximum number of simultaneiously runnig processes
// Theses are VM helpers
typedef JNIEXPORT void * (JNICALL * JVM_GetThreadInterruptEvent)();
typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *);
// Process description block. Should be created for each launched process // Process description block. Should be created for each launched process
typedef struct _procInfo { typedef struct _procInfo {
@ -64,7 +61,7 @@ pProcInfo_t findProcInfo(int pid);
unsigned int _stdcall waitProcTermination(void* pv) ; unsigned int _stdcall waitProcTermination(void* pv) ;
// This is a helper function to prevent losing of quotatin marks // This is a helper function to prevent losing of quotatin marks
static int copyTo(char * target, const char * source, int cpyLenght, int availSpace); static int copyTo(_TCHAR * target, const _TCHAR * source, int cpyLenght, int availSpace);
// Use this function to clean project descriptor and return it to the pool of available blocks. // Use this function to clean project descriptor and return it to the pool of available blocks.
static void cleanUpProcBlock(pProcInfo_t pCurProcInfo); static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
@ -82,7 +79,7 @@ typedef enum {
extern CRITICAL_SECTION cs; extern CRITICAL_SECTION cs;
extern TCHAR path[MAX_PATH]; // Directory where spawner.dll is located extern _TCHAR path[MAX_PATH]; // Directory where spawner.dll is located
static HMODULE hVM = NULL; // VM handler static HMODULE hVM = NULL; // VM handler
@ -104,14 +101,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
{ {
HANDLE stdHandles[3]; HANDLE stdHandles[3];
PROCESS_INFORMATION pi = {0}; PROCESS_INFORMATION pi = {0};
STARTUPINFO si; STARTUPINFOW si;
DWORD flags = 0; DWORD flags = 0;
char * cwd = NULL; const _TCHAR * cwd = NULL;
LPVOID envBlk = NULL; LPVOID envBlk = NULL;
int ret = 0; int ret = 0;
char szCmdLine[MAX_CMD_SIZE]; _TCHAR szCmdLine[MAX_CMD_SIZE];
int nBlkSize = MAX_ENV_SIZE; int nBlkSize = MAX_ENV_SIZE;
char * szEnvBlock = (char *)malloc(nBlkSize); _TCHAR * szEnvBlock = (_TCHAR *)malloc(nBlkSize * sizeof(_TCHAR));
jsize nCmdTokens = 0; jsize nCmdTokens = 0;
jsize nEnvVars = 0; jsize nEnvVars = 0;
int i; int i;
@ -119,16 +116,16 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
int nPos; int nPos;
pProcInfo_t pCurProcInfo; pProcInfo_t pCurProcInfo;
DWORD dwThreadId; DWORD dwThreadId;
char eventBreakName[20]; _TCHAR eventBreakName[20];
char eventWaitName[20]; _TCHAR eventWaitName[20];
char eventTerminateName[20]; _TCHAR eventTerminateName[20];
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
#endif #endif
int nLocalCounter; int nLocalCounter;
char inPipeName[PIPE_NAME_LENGTH]; _TCHAR inPipeName[PIPE_NAME_LENGTH];
char outPipeName[PIPE_NAME_LENGTH]; _TCHAR outPipeName[PIPE_NAME_LENGTH];
char errPipeName[PIPE_NAME_LENGTH]; _TCHAR errPipeName[PIPE_NAME_LENGTH];
if((HIBYTE(LOWORD(GetVersion()))) & 0x80) if((HIBYTE(LOWORD(GetVersion()))) & 0x80)
{ {
@ -146,21 +143,21 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
// Create pipe names // Create pipe names
EnterCriticalSection(&cs); EnterCriticalSection(&cs);
sprintf(inPipeName, "\\\\.\\pipe\\stdin%08i%010i", pid, nCounter); _stprintf(inPipeName, _T("\\\\.\\pipe\\stdin%08i%010i"), pid, nCounter);
sprintf(outPipeName, "\\\\.\\pipe\\stdout%08i%010i", pid, nCounter); _stprintf(outPipeName, _T("\\\\.\\pipe\\stdout%08i%010i"), pid, nCounter);
sprintf(errPipeName, "\\\\.\\pipe\\stderr%08i%010i", pid, nCounter); _stprintf(errPipeName, _T("\\\\.\\pipe\\stderr%08i%010i"), pid, nCounter);
nLocalCounter = nCounter; nLocalCounter = nCounter;
++nCounter; ++nCounter;
LeaveCriticalSection(&cs); LeaveCriticalSection(&cs);
if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipe(inPipeName, PIPE_ACCESS_OUTBOUND, if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipeW(inPipeName, PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) || PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
(INVALID_HANDLE_VALUE == (stdHandles[1] = CreateNamedPipe(outPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateNamedPipeW(outPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) || PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
(INVALID_HANDLE_VALUE == (stdHandles[2] = CreateNamedPipe(errPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateNamedPipeW(errPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL)))) { PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL)))) {
CloseHandle(stdHandles[0]); CloseHandle(stdHandles[0]);
@ -171,8 +168,8 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
} }
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Opened pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName); _stprintf(buffer, _T("Opened pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
@ -188,25 +185,25 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
} }
// Construct starter's command line // Construct starter's command line
sprintf(eventBreakName, "SABreak%p", pCurProcInfo); _stprintf(eventBreakName, _T("SABreak%p"), pCurProcInfo);
sprintf(eventWaitName, "SAWait%p", pCurProcInfo); _stprintf(eventWaitName, _T("SAWait%p"), pCurProcInfo);
sprintf(eventTerminateName, "SATerm%p", pCurProcInfo); _stprintf(eventTerminateName, _T("SATerm%p"), pCurProcInfo);
pCurProcInfo -> eventBreak = CreateEvent(NULL, TRUE, FALSE, eventBreakName); pCurProcInfo -> eventBreak = CreateEventW(NULL, TRUE, FALSE, eventBreakName);
ResetEvent(pCurProcInfo -> eventBreak); ResetEvent(pCurProcInfo -> eventBreak);
pCurProcInfo -> eventWait = CreateEvent(NULL, TRUE, FALSE, eventWaitName); pCurProcInfo -> eventWait = CreateEventW(NULL, TRUE, FALSE, eventWaitName);
ResetEvent(pCurProcInfo -> eventWait); ResetEvent(pCurProcInfo -> eventWait);
pCurProcInfo -> eventTerminate = CreateEvent(NULL, TRUE, FALSE, eventTerminateName); pCurProcInfo -> eventTerminate = CreateEventW(NULL, TRUE, FALSE, eventTerminateName);
ResetEvent(pCurProcInfo -> eventTerminate); ResetEvent(pCurProcInfo -> eventTerminate);
nPos = sprintf(szCmdLine, "%sstarter.exe %i %i %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName); nPos = _stprintf(szCmdLine, _T("%sstarter.exe %i %i %s %s %s "), path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName);
// Prepare command line // Prepare command line
for(i = 0; i < nCmdTokens; ++i) for(i = 0; i < nCmdTokens; ++i)
{ {
jobject item = (*env) -> GetObjectArrayElement(env, cmdarray, i); jobject item = (*env) -> GetObjectArrayElement(env, cmdarray, i);
jsize len = (*env) -> GetStringUTFLength(env, item); jsize len = (*env) -> GetStringLength(env, item);
int nCpyLen; int nCpyLen;
const char * str = (*env) -> GetStringUTFChars(env, item, 0); const _TCHAR * str = (*env) -> GetStringChars(env, item, 0);
if(NULL != str) if(NULL != str)
{ {
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, MAX_CMD_SIZE - nPos))) if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, MAX_CMD_SIZE - nPos)))
@ -215,13 +212,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
return 0; return 0;
} }
nPos += nCpyLen; nPos += nCpyLen;
szCmdLine[nPos] = ' '; szCmdLine[nPos] = _T(' ');
++nPos; ++nPos;
(*env) -> ReleaseStringUTFChars(env, item, str); (*env) -> ReleaseStringChars(env, item, str);
} }
} }
szCmdLine[nPos] = '\0'; szCmdLine[nPos] = _T('\0');
// Prepare environment block // Prepare environment block
if (nEnvVars > 0) if (nEnvVars > 0)
@ -230,45 +227,47 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
for(i = 0; i < nEnvVars; ++i) for(i = 0; i < nEnvVars; ++i)
{ {
jobject item = (*env) -> GetObjectArrayElement(env, envp, i); jobject item = (*env) -> GetObjectArrayElement(env, envp, i);
jsize len = (*env) -> GetStringUTFLength(env, item); jsize len = (*env) -> GetStringLength(env, item);
const char * str = (*env) -> GetStringUTFChars(env, item, 0); const _TCHAR * str = (*env) -> GetStringChars(env, item, 0);
if(NULL != str) if(NULL != str)
{ {
while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0' while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0'
{ {
nBlkSize += MAX_ENV_SIZE; nBlkSize += MAX_ENV_SIZE;
szEnvBlock = (char *)realloc(szEnvBlock, nBlkSize); szEnvBlock = (_TCHAR *)realloc(szEnvBlock, nBlkSize * sizeof(_TCHAR));
if(NULL == szEnvBlock) if(NULL == szEnvBlock)
{ {
ThrowByName(env, "java/io/IOException", "Not enough memory"); ThrowByName(env, "java/io/IOException", "Not enough memory");
return 0; return 0;
} }
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Realloc environment block; new length is %i \n", nBlkSize); _stprintf(buffer, _T("Realloc environment block; new length is %i \n"), nBlkSize);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
} }
strncpy(szEnvBlock + nPos, str, len); #ifdef DEBUG_MONITOR
_stprintf(buffer, _T("%s\n"), str);
OutputDebugStringW(buffer);
#endif
_tcsnccpy(szEnvBlock + nPos, str, len);
nPos += len; nPos += len;
szEnvBlock[nPos] = '\0'; szEnvBlock[nPos] = _T('\0');
++nPos; ++nPos;
(*env) -> ReleaseStringUTFChars(env, item, str); (*env) -> ReleaseStringChars(env, item, str);
} }
} }
szEnvBlock[nPos] = '\0';
envBlk = szEnvBlock;
} }
if (dir != 0) if (dir != 0)
{ {
const char * str = (*env) -> GetStringUTFChars(env, dir, 0); const _TCHAR * str = (*env) -> GetStringChars(env, dir, 0);
if(NULL != str) if(NULL != str)
{ {
cwd = strdup(str); cwd = _tcsdup(str);
(*env) -> ReleaseStringUTFChars(env, dir, str); (*env) -> ReleaseStringChars(env, dir, str);
} }
} }
@ -286,13 +285,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
flags = CREATE_NEW_CONSOLE; flags = CREATE_NEW_CONSOLE;
flags |= CREATE_NO_WINDOW; flags |= CREATE_NO_WINDOW;
flags |= CREATE_UNICODE_ENVIRONMENT;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
OutputDebugString(szCmdLine); OutputDebugStringW(szCmdLine);
#endif #endif
// launches starter; we need it to create another console group to correctly process // launches starter; we need it to create another console group to correctly process
// emulation of SYSint signal (Ctrl-C) // emulation of SYSint signal (Ctrl-C)
ret = CreateProcess(0, /* executable name */ ret = CreateProcessW(0, /* executable name */
szCmdLine, /* command line */ szCmdLine, /* command line */
0, /* process security attribute */ 0, /* process security attribute */
0, /* thread security attribute */ 0, /* thread security attribute */
@ -306,13 +306,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
if(NULL != cwd) if(NULL != cwd)
free(cwd); free((void *)cwd);
free(szEnvBlock); free(szEnvBlock);
if (!ret) // Launching error if (!ret) // Launching error
{ {
LPTSTR lpMsgBuf; char * lpMsgBuf;
CloseHandle(stdHandles[0]); CloseHandle(stdHandles[0]);
CloseHandle(stdHandles[1]); CloseHandle(stdHandles[1]);
@ -324,7 +324,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (char *)&lpMsgBuf,
0, 0,
NULL NULL
); );
@ -354,11 +354,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
if((what != WAIT_OBJECT_0) && (pCurProcInfo -> pid > 0)) // CreateProcess failed if((what != WAIT_OBJECT_0) && (pCurProcInfo -> pid > 0)) // CreateProcess failed
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Process %i failed\n", pi.dwProcessId); _stprintf(buffer, _T("Process %i failed\n"), pi.dwProcessId);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
cleanUpProcBlock(pCurProcInfo); cleanUpProcBlock(pCurProcInfo);
ThrowByName(env, "java/io/IOException", "Launching failed"); ThrowByName(env, "java/io/IOException", "Launching failed");
#ifdef DEBUG_MONITOR
OutputDebugStringW(_T("Process failed\n"));
#endif
} }
else else
{ {
@ -369,12 +372,12 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
file_handles[1] = (int)stdHandles[1]; file_handles[1] = (int)stdHandles[1];
file_handles[2] = (int)stdHandles[2]; file_handles[2] = (int)stdHandles[2];
(*env) -> SetIntArrayRegion(env, channels, 0, 3, file_handles); (*env) -> SetIntArrayRegion(env, channels, 0, 3, file_handles);
#ifdef DEBUG_MONITOR
OutputDebugStringW(_T("Process started\n"));
#endif
} }
CloseHandle(h[1]); CloseHandle(h[1]);
LeaveCriticalSection(&cs); LeaveCriticalSection(&cs);
#ifdef DEBUG_MONITOR
OutputDebugString("Process started\n");
#endif
} }
@ -397,18 +400,18 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi = {0}; PROCESS_INFORMATION pi = {0};
STARTUPINFO si; STARTUPINFOW si;
DWORD flags = 0; DWORD flags = 0;
char * cwd = NULL; _TCHAR * cwd = NULL;
LPVOID envBlk = NULL; _TCHAR * envBlk = NULL;
int ret = 0; int ret = 0;
jsize nCmdTokens = 0; jsize nCmdTokens = 0;
jsize nEnvVars = 0; jsize nEnvVars = 0;
int i; int i;
int nPos; int nPos;
char szCmdLine[MAX_CMD_SIZE]; _TCHAR szCmdLine[MAX_CMD_SIZE];
int nBlkSize = MAX_ENV_SIZE; int nBlkSize = MAX_ENV_SIZE;
char * szEnvBlock = (char *)malloc(nBlkSize); _TCHAR * szEnvBlock = (_TCHAR *)malloc(nBlkSize * sizeof(_TCHAR));
sa.nLength = sizeof(sa); sa.nLength = sizeof(sa);
@ -425,9 +428,9 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
for(i = 0; i < nCmdTokens; ++i) for(i = 0; i < nCmdTokens; ++i)
{ {
jobject item = (*env) -> GetObjectArrayElement(env, cmdarray, i); jobject item = (*env) -> GetObjectArrayElement(env, cmdarray, i);
jsize len = (*env) -> GetStringUTFLength(env, item); jsize len = (*env) -> GetStringLength(env, item);
int nCpyLen; int nCpyLen;
const char * str = (*env) -> GetStringUTFChars(env, item, 0); const _TCHAR * str = (*env) -> GetStringChars(env, item, 0);
if(NULL != str) if(NULL != str)
{ {
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, MAX_CMD_SIZE - nPos))) if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, MAX_CMD_SIZE - nPos)))
@ -436,13 +439,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
return 0; return 0;
} }
nPos += nCpyLen; nPos += nCpyLen;
szCmdLine[nPos] = ' '; szCmdLine[nPos] = _T(' ');
++nPos; ++nPos;
(*env) -> ReleaseStringUTFChars(env, item, str); (*env) -> ReleaseStringChars(env, item, str);
} }
} }
szCmdLine[nPos] = '\0'; szCmdLine[nPos] = _T('\0');
// Prepare environment block // Prepare environment block
if (nEnvVars > 0) if (nEnvVars > 0)
@ -451,28 +454,28 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
for(i = 0; i < nEnvVars; ++i) for(i = 0; i < nEnvVars; ++i)
{ {
jobject item = (*env) -> GetObjectArrayElement(env, envp, i); jobject item = (*env) -> GetObjectArrayElement(env, envp, i);
jsize len = (*env) -> GetStringUTFLength(env, item); jsize len = (*env) -> GetStringLength(env, item);
const char * str = (*env) -> GetStringUTFChars(env, item, 0); const _TCHAR * str = (*env) -> GetStringChars(env, item, 0);
if(NULL != str) if(NULL != str)
{ {
while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0' while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0'
{ {
nBlkSize += MAX_ENV_SIZE; nBlkSize += MAX_ENV_SIZE;
szEnvBlock = (char *)realloc(szEnvBlock, nBlkSize); szEnvBlock = (_TCHAR *)realloc(szEnvBlock, nBlkSize * sizeof(_TCHAR));
if(NULL == szEnvBlock) if(NULL == szEnvBlock)
{ {
ThrowByName(env, "java/io/Exception", "Not enough memory"); ThrowByName(env, "java/io/Exception", "Not enough memory");
return 0; return 0;
} }
} }
strncpy(szEnvBlock + nPos, str, len); _tcsnccpy(szEnvBlock + nPos, str, len);
nPos += len; nPos += len;
szEnvBlock[nPos] = '\0'; szEnvBlock[nPos] = _T('\0');
++nPos; ++nPos;
(*env) -> ReleaseStringUTFChars(env, item, str); (*env) -> ReleaseStringChars(env, item, str);
} }
} }
szEnvBlock[nPos] = '\0'; szEnvBlock[nPos] = _T('\0');
envBlk = szEnvBlock; envBlk = szEnvBlock;
} }
@ -480,11 +483,11 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
if (dir != 0) if (dir != 0)
{ {
const char * str = (*env) -> GetStringUTFChars(env, dir, 0); const _TCHAR * str = (*env) -> GetStringChars(env, dir, 0);
if(NULL != str) if(NULL != str)
{ {
cwd = strdup(str); cwd = _tcsdup(str);
(*env) -> ReleaseStringUTFChars(env, dir, str); (*env) -> ReleaseStringChars(env, dir, str);
} }
} }
@ -498,7 +501,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
flags = CREATE_NEW_CONSOLE; flags = CREATE_NEW_CONSOLE;
ret = CreateProcess(0, /* executable name */ ret = CreateProcessW(0, /* executable name */
szCmdLine, /* command line */ szCmdLine, /* command line */
0, /* process security attribute */ 0, /* process security attribute */
0, /* thread security attribute */ 0, /* thread security attribute */
@ -517,7 +520,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
if (!ret) // error if (!ret) // error
{ {
LPTSTR lpMsgBuf; char * lpMsgBuf;
FormatMessage( FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
@ -526,9 +529,9 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (char *)&lpMsgBuf,
0, 0,
NULL NULL
); );
ThrowByName(env, "java/io/IOException", lpMsgBuf); ThrowByName(env, "java/io/IOException", lpMsgBuf);
// Free the buffer. // Free the buffer.
@ -563,7 +566,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
HANDLE hProc; HANDLE hProc;
pProcInfo_t pCurProcInfo = findProcInfo(uid); pProcInfo_t pCurProcInfo = findProcInfo(uid);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[100]; _TCHAR buffer[100];
#endif #endif
if(NULL == pCurProcInfo) { if(NULL == pCurProcInfo) {
@ -574,8 +577,8 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
} }
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Spawner received signal %i for process %i\n", signal, pCurProcInfo -> pid); _stprintf(buffer, _T("Spawner received signal %i for process %i\n"), signal, pCurProcInfo -> pid);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pCurProcInfo -> pid); hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pCurProcInfo -> pid);
@ -596,12 +599,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
case SIG_KILL: case SIG_KILL:
case SIG_TERM: case SIG_TERM:
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Spawner received KILL or TERM signal for process %i\n", pCurProcInfo -> pid); _stprintf(buffer, _T("Spawner received KILL or TERM signal for process %i\n"),
OutputDebugString(buffer); pCurProcInfo -> pid);
OutputDebugStringW(buffer);
#endif #endif
SetEvent(pCurProcInfo -> eventTerminate); SetEvent(pCurProcInfo -> eventTerminate);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
OutputDebugString("Spawner signalled KILL event\n"); OutputDebugStringW(_T("Spawner signalled KILL event\n"));
#endif #endif
ret = 0; ret = 0;
break; break;
@ -780,7 +784,7 @@ unsigned int _stdcall waitProcTermination(void* pv)
int i; int i;
int pid = (int)pv; int pid = (int)pv;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
#endif #endif
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
@ -788,16 +792,18 @@ unsigned int _stdcall waitProcTermination(void* pv)
if(NULL == hProc) if(NULL == hProc)
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "waitProcTermination: cannot get handler for PID %i (error %i)\n", pid, GetLastError()); _stprintf(buffer, _T("waitProcTermination: cannot get handler for PID %i (error %i)\n"),
OutputDebugString(buffer); pid,
GetLastError());
OutputDebugStringW(buffer);
#endif #endif
} }
else else
{ {
WaitForSingleObject(hProc, INFINITE); WaitForSingleObject(hProc, INFINITE);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Process PID %i terminated\n", pid); _stprintf(buffer, _T("Process PID %i terminated\n"), pid);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
} }
@ -808,8 +814,10 @@ unsigned int _stdcall waitProcTermination(void* pv)
if(WaitForSingleObject(pInfo[i].eventWait, 1) == WAIT_OBJECT_0) // Correct finish if(WaitForSingleObject(pInfo[i].eventWait, 1) == WAIT_OBJECT_0) // Correct finish
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "waitProcTermination: set PID %i to 0\n", pid, GetLastError()); _stprintf(buffer, _T("waitProcTermination: set PID %i to 0\n"),
OutputDebugString(buffer); pid,
GetLastError());
OutputDebugStringW(buffer);
#endif #endif
cleanUpProcBlock(pInfo + i); cleanUpProcBlock(pInfo + i);
} }
@ -832,7 +840,7 @@ unsigned int _stdcall waitProcTermination(void* pv)
// availSpace - size of the target buffer // availSpace - size of the target buffer
// Return :number of bytes used in target, or -1 in case of error // Return :number of bytes used in target, or -1 in case of error
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
int copyTo(char * target, const char * source, int cpyLength, int availSpace) int copyTo(_TCHAR * target, const _TCHAR * source, int cpyLength, int availSpace)
{ {
BOOL bSlash = FALSE; BOOL bSlash = FALSE;
int i = 0, j = 0; int i = 0, j = 0;
@ -849,12 +857,12 @@ int copyTo(char * target, const char * source, int cpyLength, int availSpace)
if(availSpace <= cpyLength) // = to reserve space for final '\0' if(availSpace <= cpyLength) // = to reserve space for final '\0'
return -1; return -1;
if(('\"' == *source) && ('\"' == *(source + cpyLength - 1))) if((_T('\"') == *source) && (_T('\"') == *(source + cpyLength - 1)))
{ {
nQuotationMode = QUOTATION_DONE; nQuotationMode = QUOTATION_DONE;
} }
else else
if(strchr(source, ' ') == NULL) if(_tcschr(source, _T(' ')) == NULL)
{ {
// No reason to quotate term becase it doesn't have embedded spaces // No reason to quotate term becase it doesn't have embedded spaces
nQuotationMode = QUOTATION_NONE; nQuotationMode = QUOTATION_NONE;
@ -863,25 +871,25 @@ int copyTo(char * target, const char * source, int cpyLength, int availSpace)
{ {
// Needs to be quotated // Needs to be quotated
nQuotationMode = QUOTATION_DO; nQuotationMode = QUOTATION_DO;
*target = '\"'; *target = _T('\"');
++j; ++j;
} }
for(; i < cpyLength; ++i, ++j) for(; i < cpyLength; ++i, ++j)
{ {
if(source[i] == '\\') if(source[i] == _T('\\'))
bSlash = TRUE; bSlash = TRUE;
else else
{ {
// Don't escape embracing quotation marks // Don't escape embracing quotation marks
if((source[i] == '\"') && !((nQuotationMode == QUOTATION_DONE) && ((i == 0) || (i == (cpyLength - 1))) ) ) if((source[i] == _T('\"')) && !((nQuotationMode == QUOTATION_DONE) && ((i == 0) || (i == (cpyLength - 1))) ) )
{ {
if(!bSlash) // If still not escaped if(!bSlash) // If still not escaped
{ {
if(j == availSpace) if(j == availSpace)
return -1; return -1;
target[j] = '\\'; target[j] = _T('\\');
++j; ++j;
} }
} }
@ -897,7 +905,7 @@ int copyTo(char * target, const char * source, int cpyLength, int availSpace)
{ {
if(j == availSpace) if(j == availSpace)
return -1; return -1;
target[j] = '\"'; target[j] = _T('\"');
++j; ++j;
} }

View file

@ -23,6 +23,7 @@
#include "jni.h" #include "jni.h"
#include "io.h" #include "io.h"
//#define READ_REPORT
JNIEXPORT void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg); JNIEXPORT void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
@ -40,7 +41,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
BYTE tmpBuf[BUFF_SIZE]; BYTE tmpBuf[BUFF_SIZE];
int nBuffOffset = 0; int nBuffOffset = 0;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
#endif #endif
OVERLAPPED overlapped; OVERLAPPED overlapped;
overlapped.Offset = 0; overlapped.Offset = 0;
@ -51,7 +52,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
NULL); // unnamed event object NULL); // unnamed event object
if(NULL == overlapped.hEvent) { if(NULL == overlapped.hEvent) {
LPTSTR lpMsgBuf; char * lpMsgBuf;
FormatMessage( FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_SYSTEM |
@ -59,17 +60,21 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (char *) &lpMsgBuf,
0, 0,
NULL NULL
); );
ThrowByName(env, "java/io/IOException", lpMsgBuf); ThrowByName(env, "java/io/IOException", lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
} }
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Start read %i\n", fd); #ifdef READ_REPORT
OutputDebugString(buffer); _stprintf(buffer, _T("Start read %i\n"), fd);
OutputDebugStringW(buffer);
#endif
#endif #endif
while(len > nBuffOffset) while(len > nBuffOffset)
@ -95,11 +100,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
break; break;
if(err != 0) if(err != 0)
{ {
LPTSTR lpMsgBuf; char * lpMsgBuf;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[200]; _stprintf(buffer, _T("Read failed - %i, error %i\n"), fd, err);
sprintf(buffer, "Read failed - %i, error %i\n", fd, err); OutputDebugStringW(buffer);
OutputDebugString(buffer);
#endif #endif
if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data
{ // than buffer can accept { // than buffer can accept
@ -110,7 +114,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
NULL, NULL,
err, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (char *) &lpMsgBuf,
0, 0,
NULL NULL
); );
@ -132,8 +136,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
} }
CloseHandle(overlapped.hEvent); CloseHandle(overlapped.hEvent);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "End read %i\n", fd); #ifdef READ_REPORT
OutputDebugString(buffer); _stprintf(buffer, _T("End read %i\n"), fd);
OutputDebugStringW(buffer);
#endif
#endif #endif
return nBuffOffset; // This is a real full readed length return nBuffOffset; // This is a real full readed length
@ -149,15 +155,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_clo
{ {
int rc; int rc;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
sprintf(buffer, "Close %i\n", fd); _stprintf(buffer, _T("Close %i\n"), fd);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
DisconnectNamedPipe((HANDLE)fd); DisconnectNamedPipe((HANDLE)fd);
rc = (CloseHandle((HANDLE)fd) ? 0 : -1); rc = (CloseHandle((HANDLE)fd) ? 0 : -1);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Closed %i\n", fd); _stprintf(buffer, _T("Closed %i\n"), fd);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
return (rc ? GetLastError() : 0); return (rc ? GetLastError() : 0);
} }
@ -181,7 +187,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_wr
(*env) -> GetByteArrayRegion(env, buf, nBuffOffset, nNumberOfBytesToWrite, tmpBuf); (*env) -> GetByteArrayRegion(env, buf, nBuffOffset, nNumberOfBytesToWrite, tmpBuf);
if(0 == WriteFile((HANDLE)fd, tmpBuf, nNumberOfBytesToWrite, &nNumberOfBytesWritten, NULL)) if(0 == WriteFile((HANDLE)fd, tmpBuf, nNumberOfBytesToWrite, &nNumberOfBytesWritten, NULL))
{ {
LPTSTR lpMsgBuf; char * lpMsgBuf;
FormatMessage( FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_SYSTEM |
@ -189,7 +195,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_wr
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, (char *) &lpMsgBuf,
0, 0,
NULL NULL
); );
@ -213,15 +219,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_cl
{ {
int rc; int rc;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
sprintf(buffer, "Close %i\n", fd); _stprintf(buffer, _T("Close %i\n"), fd);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
DisconnectNamedPipe((HANDLE)fd); DisconnectNamedPipe((HANDLE)fd);
rc = (CloseHandle((HANDLE)fd) ? 0 : -1); rc = (CloseHandle((HANDLE)fd) ? 0 : -1);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Closed %i\n", fd); _stprintf(buffer, _T("Closed %i\n"), fd);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
return (rc ? GetLastError() : 0); return (rc ? GetLastError() : 0);
} }

View file

@ -64,7 +64,7 @@ find_child_console (HWND hwnd, LPARAM arg)
int interruptProcess(int pid) int interruptProcess(int pid)
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
char buffer[1000]; _TCHAR buffer[1000];
#endif #endif
int rc; int rc;
// Try another method // Try another method
@ -72,8 +72,8 @@ int interruptProcess(int pid)
consoleHWND = NULL; consoleHWND = NULL;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Try to interrupt process %i\n", pid); _stprintf(buffer, _T("Try to interrupt process %i\n"), pid);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
// Find console // Find console
EnumWindows (find_child_console, (LPARAM) pid); EnumWindows (find_child_console, (LPARAM) pid);
@ -140,16 +140,15 @@ int interruptProcess(int pid)
AttachThreadInput (GetCurrentThreadId (), AttachThreadInput (GetCurrentThreadId (),
child_thread, FALSE); child_thread, FALSE);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Sent Ctrl-C & Ctrl-Break to process %i\n", pid); _stprintf(buffer, _T("Sent Ctrl-C & Ctrl-Break to process %i\n"), pid);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
} }
} }
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
else { else {
sprintf(buffer, "Cannot find console for process %i\n", pid); _stprintf(buffer, _T("Cannot find console for process %i\n"), pid);
OutputDebugStringW(buffer);
OutputDebugString(buffer);
} }
#endif #endif

View file

@ -20,7 +20,7 @@
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
TCHAR path[MAX_PATH + 1] = {_T('\0') }; // Directory where spawner.dll is located _TCHAR path[MAX_PATH + 1] = {_T('\0') }; // Directory where spawner.dll is located
BOOL APIENTRY DllMain( HANDLE hModule, BOOL APIENTRY DllMain( HANDLE hModule,
@ -32,14 +32,14 @@ BOOL APIENTRY DllMain( HANDLE hModule,
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
{ {
LPTSTR p; _TCHAR * p;
InitializeCriticalSection(&cs); InitializeCriticalSection(&cs);
GetModuleFileName(hModule, path, MAX_PATH); GetModuleFileNameW(hModule, path, MAX_PATH);
p = _tcsrchr(path, _T('\\')); p = _tcsrchr(path, _T('\\'));
if(NULL != p) if(NULL != p)
*(p + 1) = _T('\0'); *(p + 1) = _T('\0');
else else
_tcscat(path, "\\"); _tcscat(path, _T("\\"));
} }
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:

View file

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /Gz /MT /W3 /GX /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\Win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /Gz /MT /W3 /GX /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\Win32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /Gz /MD /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\Win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAWNER_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /Gz /MD /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\Win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "_USRDLL" /D "SPAWNER_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
@ -96,7 +96,7 @@ SOURCE=.\iostream.c
!IF "$(CFG)" == "spawner - Win32 Release" !IF "$(CFG)" == "spawner - Win32 Release"
# ADD CPP /I "E:\Java\jdk1.3.1\include" /I "E:\Java\jdk1.3.1\include\Win32" # ADD CPP /I "E:\Java\jdk1.3.1\include" /I "E:\Java\jdk1.3.1\include\Win32" /FAcs
!ELSEIF "$(CFG)" == "spawner - Win32 Debug" !ELSEIF "$(CFG)" == "spawner - Win32 Debug"
@ -141,7 +141,7 @@ SOURCE=.\Win32ProcessEx.c
!IF "$(CFG)" == "spawner - Win32 Release" !IF "$(CFG)" == "spawner - Win32 Release"
# ADD CPP /I "E:\Java\jdk1.3.1\include" /I "E:\Java\jdk1.3.1\include\Win32" # ADD CPP /I "E:\Java\jdk1.3.1\include" /I "E:\Java\jdk1.3.1\include\Win32" /FAcs
!ELSEIF "$(CFG)" == "spawner - Win32 Debug" !ELSEIF "$(CFG)" == "spawner - Win32 Debug"

View file

@ -25,7 +25,8 @@
#define MAX_CMD_LINE_LENGTH (2049) #define MAX_CMD_LINE_LENGTH (2049)
#define PIPE_NAME_LENGTH 100 #define PIPE_NAME_LENGTH 100
int copyTo(char * target, const char * source, int cpyLength, int availSpace); int copyTo(_TCHAR * target, const _TCHAR * source, int cpyLength, int availSpace);
void DisplayErrorMessage();
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI HandlerRoutine( DWORD dwCtrlType) // control signal type BOOL WINAPI HandlerRoutine( DWORD dwCtrlType) // control signal type
@ -54,17 +55,17 @@ BOOL WINAPI HandlerRoutine( DWORD dwCtrlType) // control signal type
extern "C" int _tmain(int argc, TCHAR* argv[]) { extern "C" int _tmain(int argc, _TCHAR * argv[]) {
// Make sure that we've been passed the right number of arguments // Make sure that we've been passed the right number of arguments
if (argc < 7) { if (argc < 7) {
_tprintf(__TEXT("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"), _tprintf(_T("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"),
argv[0]); argv[0]);
return(0); return(0);
} }
// Construct the full command line // Construct the full command line
TCHAR szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 }; _TCHAR szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 };
int nPos = 0; int nPos = 0;
for(int i = 6; i < argc; ++i) for(int i = 6; i < argc; ++i)
@ -73,7 +74,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], _tcslen(argv[i]), MAX_CMD_LINE_LENGTH - nPos))) if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], _tcslen(argv[i]), MAX_CMD_LINE_LENGTH - nPos)))
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
OutputDebugString("Not enough space to build command line\n"); OutputDebugStringW(_T("Not enough space to build command line\n"));
#endif #endif
return 0; return 0;
} }
@ -83,34 +84,34 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
} }
szCmdLine[nPos] = _T('\0'); szCmdLine[nPos] = _T('\0');
STARTUPINFO si = { sizeof(si) }; STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 }; PROCESS_INFORMATION pi = { 0 };
DWORD dwExitCode = 0; DWORD dwExitCode = 0;
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
int currentPID = GetCurrentProcessId(); int currentPID = GetCurrentProcessId();
char buffer[MAX_CMD_LINE_LENGTH]; _TCHAR buffer[MAX_CMD_LINE_LENGTH];
#endif #endif
BOOL exitProc = FALSE; BOOL exitProc = FALSE;
HANDLE waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[4]); HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]);
HANDLE h[3]; HANDLE h[3];
h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]); h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]);
h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[5]); // This is a terminate event h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // This is a terminate event
SetConsoleCtrlHandler(HandlerRoutine, TRUE); SetConsoleCtrlHandler(HandlerRoutine, TRUE);
int parentPid = strtol(argv[1], NULL, 10); int parentPid = _tcstol(argv[1], NULL, 10);
int nCounter = strtol(argv[2], NULL, 10); int nCounter = _tcstol(argv[2], NULL, 10);
char inPipeName[PIPE_NAME_LENGTH]; _TCHAR inPipeName[PIPE_NAME_LENGTH];
char outPipeName[PIPE_NAME_LENGTH]; _TCHAR outPipeName[PIPE_NAME_LENGTH];
char errPipeName[PIPE_NAME_LENGTH]; _TCHAR errPipeName[PIPE_NAME_LENGTH];
sprintf(inPipeName, "\\\\.\\pipe\\stdin%08i%010i", parentPid, nCounter); _stprintf(inPipeName, _T("\\\\.\\pipe\\stdin%08i%010i"), parentPid, nCounter);
sprintf(outPipeName, "\\\\.\\pipe\\stdout%08i%010i", parentPid, nCounter); _stprintf(outPipeName, _T("\\\\.\\pipe\\stdout%08i%010i"), parentPid, nCounter);
sprintf(errPipeName, "\\\\.\\pipe\\stderr%08i%010i", parentPid, nCounter); _stprintf(errPipeName, _T("\\\\.\\pipe\\stderr%08i%010i"), parentPid, nCounter);
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName); _stprintf(buffer, _T("Pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
HANDLE stdHandles[3]; HANDLE stdHandles[3];
@ -120,13 +121,13 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
sa.bInheritHandle = TRUE; sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL; sa.lpSecurityDescriptor = NULL;
if((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateFile(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) || if((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateFileW(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) ||
(INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFile(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) || (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFileW(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) ||
(INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFile(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa)))) (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFileW(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))))
{ {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Failed to open pipe %i, %i, %i: %i\n", stdHandles[0], stdHandles[1], stdHandles[2], GetLastError()); _stprintf(buffer, _T("Failed to open pipe %i, %i, %i: %i\n"), stdHandles[0], stdHandles[1], stdHandles[2], GetLastError());
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
CloseHandle(stdHandles[0]); CloseHandle(stdHandles[0]);
CloseHandle(stdHandles[1]); CloseHandle(stdHandles[1]);
@ -141,8 +142,8 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
!SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) || !SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) ||
!SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) { !SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) {
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Failed to reassign standard streams: %i\n", GetLastError()); _stprintf(buffer, _T("Failed to reassign standard streams: %i\n"), GetLastError());
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
CloseHandle(stdHandles[0]); CloseHandle(stdHandles[0]);
CloseHandle(stdHandles[1]); CloseHandle(stdHandles[1]);
@ -150,19 +151,22 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
return -1;; return -1;;
} }
#ifdef DEBUG_MONITOR
_stprintf(buffer, _T("Starting: %s\n"), szCmdLine);
OutputDebugStringW(buffer);
#endif
// Spawn the other processes as part of this Process Group // Spawn the other processes as part of this Process Group
BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, BOOL f = CreateProcessW(NULL, szCmdLine, NULL, NULL, TRUE,
0, NULL, NULL, &si, &pi); 0, NULL, NULL, &si, &pi);
// We don't need them any more // We don't need them any more
CloseHandle(stdHandles[0]); CloseHandle(stdHandles[0]);
CloseHandle(stdHandles[1]); CloseHandle(stdHandles[1]);
CloseHandle(stdHandles[2]); CloseHandle(stdHandles[2]);
if (f) if (f) {
{
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "Process %i started\n", pi.dwProcessId); _stprintf(buffer, _T("Process %i started\n"), pi.dwProcessId);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
SetEvent(waitEvent); // Means thar process has been spawned SetEvent(waitEvent); // Means thar process has been spawned
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
@ -175,8 +179,8 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
{ {
case WAIT_OBJECT_0 + 0: // Send Ctrl-C case WAIT_OBJECT_0 + 0: // Send Ctrl-C
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "starter (PID %i) received CTRL-C event\n", currentPID); _stprintf(buffer, _T("starter (PID %i) received CTRL-C event\n"), currentPID);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
SetEvent(waitEvent); SetEvent(waitEvent);
@ -185,16 +189,17 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
case WAIT_OBJECT_0 + 1: // App terminated normally case WAIT_OBJECT_0 + 1: // App terminated normally
// Make it's exit code our exit code // Make it's exit code our exit code
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "starter: launched process has been terminated(PID %i)\n", currentPID); _stprintf(buffer, _T("starter: launched process has been terminated(PID %i)\n"),
OutputDebugString(buffer); pi.dwProcessId);
OutputDebugStringW(buffer);
#endif #endif
GetExitCodeProcess(pi.hProcess, &dwExitCode); GetExitCodeProcess(pi.hProcess, &dwExitCode);
exitProc = TRUE; exitProc = TRUE;
break; break;
case WAIT_OBJECT_0 + 2: // Kill case WAIT_OBJECT_0 + 2: // Kill
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
sprintf(buffer, "starter received KILL event (PID %i)\n", currentPID); _stprintf(buffer, _T("starter received KILL event (PID %i)\n"), currentPID);
OutputDebugString(buffer); OutputDebugStringW(buffer);
#endif #endif
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
TerminateProcess(h[1], 0); TerminateProcess(h[1], 0);
@ -203,22 +208,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
default: default:
// Unexpected code // Unexpected code
#ifdef DEBUG_MONITOR #ifdef DEBUG_MONITOR
LPTSTR lpMsgBuf; DisplayErrorMessage();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
OutputDebugString(lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
#endif #endif
exitProc = TRUE; exitProc = TRUE;
break; break;
@ -226,7 +216,14 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
} }
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
} } else {
#ifdef DEBUG_MONITOR
_stprintf(buffer, _T("Cannot start: %s\n"), szCmdLine);
OutputDebugStringW(buffer);
DisplayErrorMessage();
#endif
}
CloseHandle(waitEvent); CloseHandle(waitEvent);
CloseHandle(h[0]); CloseHandle(h[0]);
@ -245,7 +242,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
// availSpace - size of the target buffer // availSpace - size of the target buffer
// Return :number of bytes used in target, or -1 in case of error // Return :number of bytes used in target, or -1 in case of error
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
int copyTo(LPTSTR target, LPCTSTR source, int cpyLength, int availSpace) int copyTo(_TCHAR * target, const _TCHAR * source, int cpyLength, int availSpace)
{ {
BOOL bSlash = FALSE; BOOL bSlash = FALSE;
int i = 0, j = 0; int i = 0, j = 0;
@ -314,5 +311,23 @@ int copyTo(LPTSTR target, LPCTSTR source, int cpyLength, int availSpace)
} }
void DisplayErrorMessage() {
char * lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(char *) &lpMsgBuf,
0,
NULL
);
OutputDebugString(lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
}
//////////////////////////////// End of File ////////////////////////////////// //////////////////////////////// End of File //////////////////////////////////