Unicode port: Adapted MakensisW & zip2exe for UTF-8 (avoid cutting sequence). Also fix a bug where they would get stuck if output log was multiple of 1023 bytes. Simplification of reading loop.

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6085 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
wizou 2010-05-07 13:54:03 +00:00
parent 27977fd335
commit 428ae80ab1
2 changed files with 58 additions and 60 deletions

View file

@ -706,6 +706,8 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
}
DWORD WINAPI MakeNSISProc(LPVOID p) {
TCHAR buf[1024];
char iobuf[1024]; //i/o buffer
STARTUPINFO si={sizeof(si),};
SECURITY_ATTRIBUTES sa={sizeof(sa),};
SECURITY_DESCRIPTOR sd={0,};
@ -746,34 +748,40 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
return 1;
}
char szBuf[1024];
DWORD dwRead = 1;
DWORD dwExit = !STILL_ACTIVE;
while (dwExit == STILL_ACTIVE || dwRead) {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
if (dwRead) {
ReadFile(read_stdout, szBuf, sizeof(szBuf)-sizeof(TCHAR), &dwRead, NULL);
szBuf[dwRead] = 0;
CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
DWORD dwLeft = 0, dwRead = 0;
while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits
{
dwRead += dwLeft;
iobuf[dwRead] = '\0';
#ifdef _UNICODE
TCHAR wideBuf[1024];
MultiByteToWideChar(CP_UTF8,0,szBuf,-1,wideBuf,COUNTOF(wideBuf));
LogMessage(g_sdata.hwnd, wideBuf);
// this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence
// we print only up to the latest \n of the buffer, and keep the remaining for the next loop
char* lastLF = strrchr(iobuf,'\n');
if (lastLF == NULL) lastLF = iobuf+dwRead-1;
char ch = *++lastLF;
*lastLF = '\0';
MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
LogMessage(g_sdata.hwnd, buf);
*lastLF = ch;
dwLeft = iobuf+dwRead-lastLF;
memmove(iobuf, lastLF, dwLeft);
#else
LogMessage(g_sdata.hwnd, szBuf);
LogMessage(g_sdata.hwnd, iobuf);
#endif
}
else Sleep(TIMEOUT);
GetExitCodeProcess(pi.hProcess, &dwExit);
// Make sure we have no data before killing getting out of the loop
if (dwExit != STILL_ACTIVE) {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
}
}
#ifdef _UNICODE
// because of UTF-8 tweak, in rare case there can be some data remaining
dwRead += dwLeft;
iobuf[dwRead] = 0;
MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
LogMessage(g_sdata.hwnd, buf);
#endif
DWORD dwExit;
GetExitCodeProcess(pi.hProcess, &dwExit);
g_sdata.retcode = dwExit;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(newstdin);
CloseHandle(read_stdin);

View file

@ -386,7 +386,8 @@ void ErrorMessage(TCHAR *str) //display detailed error info
DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis
{
TCHAR buf[1024]; //i/o buffer
TCHAR buf[1024];
char iobuf[1024]; //i/o buffer
STARTUPINFO si={sizeof(si),};
SECURITY_ATTRIBUTES sa={sizeof(sa),};
SECURITY_DESCRIPTOR sd={0,}; //security information for pipes
@ -436,48 +437,37 @@ DWORD WINAPI ThreadProc(LPVOID p) // thread that will start & monitor makensis
PostMessage(g_hwnd,WM_USER+1203,0,1);
return 1;
}
DWORD exit=0; //process exit code
DWORD bread; //bytes read
DWORD avail; //bytes available
// Number of bytes available in the buffer.
const int bufBytesAvail = sizeof(buf)-sizeof(TCHAR);
memset(buf,0,sizeof(buf));
while (1) //main program loop
CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
DWORD dwLeft = 0, dwRead = 0;
while (ReadFile(read_stdout, iobuf+dwLeft, sizeof(iobuf)-dwLeft-1, &dwRead, NULL)) //wait for buffer, or fails with ERROR_BROKEN_PIPE when subprocess exits
{
PeekNamedPipe(read_stdout,buf,bufBytesAvail,&bread,&avail,NULL);
//check to see if there is any data to read from stdout
if (bread != 0)
{
memset(buf,0,sizeof(buf));
if (avail > bufBytesAvail)
{
while (bread >= bufBytesAvail)
{
ReadFile(read_stdout,buf,bufBytesAvail,&bread,NULL); //read the stdout pipe
wnd_printf(buf);
memset(buf,0,sizeof(buf));
}
}
else
{
ReadFile(read_stdout,buf,bufBytesAvail,&bread,NULL);
wnd_printf(buf);
}
}
GetExitCodeProcess(pi.hProcess,&exit); //while the process is running
if (exit != STILL_ACTIVE)
break;
Sleep(100);
dwRead += dwLeft;
iobuf[dwRead] = '\0';
#ifdef _UNICODE
// this tweak is to prevent LogMessage from cutting in the middle of an UTF-8 sequence
// we print only up to the latest \n of the buffer, and keep the remaining for the next loop
char* lastLF = strrchr(iobuf,'\n');
if (lastLF == NULL) lastLF = iobuf+dwRead-1;
char ch = *++lastLF;
*lastLF = '\0';
MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
wnd_printf(buf);
*lastLF = ch;
dwLeft = iobuf+dwRead-lastLF;
memmove(iobuf, lastLF, dwLeft);
#else
wnd_printf(iobuf);
#endif
}
#ifdef _UNICODE
// because of UTF-8 tweak, in rare case there can be some data remaining
dwRead += dwLeft;
iobuf[dwRead] = 0;
MultiByteToWideChar(CP_UTF8,0,iobuf,dwRead+1,buf,COUNTOF(buf));
wnd_printf(buf);
#endif
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);