StdOut Unicode support, controlled by /OUTPUTCHARSET and/or existing BOM if redirected.
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6350 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
c6f149764d
commit
0653f46c07
19 changed files with 684 additions and 425 deletions
|
@ -413,6 +413,14 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||
DragAcceptFiles(g_sdata.hwnd,TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
case MakensisAPI::QUERYHOST: {
|
||||
if (MakensisAPI::QH_OUTPUTCHARSET) {
|
||||
const UINT reqcp = CP_UTF8; // TODO: UTF16LE will be faster for makensis
|
||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(1+reqcp));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
switch (((NMHDR*)lParam)->code ) {
|
||||
case EN_SELCHANGE:
|
||||
|
@ -712,12 +720,12 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||
|
||||
DWORD WINAPI MakeNSISProc(LPVOID p) {
|
||||
TCHAR eventnamebuf[100];
|
||||
wsprintf(eventnamebuf,MakensisAPI::SigintEventNameFmt,g_sdata.hwnd);
|
||||
wsprintf(eventnamebuf, MakensisAPI::SigintEventNameFmt, g_sdata.hwnd);
|
||||
if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event);
|
||||
g_sdata.sigint_event = CreateEvent(NULL,FALSE,FALSE,eventnamebuf);
|
||||
g_sdata.sigint_event = CreateEvent(NULL, FALSE, FALSE, eventnamebuf);
|
||||
if (!g_sdata.sigint_event) {
|
||||
ErrorMessage(g_sdata.hwnd,_T("There was an error creating the abort event."));
|
||||
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
|
||||
ErrorMessage(g_sdata.hwnd, _T("There was an error creating the abort event."));
|
||||
PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -725,44 +733,21 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
|
|||
TCHAR buf[1024];
|
||||
#endif
|
||||
char iobuf[1024]; //i/o buffer
|
||||
STARTUPINFO si={sizeof(si),};
|
||||
SECURITY_ATTRIBUTES sa={sizeof(sa),};
|
||||
SECURITY_DESCRIPTOR sd={0,};
|
||||
PROCESS_INFORMATION pi={0,};
|
||||
HANDLE newstdout=0,read_stdout=0;
|
||||
HANDLE newstdin=0,read_stdin=0;
|
||||
OSVERSIONINFO osv={sizeof(osv)};
|
||||
GetVersionEx(&osv);
|
||||
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
||||
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd,true,NULL,false);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
}
|
||||
else sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = true;
|
||||
if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
|
||||
ErrorMessage(g_sdata.hwnd,_T("There was an error creating the output pipe."));
|
||||
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
|
||||
STARTUPINFO si;
|
||||
HANDLE newstdout,read_stdout;
|
||||
|
||||
if (!InitSpawn(si, read_stdout, newstdout)) {
|
||||
ErrorMessage(g_sdata.hwnd, _T("There was an error creating the pipe."));
|
||||
PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
if (!CreatePipe(&read_stdin,&newstdin,&sa,0)) {
|
||||
ErrorMessage(g_sdata.hwnd,_T("There was an error creating the input pipe."));
|
||||
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
|
||||
return 1;
|
||||
}
|
||||
GetStartupInfo(&si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.hStdOutput = newstdout;
|
||||
si.hStdError = newstdout;
|
||||
si.hStdInput = newstdin;
|
||||
if (!CreateProcess(NULL,g_sdata.compile_command,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
|
||||
TCHAR buf[MAX_STRING];
|
||||
wsprintf(buf,_T("Could not execute:\r\n %s."),g_sdata.compile_command);
|
||||
ErrorMessage(g_sdata.hwnd,buf);
|
||||
CloseHandle(newstdout);
|
||||
CloseHandle(read_stdout);
|
||||
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!CreateProcess(0, g_sdata.compile_command, 0, 0, TRUE, CREATE_NEW_CONSOLE, 0, 0, &si, &pi)) {
|
||||
TCHAR buf[MAX_STRING]; // BUGBUG: TODO: Too small?
|
||||
wsprintf(buf,_T("Could not execute:\r\n %s."), g_sdata.compile_command);
|
||||
ErrorMessage(g_sdata.hwnd, buf);
|
||||
FreeSpawn(0, read_stdout, newstdout);
|
||||
PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(newstdout); // close this handle (duplicated in subprocess) now so we get ERROR_BROKEN_PIPE
|
||||
|
@ -774,8 +759,9 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
|
|||
#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
|
||||
// BUGBUG: What if the line is longer than sizeof(iobuf)?
|
||||
char* lastLF = strrchr(iobuf,'\n');
|
||||
if (lastLF == NULL) lastLF = iobuf+dwRead-1;
|
||||
if (!lastLF) lastLF = iobuf+dwRead-1;
|
||||
char ch = *++lastLF;
|
||||
*lastLF = '\0';
|
||||
MultiByteToWideChar(CP_UTF8,0,iobuf,lastLF+1-iobuf,buf,COUNTOF(buf));
|
||||
|
@ -794,15 +780,9 @@ DWORD WINAPI MakeNSISProc(LPVOID p) {
|
|||
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(read_stdout);
|
||||
CloseHandle(newstdin);
|
||||
CloseHandle(read_stdin);
|
||||
PostMessage(g_sdata.hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
|
||||
FreeSpawn(&pi, read_stdout, 0);
|
||||
g_sdata.retcode = pi.dwProcessId;
|
||||
PostMessage(g_sdata.hwnd, WM_MAKENSIS_PROCESSCOMPLETE, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ namespace MakensisAPI {
|
|||
NOTIFY_ERROR,
|
||||
NOTIFY_OUTPUT
|
||||
};
|
||||
enum sndmsg_e {
|
||||
QUERYHOST = WM_APP
|
||||
};
|
||||
enum QUERYHOST_e {
|
||||
QH_OUTPUTCHARSET = 1
|
||||
};
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -568,57 +568,73 @@ void ResetSymbols() {
|
|||
}
|
||||
}
|
||||
|
||||
int InitBranding() {
|
||||
TCHAR *s;
|
||||
TCHAR opt[] = _T(" /version");
|
||||
s = (TCHAR *)GlobalAlloc(GPTR,(lstrlen(EXENAME)+lstrlen(opt)+1)*sizeof(TCHAR));
|
||||
lstrcpy(s, EXENAME);
|
||||
lstrcat(s, opt);
|
||||
{
|
||||
STARTUPINFO si={sizeof(si),};
|
||||
SECURITY_ATTRIBUTES sa={sizeof(sa),};
|
||||
SECURITY_DESCRIPTOR sd={0,};
|
||||
PROCESS_INFORMATION pi={0,};
|
||||
HANDLE newstdout=0,read_stdout=0;
|
||||
void FreeSpawn(PROCESS_INFORMATION *pPI, HANDLE hRd, HANDLE hWr) {
|
||||
if (pPI) {
|
||||
GetExitCodeProcess(pPI->hProcess, &pPI->dwProcessId);
|
||||
CloseHandle(pPI->hProcess);
|
||||
CloseHandle(pPI->hThread);
|
||||
}
|
||||
CloseHandle(hRd);
|
||||
CloseHandle(hWr);
|
||||
}
|
||||
BOOL InitSpawn(STARTUPINFO &si, HANDLE &hRd, HANDLE &hWr) {
|
||||
OSVERSIONINFO osv = {sizeof(osv)};
|
||||
GetVersionEx(&osv);
|
||||
const bool winnt = VER_PLATFORM_WIN32_NT == osv.dwPlatformId;
|
||||
|
||||
OSVERSIONINFO osv={sizeof(osv)};
|
||||
GetVersionEx(&osv);
|
||||
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
||||
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd,true,NULL,false);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
}
|
||||
else sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = true;
|
||||
if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
GetStartupInfo(&si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
|
||||
SECURITY_ATTRIBUTES sa={sizeof(sa)};
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
if (winnt) {
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, true, NULL, false);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
}
|
||||
sa.bInheritHandle = true;
|
||||
BOOL okp = CreatePipe(&hRd, &hWr, &sa, 0);
|
||||
si.hStdOutput = hWr, si.hStdError = hWr;
|
||||
si.hStdInput = INVALID_HANDLE_VALUE;
|
||||
return okp;
|
||||
}
|
||||
|
||||
int InitBranding() {
|
||||
const TCHAR *opt = _T(" /version");
|
||||
UINT cch = lstrlen(EXENAME) + lstrlen(opt) + 1;
|
||||
TCHAR *s = (TCHAR *)GlobalAlloc(GPTR, cch*sizeof(TCHAR));
|
||||
if (s) {
|
||||
lstrcpy(s, EXENAME);
|
||||
lstrcat(s, opt);
|
||||
STARTUPINFO si;
|
||||
HANDLE newstdout, read_stdout;
|
||||
if (!InitSpawn(si, read_stdout, newstdout)) return 0;
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!CreateProcess(0, s, 0, 0, TRUE, CREATE_NEW_CONSOLE, 0, 0, &si, &pi)) {
|
||||
FreeSpawn(0, read_stdout, newstdout);
|
||||
return 0;
|
||||
}
|
||||
GetStartupInfo(&si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.hStdOutput = newstdout;
|
||||
si.hStdError = newstdout;
|
||||
if (!CreateProcess(NULL,s,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
|
||||
CloseHandle(newstdout);
|
||||
CloseHandle(read_stdout);
|
||||
return 0;
|
||||
char szBuf[1024], retval = 0;
|
||||
DWORD dwRead = 0;
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, 10000)) {
|
||||
ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL);
|
||||
retval = 1;
|
||||
}
|
||||
char szBuf[1024];
|
||||
DWORD dwRead = 1;
|
||||
if (WaitForSingleObject(pi.hProcess,10000)!=WAIT_OBJECT_0) {
|
||||
return 0;
|
||||
}
|
||||
ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL);
|
||||
FreeSpawn(&pi, read_stdout, newstdout);
|
||||
szBuf[dwRead] = 0;
|
||||
int len = lstrlenA(szBuf);
|
||||
if (len==0) return 0;
|
||||
g_sdata.branding = (TCHAR *)GlobalAlloc(GPTR,(len+6)*sizeof(TCHAR));
|
||||
wsprintf(g_sdata.branding,_T("NSIS %hs"),szBuf);
|
||||
g_sdata.brandingv = (char *)GlobalAlloc(GPTR,len+1);
|
||||
lstrcpyA(g_sdata.brandingv,szBuf);
|
||||
if (len==0) retval = 0;
|
||||
g_sdata.branding = (TCHAR *)GlobalAlloc(GPTR, (len+6)*sizeof(TCHAR)); // LEAKED
|
||||
wsprintf(g_sdata.branding, _T("NSIS %hs"), szBuf);
|
||||
g_sdata.brandingv = (char *)GlobalAlloc(GPTR, len+1); // LEAKED
|
||||
lstrcpyA(g_sdata.brandingv, szBuf);
|
||||
GlobalFree(s);
|
||||
return retval;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -627,7 +643,7 @@ void InitTooltips(HWND h) {
|
|||
memset(&g_tip,0,sizeof(NTOOLTIP));
|
||||
g_tip.tip_p = h;
|
||||
INITCOMMONCONTROLSEX icx;
|
||||
icx.dwSize = sizeof(icx);
|
||||
icx.dwSize = sizeof(icx);
|
||||
icx.dwICC = ICC_BAR_CLASSES;
|
||||
InitCommonControlsEx(&icx);
|
||||
DWORD dwStyle = WS_POPUP | WS_BORDER | TTS_ALWAYSTIP;
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#define MRU_LIST_SIZE 5
|
||||
#define MRU_DISPLAY_LENGTH 40
|
||||
|
||||
void FreeSpawn(PROCESS_INFORMATION *pPI, HANDLE hRd, HANDLE hWr);
|
||||
BOOL InitSpawn(STARTUPINFO &si, HANDLE &hRd, HANDLE &hWr);
|
||||
|
||||
int SetArgv(const TCHAR *cmdLine, TCHAR ***argv);
|
||||
void SetTitle(HWND hwnd,const TCHAR *substr);
|
||||
void SetBranding(HWND hwnd);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue