void DeleteCharBackward(HIMC hIMC,WORD wParam) { if(wConversionMode & CONVERSION_MODE_PHRASETOCHAR){ MakeResultString(hIMC,FALSE); } else if( wConversionMode & CONVERSION_MODE_I || wConversionMode & CONVERSION_MODE_U || wConversionMode & CONVERSION_MODE_V ) { LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPCOMPOSITIONSTRING lpCompStr; GENEMSG GnMsg; LPTSTR lpStr; lpIMC = ImmLockIMC(hIMC); lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]); lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if( !lpCandList->dwCount ) MakeResultString(hIMC,FALSE); else{ lpCandList->dwCount = 0; lpStr = GETLPCOMPSTR(lpCompStr); lpStr = CharPrev(lpStr,lpStr + _tcslen(lpStr)); *lpStr= _T('\0'); lpStr = ((LPMYCOMPSTR)lpCompStr)->FreePYComp.szPaintCompStr; lpStr = CharPrev(lpStr,lpStr + _tcslen(lpStr)); *lpStr= _T('\0'); GnMsg.msg = WM_IME_COMPOSITION; GnMsg.wParam = 0; GnMsg.lParam = GCS_COMPSTR; GenerateMessage(hIMC, lpdwCurTransKey,(LPGENEMSG)&GnMsg); } ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); } else AddChar(hIMC,wParam,EDIT_BACK); return; }
void FormatToStream(_In_ FILE * stream, _In_ DWORD fmt,...) /*++ Routine Description: Format text to stream using a particular msg-id fmt Used for displaying localizable messages Arguments: stream - file stream to output to, stdout or stderr fmt - message id ... - parameters %1... Return Value: none --*/ { va_list arglist; LPTSTR locbuffer = NULL; DWORD count; va_start(arglist, fmt); count = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, fmt, 0, // LANGID (LPTSTR) &locbuffer, 0, // minimum size of buffer &arglist); if(locbuffer) { if(count) { int c; int back = 0; // // strip any trailing "\r\n"s and replace by a single "\n" // while(((c = *CharPrev(locbuffer,locbuffer+count)) == TEXT('\r')) || (c == TEXT('\n'))) { count--; back++; } if(back) { locbuffer[count++] = TEXT('\n'); locbuffer[count] = TEXT('\0'); } // // now write to apropriate stream // _fputts(locbuffer,stream); } LocalFree(locbuffer); } }
static char *scanstr_back(char *str, char *toscan, char *defval) { char *s=str+strlen(str)-1; if (strlen(str) < 1) return defval; if (strlen(toscan) < 1) return defval; while (1) { char *t=toscan; while (*t) if (*t++ == *s) return s; t=CharPrev(str,s); if (t==s) return defval; s=t; } }
void TrimString(TCHAR *pszStr) { int i; TCHAR *psz,szChars[]=_T(" \r\n\t"); for(i=0;i<SIZEOF(szChars);++i) { /* trim end */ psz=&pszStr[lstrlen(pszStr)-1]; while(pszStr[0] && *psz==szChars[i]) { *psz=0; psz=CharPrev(pszStr,psz); } /* trim beginning */ for(psz=pszStr;(*psz && *psz==szChars[i]);psz=CharNext(psz)); MoveMemory(pszStr,psz,(lstrlen(psz)+1)*sizeof(TCHAR)); } }
static int NSDFUNC ConvertPlacement(char *str, int total, int height) { char unit = *CharPrev(str, str + lstrlen(str)); int x = myatoi(str); if (unit == '%') { if (x < 0) { return MulDiv(total, 100 + x, 100); } return MulDiv(total, x, 100); } else if (unit == 'u') { RECT r; r.left = r.top = x; r.right = r.bottom = 0; MapDialogRect(g_dialog.hwParent, &r); if (height) return x >= 0 ? r.top : total + r.top; else return x >= 0 ? r.left : total + r.left; } if (x < 0) { return total + x; } return x; }
//Save document with (possibly) a new file name BOOL FAR SaveDocument(int doc, LPSTR FileName) { LPLINEREC pl; LPBLOCKDEF pb; long y; register WORD i; WORD len; HCURSOR hSaveCursor; LPDOCREC d = &Docs[doc]; //Set the Hour glass cursor hSaveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); //Create file if (HFILE_ERROR == (hFileDoc = _lcreat(FileName, 0)) ) { ErrorBox(ERR_File_Create, (LPSTR)FileName); goto error0; } //Allocate space for Disk Buffer if ((pszBufferDoc = DocAlloc(DISK_BLOCK_SIZE)) == NULL) { ErrorBox(SYS_Allocate_Memory); goto error1; } dwOffsetDoc = 0; y = 0; //Get first line if (!FirstLine (doc, &pl, &y, &pb)) return FALSE; //Save each line of file while (TRUE) { //Remove trailing blanks len = (WORD) (pl->Length - LHD); { TCHAR *pch1; pch1 = pl->Text + (pl->Length - LHD); while (pch1 > pl->Text) { pch1 = CharPrev(pl->Text, pch1); if (*pch1 != ' ' && *pch1 != TAB) { break; } len --; } } //Write line i = 0; while (i < len) { PutChar(FileName, pl->Text[i]); i++; } if (y >= d->NbLines) { if (dwOffsetDoc && !Flush(FileName)) goto error2; break; } else { PutChar (FileName, CR); PutChar (FileName, LF); if (!NextLine (doc, &pl, &y, &pb)) goto error2; } } CloseHandle (hFileDoc); //Update internal file date GetSystemTimeAsFileTime(&d->time); CloseLine(doc, &pl, y, &pb); d->ismodified = FALSE; RefreshWindowsTitle(doc); SetCursor (hSaveCursor); return TRUE; error2: CloseLine(doc, &pl, y, &pb); if (!DocFree(pszBufferDoc)) InternalErrorBox(SYS_Free_Memory); error1: CloseHandle (hFileDoc); error0: SetCursor (hSaveCursor); return FALSE; } /* SaveDocument() */
BOOL view_findstring(VIEW view, LONG iCol, LPCSTR pszFind, BOOL fSearchDown, BOOL fMatchCase, BOOL fWholeWord) { const LONG cRows = view_getrowcount(view); BOOL fFound = FALSE; if (cRows > 0) { STRSUBFUNC pfnSub = (fMatchCase) ? My_mbsstr : My_mbsistr; const char *pszRow = NULL; const char *pszFound = NULL; char *pszEnd = NULL; LONG iEnd = 0; LONG iRow = 0; LONG nStep = 0; LONG iWrapAt = 0; LONG iWrapTo = 0; if (fSearchDown) { nStep = 1; iRow = selection + selection_nrows - 1; iWrapAt = cRows; iWrapTo = 0; } else { nStep = -1; iRow = selection; iWrapAt = -1; iWrapTo = cRows - 1; } iRow += nStep; if (iRow < 0 || iRow >= cRows) { iRow = iWrapTo; } iEnd = iRow; for (;;) { pszRow = view_gettext(view, iRow, iCol); if (pszRow) { pszEnd = NULL; pszFound = (const char*)pfnSub((PUCHAR)pszRow, (PUCHAR)pszFind, (PUCHAR*)&pszEnd); if (pszFound) { if (!fWholeWord) { fFound = TRUE; } else { /* check end of string */ if (!pszEnd || !*pszEnd || (!IsDBCSLeadByte(*pszEnd) && !isalpha((UCHAR)*pszEnd) && !isdigit((UCHAR)*pszEnd))) { /* check beginning of string */ if (pszFound == pszRow) { fFound = TRUE; } else { const char *pchT = CharPrev(pszRow, pszFound); if (!pchT || !*pchT || (!IsDBCSLeadByte(*pchT) && !isalpha((UCHAR)*pchT) && !isdigit((UCHAR)*pchT))) { fFound = TRUE; } } } } if (fFound) { view_gototableline(view, iRow); break; } } } iRow += nStep; if (iRow == iWrapAt) { iRow = iWrapTo; } if (iRow == iEnd) { break; } } } return fFound; }
int main(int argc, char **argv) { CEXEBuild build; int do_cd=1; int outputtried=0; int argpos=1; int nousage=0; int files_processed=0; int cmds_processed=0; int plugins_processed=0; FILE *fp; int tmpargpos=1; int no_logo=0; if (argc > 1 && !stricmp(argv[1], "/VERSION")) { fprintf(g_output,NSIS_VERSION); fflush(g_output); return 0; } if (argc > 1 && argv[1][0]=='/' && (argv[1][1]=='v' || argv[1][1]=='V')) { tmpargpos++; if (argv[1][2] <= '2' && argv[1][2] >= '0') { no_logo=1; } } if (!no_logo) { if (argc > tmpargpos && argv[tmpargpos][0]=='/' && (argv[tmpargpos][1]=='o' || argv[tmpargpos][1]=='O') && argv[tmpargpos][2]) { g_output=fopen(argv[tmpargpos]+2,"w"); if (!g_output) { printf("Error opening output log for writing. Using stdout.\n"); g_output=stdout; } outputtried=1; } fprintf(g_output,"MakeNSIS %s - Copyright 1999-2003 Nullsoft, Inc.\n" "\n" "Portions Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler (zlib).\n" "Includes portions derived from bzip2 (see documentation for details).\n" "Contributors: [email protected], Ryan Geiss, Andras Varga, Drew Davidson, Peter Windridge, Dave Laundon, Robert Rainwater, Yaroslav Faybishenko, Jeff Doozan, Amir Szekely, Ximon Eighteen, et al.\n\n",NSIS_VERSION); fflush(g_output); } atexit(myatexit); signal(SIGINT,sigint); if (!g_output) g_output=stdout; while (argpos < argc) { if (argv[argpos][0]=='/' && (argv[argpos][1]=='D' || argv[argpos][1]=='d') && argv[argpos][2]) { char *p=argv[argpos]+2; if (p[0]) { char *s=strdup(p),*v; if (build.display_script) { fprintf(g_output,"Command line defined: \"%s\"\n",p); fflush(g_output); } v=strstr(s,"="); if (v) *v++=0; build.define(s,v?v:""); free(s); } else { build.warning("command line /D requires argument (i.e. \"/Ddefine\"). ignored."); } } else if (argv[argpos][0]=='/' && (argv[argpos][1]=='X' || argv[argpos][1]=='x') && argv[argpos][2]) { if (build.process_oneline(argv[argpos]+2,"command line",argpos+1) != PS_OK) { return 1; } cmds_processed++; } else if (argv[argpos][0]=='/' && (argv[argpos][1]=='O' || argv[argpos][1]=='o') && argv[argpos][2]) { if (!outputtried) { g_output=fopen(argv[argpos]+2,"w"); if (!g_output) { if (build.display_errors) printf("Error opening output log for writing. Using stdout.\n"); g_output=stdout; } outputtried=1; } } else if (!stricmp(argv[argpos],"/NOCD")) do_cd=0; else if (argv[argpos][0] == '/' && (argv[argpos][1] == 'V' || argv[argpos][1] == 'v') && argv[argpos][2] >= '0' && argv[argpos][2] <= '4' && !argv[argpos][3]) { int v=argv[argpos][2]-'0'; build.display_script=v>3; build.display_info=v>2; build.display_warnings=v>1; build.display_errors=v>0; g_display_errors=build.display_errors; } else if (!stricmp(argv[argpos],"/NOCONFIG")) g_noconfig=1; else if (!stricmp(argv[argpos],"/PAUSE")) g_dopause=1; else if (!stricmp(argv[argpos],"/LICENSE")) { if (build.display_info) { fprintf(g_output,"This software is provided 'as-is', without any express or implied warranty. In\n" "no event will the authors be held liable for any damages arising from the use\n" "of this software.\n\n" "Permission is granted to anyone to use this software for any purpose, including\n" "commercial applications, and to alter it and redistribute it freely, subject to\n" "the following restrictions:\n" " 1. The origin of this software must not be misrepresented; you must not claim\n" " that you wrote the original software. If you use this software in a\n" " product, an acknowledgment in the product documentation would be\n" " appreciated but is not required.\n" " 2. Altered source versions must be plainly marked as such, and must not be\n" " misrepresented as being the original software.\n" " 3. This notice may not be removed or altered from any source distribution.\n\n"); fflush(g_output); } nousage++; } else if (!stricmp(argv[argpos],"/CMDHELP")) { if (argpos < argc-1) build.print_help(argv[++argpos]); else build.print_help(NULL); nousage++; } else if (!stricmp(argv[argpos],"/NOTIFYHWND")) { build.notify_hwnd=(HWND)atol(argv[++argpos]); if (!IsWindow(build.notify_hwnd)) build.notify_hwnd=0; } else if (!stricmp(argv[argpos],"/HDRINFO")) { if (build.display_info) { fprintf(g_output,"Size of EXE header is %d bytes for zlib, %d bytes for bzip2.\n", zlib_exeheader_size,bzip2_exeheader_size); fprintf(g_output,"Size of info header is %d bytes.\n",sizeof(firstheader)); fprintf(g_output,"Size of [un]install header is %d bytes,\n",sizeof(header)); fprintf(g_output,"Size of each section is %d bytes.\n",sizeof(section)); fprintf(g_output,"Size of each page is %d bytes.\n",sizeof(page)); fprintf(g_output,"Size of each instruction is %d bytes.\n",sizeof(entry)); int x=build.definedlist.getnum(); fprintf(g_output,"\nDefined symbols: "); for (int i=0; i<x; i++) { fprintf(g_output,"%s",build.definedlist.getname(i)); char *p=build.definedlist.getvalue(i); if (*p) fprintf(g_output,"=%s",p); if (i<x-1) fprintf(g_output,","); } if (!x) fprintf(g_output,"none"); fprintf(g_output,"\n"); fflush(g_output); } nousage++; } else { if (argv[argpos][0]=='/') break; files_processed++; if (!strcmp(argv[argpos],"-")) g_dopause=0; if (!g_noconfig) { g_noconfig=1; char exepath[1024]; GetModuleFileName(NULL,exepath,sizeof(exepath)-1); //strncpy(exepath,argv[0],1023); exepath[1023]=0; char *p=exepath; while (*p) p++; while (p > exepath && *p != '\\') p=CharPrev(exepath,p); if (p>exepath) p++; strcpy(p,"nsisconf.nsh"); FILE *cfg=fopen(exepath,"rt"); if (cfg) { if (build.display_script) { fprintf(g_output,"\n\nProcessing config: \n"); fflush(g_output); } int ret=build.process_script(cfg,exepath); fclose(cfg); if (ret != PS_OK && ret != PS_EOF) { if (build.display_errors) { fprintf(g_output,"Error in config on line %d -- aborting creation process\n",build.linecnt); fflush(g_output); } return 1; } } } { char sfile[1024]; if (!strcmp(argv[argpos],"-")) { fp=stdin; strcpy(sfile,"stdin"); } else { strcpy(sfile,argv[argpos]); fp=fopen(sfile,"rt"); if (!fp) { sprintf(sfile,"%s.nsi",argv[argpos]); fp=fopen(sfile,"rt"); if (!fp) { if (build.display_errors) { sfile[strlen(sfile)-4]=0; fprintf(g_output,"Can't open script \"%s\"\n",sfile); fflush(g_output); } return 1; } } if (do_cd) { char dirbuf[1024],*p; GetFullPathName(sfile,sizeof(dirbuf),dirbuf,&p); p=dirbuf; while (*p) p++; while (p > dirbuf && *p != '\\') p=CharPrev(dirbuf,p); *p=0; if (dirbuf[0]) { if (build.display_script) { fprintf(g_output,"Changing directory to: \"%s\"\n",dirbuf); fflush(g_output); } if (!SetCurrentDirectory(dirbuf)) { if (build.display_errors) { fprintf(g_output,"Error changing directory to \"%s\"\n",dirbuf); fflush(g_output); } return 1; } } } } #ifdef NSIS_CONFIG_PLUGIN_SUPPORT // Added by Ximon Eighteen 5th August 2002 if (!plugins_processed) { build.build_plugin_table(); plugins_processed=1; } #endif //NSIS_CONFIG_PLUGIN_SUPPORT if (build.display_script) { build.notify(MAKENSIS_NOTIFY_SCRIPT,sfile); fprintf(g_output,"\n\nProcessing script file: \"%s\"\n",sfile); fflush(g_output); } int ret=build.process_script(fp,sfile); if (fp != stdin) fclose(fp); if (ret != PS_EOF && ret != PS_OK) { if (build.display_errors) { fprintf(g_output,"Error in script \"%s\" on line %d -- aborting creation process\n",sfile,build.linecnt); fflush(g_output); } return 1; } } } argpos++; } if (argpos<argc || (!files_processed && !cmds_processed)) { if (build.display_errors && !nousage) { fprintf(g_output,"Usage:\n" " makensis [options] [script.nsi | - [...]]\n" " options are:\n" " /CMDHELP item prints out help for 'item', or lists all commands\n" " /HDRINFO prints information about what options makensis was compiled with\n" " /LICENSE prints the makensis software license\n"); fprintf(g_output, " /Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n" " /Ofile specifies a text file to log compiler output (default is stdout)\n" " /PAUSE pauses after execution\n" " /NOCONFIG disables inclusion of <path to makensis.exe>\\nsisconf.nsh\n" " /NOCD disabled the current directory change to that of the .nsi file\n" " /Ddefine[=value] defines the symbol \"define\" for the script [to value]\n" " /Xscriptcmd executes scriptcmd in script (i.e. \"/XOutFile poop.exe\")\n" " for script file name, you can use - to read from the standard input\n"); fflush(g_output); } return 1; } if (build.display_info) { fprintf(g_output,"\nProcessed "); if (files_processed) fprintf(g_output,"%d file%s, ",files_processed,files_processed==1?"":"s"); if (cmds_processed) fprintf(g_output,"%d command line command%s, ",cmds_processed,cmds_processed==1?"":"s"); fprintf(g_output,"writing output:\n"); fflush(g_output); } if (build.write_output()) { if (build.display_errors) { fprintf(g_output,"Error - aborting creation process\n"); fflush(g_output); } return 1; } return 0; }
void ExecScript(int log) { char szRet[128] = ""; char meDLLPath[MAX_PATH]; char *executor; char *g_exec; char *pExec; unsigned int g_to; BOOL bOEM; if (!IsWOW64()) { char *p; int nComSpecSize; nComSpecSize = GetModuleFileName(g_hInst, meDLLPath, MAX_PATH) + 2; // 2 chars for quotes g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+nComSpecSize+2); // 1 for space, 1 for null p = meDLLPath + nComSpecSize - 2; // point p at null char of meDLLPath *g_exec = '"'; executor = g_exec + 1; do { if (*p == '\\') break; p = CharPrev(meDLLPath, p); } while (p > meDLLPath); if (p == meDLLPath) { // bad path pushstring("error"); GlobalFree(g_exec); return; } *p = 0; GetTempFileName(meDLLPath, "ns", 0, executor); *p = '\\'; if (CopyFile(meDLLPath, executor, FALSE)) { HANDLE hFile, hMapping; LPBYTE pMapView; PIMAGE_NT_HEADERS pNTHeaders; hFile = CreateFile(executor, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0); hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); pMapView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0); if (pMapView) { pNTHeaders = (PIMAGE_NT_HEADERS)(pMapView + ((PIMAGE_DOS_HEADER)pMapView)->e_lfanew); pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE; pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD)WinMain - (DWORD)g_hInst; UnmapViewOfFile(pMapView); } CloseHandle(hMapping); CloseHandle(hFile); } lstrcat(g_exec, "\""); // add space pExec = g_exec + lstrlen(g_exec); *pExec = ' '; pExec++; } else { executor = NULL; g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+1); // 1 for null pExec = g_exec; } g_to = 0; // default is no timeout bOEM = FALSE; // default is no OEM->ANSI conversion g_hwndList = NULL; if (g_hwndParent) g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,"#32770",NULL),NULL,"SysListView32",NULL); params: popstring(pExec); if (my_strstr(pExec, "/TIMEOUT=") == pExec) { char *szTimeout = pExec + 9; g_to = my_atoi(szTimeout); *pExec = 0; goto params; } if (!lstrcmpi(pExec, "/OEM")) { bOEM = TRUE; *pExec = 0; goto params; } if (!pExec[0]) { pushstring("error"); *(pExec-2) = '\0'; // skip space and quote if (executor) DeleteFile(executor); GlobalFree(g_exec); return; } { STARTUPINFO si={sizeof(si),}; SECURITY_ATTRIBUTES sa={sizeof(sa),}; SECURITY_DESCRIPTOR sd={0,}; PROCESS_INFORMATION pi={0,}; OSVERSIONINFO osv={sizeof(osv)}; HANDLE newstdout=0,read_stdout=0; HANDLE newstdin=0,read_stdin=0; DWORD dwRead = 1; DWORD dwExit = 0; DWORD dwWait = WAIT_TIMEOUT; DWORD dwLastOutput; static char szBuf[1024]; HGLOBAL hUnusedBuf = NULL; char *szUnusedBuf = 0; if (log) { hUnusedBuf = GlobalAlloc(GHND, log & 2 ? g_stringsize : sizeof(szBuf)*4); if (!hUnusedBuf) { lstrcpy(szRet, "error"); goto done; } szUnusedBuf = (char *)GlobalLock(hUnusedBuf); } 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)) { lstrcpy(szRet, "error"); goto done; } if (!CreatePipe(&read_stdin,&newstdin,&sa,0)) { lstrcpy(szRet, "error"); goto done; } GetStartupInfo(&si); si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdInput = newstdin; si.hStdOutput = newstdout; si.hStdError = newstdout; if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) { lstrcpy(szRet, "error"); goto done; } dwLastOutput = GetTickCount(); while (dwWait != WAIT_OBJECT_0 || dwRead) { PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); if (dwRead) { dwLastOutput = GetTickCount(); ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL); szBuf[dwRead] = 0; if (log) { char *p, *p2; SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf); if (GlobalSize(hUnusedBuf) < iReqLen && (iReqLen < g_stringsize || !(log & 2))) { GlobalUnlock(hUnusedBuf); hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND); if (!hUnusedBuf) { lstrcpy(szRet, "error"); break; } szUnusedBuf = (char *)GlobalLock(hUnusedBuf); } p = szUnusedBuf; // get the old left overs if (iReqLen < g_stringsize || !(log & 2)) lstrcat(p, szBuf); else { lstrcpyn(p + lstrlen(p), szBuf, g_stringsize - lstrlen(p)); } if (!(log & 2)) { while ((p = my_strstr(p, "\t"))) { if ((int)(p - szUnusedBuf) > (int)(GlobalSize(hUnusedBuf) - TAB_REPLACE_SIZE - 1)) { *p++ = ' '; } else { int len = lstrlen(p); char *c_out=(char*)p+TAB_REPLACE_SIZE+len; char *c_in=(char *)p+len; while (len-- > 0) { *c_out--=*c_in--; } lstrcpy(p, TAB_REPLACE); p += TAB_REPLACE_SIZE; *p = ' '; } } p = szUnusedBuf; // get the old left overs for (p2 = p; *p2;) { if (*p2 == '\r') { *p2++ = 0; continue; } if (*p2 == '\n') { *p2 = 0; while (!*p && p != p2) p++; LogMessage(p, bOEM); p = ++p2; continue; } p2 = CharNext(p2); } // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf if (p != szUnusedBuf) { char *p2 = szUnusedBuf; while (*p) *p2++ = *p++; *p2 = 0; } } } } else { if (g_to && GetTickCount() > dwLastOutput+g_to) { TerminateProcess(pi.hProcess, -1); lstrcpy(szRet, "timeout"); } else Sleep(LOOPTIMEOUT); } dwWait = WaitForSingleObject(pi.hProcess, 0); GetExitCodeProcess(pi.hProcess, &dwExit); PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); } done: if (log & 2) pushstring(szUnusedBuf); if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf, bOEM); if ( dwExit == STATUS_ILLEGAL_INSTRUCTION ) lstrcpy(szRet, "error"); if (!szRet[0]) wsprintf(szRet,"%d",dwExit); pushstring(szRet); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(newstdin); CloseHandle(read_stdin); *(pExec-2) = '\0'; // skip space and quote if (executor) DeleteFile(executor); GlobalFree(g_exec); if (log) { GlobalUnlock(hUnusedBuf); GlobalFree(hUnusedBuf); } } }
int ExecuteEntry(HANDLE hFile, int offset, entry *thisentry) { static TCHAR buf[MAX_PATH], buf2[MAX_PATH], tmpbuf[MAX_PATH]; if (skip && thisentry->which != 15) return 0; switch (thisentry->which) { case 0: // set output directory if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { if (!buf[0]) { _tcscpy(state_output_directory,state_install_directory); } else { if (process_string(state_output_directory,buf,state_install_directory)) _tcscpy(state_output_directory,state_install_directory); } log_printf3("SetOutPath: \"%s\"->\"%s\"\n",buf,state_output_directory); { INT32 args[] = { (INT32)state_output_directory }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_OUTDIR, args); update_status_text(tmpbuf); } recursive_create_directory(state_output_directory); return 0; } log_printf("SetOutPath: INSTALLER CORRUPTED\n"); break; case 1: // extract file { TCHAR tempFile[MAX_PATH]; int queueForRebootFlag = 0; int overwriteflag=thisentry->offsets[0]; LPTSTR p; _tcscpy(buf,state_output_directory); p=buf; while (*p) p=CharNext(p); if (p == buf || (CharPrev(buf,p))[0]!=_T('\\')) _tcscat(buf,_T("\\")); if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf2,MAX_PATH)) { HANDLE hOut; int ret; log_printf3("File: overwriteflag=%d, name=\"%s\"\n",overwriteflag,buf2); _tcscat(buf,buf2); _tryagain: if ((overwriteflag&3)==0) { int attr=GetFileAttributes(buf); if (attr & FILE_ATTRIBUTE_READONLY) SetFileAttributes(buf,attr^FILE_ATTRIBUTE_READONLY); } hOut=CreateFile(buf,GENERIC_WRITE,0,NULL,(overwriteflag&1)?CREATE_NEW:CREATE_ALWAYS,0,NULL); if (hOut == INVALID_HANDLE_VALUE) { if (overwriteflag&3) { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_SKIPPED, args); update_status_text(tmpbuf); log_printf3("File: skipping: \"%s\" (overwriteflag=%d)\n",buf,overwriteflag); return 0; } log_printf2("File: error creating \"%s\"\n",buf); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_ERROR_OPENWRITE, args); wsprintf(buf2, _T("%s"), tmpbuf); } /* If we're not in silent mode then tell the user up front that */ /* the file is locked. Otherwise (silent mode), queue the file */ /* for copy on next reboot. */ if (noisy) { switch (MessageBox(g_hwnd,buf2,g_caption,MB_ABORTRETRYIGNORE|MB_ICONSTOP)) { case IDABORT: log_printf("File: on error, user selected abort.\n"); { INT32 args[]={ (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_ERROR_ABORTWRITE, args); update_status_text(tmpbuf); } return -2; case IDRETRY: log_printf("File: on error, user selected retry.\n"); goto _tryagain; case IDIGNORE: log_printf("File: on error, user selected cancel.\n"); return 0; } } else { /* try to queue the file for copy on reboot */ GetTempFileName(g_tempdir, "jws", 0, tempFile); hOut=CreateFile(tempFile,GENERIC_WRITE,0,NULL,(overwriteflag&1)?CREATE_NEW:CREATE_ALWAYS,0,NULL); if (hOut == INVALID_HANDLE_VALUE) return 0; queueForRebootFlag = 1; } } { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_EXTRACT, args); update_status_text(tmpbuf); } ret=GetCompressedDataFromDataBlock(hFile,offset+thisentry->offsets[2],hOut); log_printf3("File: wrote %d to \"%s\"\n",ret,buf); CloseHandle(hOut); if (ret >= 0) { if (queueForRebootFlag == 1) { TCHAR winini[MAX_PATH]; TCHAR shortname[MAX_PATH]; TCHAR rebootFlagFile[MAX_PATH]; int len; _tcscpy(rebootFlagFile, g_tempdir); _tcscat(rebootFlagFile, JAVAWS_REBOOT_FILENAME); if (IsRunningOnNT4() || IsRunningOn2000XP()) { MoveFileEx(tempFile, buf, MOVEFILE_DELAY_UNTIL_REBOOT); MoveFileEx(rebootFlagFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } else { /* queue for copy on boot; tempFile is the file to be copied */ /* buf holds the target filename that was locked previously. */ GetWindowsDirectory(winini, MAX_PATH); /* append a trailing backslash if necessary */ len = _tcslen(winini); if (winini[len - 1] != '\\') { winini[len] = '\\'; winini[len+1] = 0; } _tcscat(winini, "WININIT.INI"); /* write to the wininit.ini file to queue the file for copy on */ /* reboot. */ GetShortPathName(buf, shortname, MAX_PATH); WritePrivateProfileString("rename", shortname, tempFile, winini); /* write the wininit.ini file to tell Windows to delete the */ /* reboot flag file after it reboots */ WritePrivateProfileString("rename", "NUL", rebootFlagFile, winini); } /* write the reboot flag file */ WritePrivateProfileString(JAVAWS_APPLICATION_NAME, JAVAWS_REBOOT_KEY, "1", rebootFlagFile); state_reboot_needed = 1; } return ret; } if (ret == -3 || ret == -6) { log_printf2("File: INSTALLER CORRUPTED (gcdfdb:%d)\n",ret); goto installer_corrupted; } else { DeleteFile(buf); log_printf("File: error writing. deleted.\n"); return -2; } } log_printf("File: INSTALLER CORRUPTED\n"); } break; case 2: // execute program { PROCESS_INFORMATION ProcInfo={0,}; STARTUPINFO StartUp={sizeof(STARTUPINFO),}; int disabled = 0; if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf2,sizeof(buf2))) { log_printf2("Exec: command=\"%s\"\n",buf2); if (process_string(buf,buf2,state_install_directory)) _tcscpy(buf,buf2); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_EXECUTE, args); update_status_text(tmpbuf); } if (IsWindowEnabled(GetDlgItem(g_hwnd,IDOK))!=0) { /* if Next button is already disabled, don't disable */ /* and re-enable it. (bug 4624948) */ EnableWindow(GetDlgItem(g_hwnd,IDOK), 0); disabled = 1; } if (CreateProcess( NULL, buf, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, state_output_directory, &StartUp, &ProcInfo) ) { log_printf2("Exec: success (\"%s\")\n",buf); if (NULL != ProcInfo.hThread) CloseHandle( ProcInfo.hThread ); if (NULL != ProcInfo.hProcess) { if (thisentry->offsets[1]==1) { WaitForSingleObject(ProcInfo.hProcess,INFINITE); ShowWindow(g_hwnd,SW_HIDE); ShowWindow(g_hwnd,SW_SHOW); InvalidateRect(g_hwnd,NULL,TRUE); UpdateWindow(g_hwnd); while (1) { MSG msg; if (!PeekMessage(&msg,g_hwnd,WM_PAINT,WM_PAINT,PM_REMOVE)) break; DispatchMessage(&msg); } } { DWORD exitcode; if (!GetExitCodeProcess(ProcInfo.hProcess, (LPDWORD)&exitcode)) { log_printf("Exec: failed getting exit code\n"); state_return_value = STATE_RETURN_INVALID; } else { state_return_value = exitcode; } } CloseHandle( ProcInfo.hProcess ); } } else { log_printf2("Exec: failed createprocess (\"%s\")\n",buf); } if (disabled != 0) { EnableWindow(GetDlgItem(g_hwnd,IDOK), 1); } return 0; } log_printf("Exec: INSTALLER CORRUPTED\n"); } break; case 3: // register DLL #ifdef NSIS_SUPPORT_ACTIVEXREG if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf2,sizeof(buf2))) { HRESULT hr; hr=OleInitialize(NULL); if (hr == S_OK || hr == S_FALSE) { if (!process_string(buf,buf2,state_install_directory)) { HANDLE h; int is_uninstall=0; if (buf[0] == _T('-') && buf[1] == _T(' ')) is_uninstall=2; h=LoadLibrary(buf+is_uninstall); if (h) { FARPROC funke = GetProcAddress(h,is_uninstall?"DllUnregisterServer":"DllRegisterServer"); if (funke) { if (!is_uninstall) { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_REGDLL, args); update_status_text(tmpbuf); } else { INT32 args[] = { (INT32)buf+is_uninstall }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_UNREGDLL, args); update_status_text(tmpbuf); } funke(); } else if (!is_uninstall) { INT32 args[] = { (INT32)buf }; GETRESOURCE2(buf2,JAVAWS_ERROR_REGDLL,args); if (noisy) MessageBox(g_hwnd,buf2,g_caption,MB_OK); } FreeModule(h); } else if (!is_uninstall) { INT32 args[] = { (INT32)buf }; GETRESOURCE2(buf2,JAVAWS_ERROR_REGDLLU, args); if (noisy) MessageBox(g_hwnd,buf2,g_caption,MB_OK); } } if (hr == S_OK) OleUninitialize(); } else { INT32 args[] = { (INT32)buf }; GETRESOURCE2(buf2,JAVAWS_ERROR_OLEINIT,args); if (noisy) MessageBox(g_hwnd,buf2,g_caption,MB_OK); } return 0; } #endif break; case 4: // install netscape plug-in case 11: #ifdef NSIS_SUPPORT_NETSCAPEPLUGINS #warning NSIS_SUPPORT_NETSCAPEPLUGINS defined, this section NOT internationalized, proceed with caution! if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf2,sizeof(buf2))) { HKEY hKey; if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Netscape\\Netscape Navigator",0,KEY_READ,&hKey) == ERROR_SUCCESS) { int x=0; while (1) { FILETIME pft; char name[256]; HKEY subKey; DWORD lname=sizeof(name); if (RegEnumKeyEx(hKey,x++,name,&lname,NULL,NULL,NULL,&pft) != ERROR_SUCCESS) break; mini_strcat(name,"\\Main"); if (RegOpenKeyEx(hKey,name,0,KEY_READ,&subKey) == ERROR_SUCCESS) { int l = sizeof(buf); int t=REG_SZ; if (RegQueryValueEx(subKey,"Plugins Directory",NULL,&t,buf,&l ) == ERROR_SUCCESS && t == REG_SZ) { mini_strcat(buf,"\\"); mini_strcat(buf,buf2); { HANDLE hOut=INVALID_HANDLE_VALUE; retryagainns: { int attr=GetFileAttributes(buf); if (attr & FILE_ATTRIBUTE_READONLY) SetFileAttributes(buf,attr^FILE_ATTRIBUTE_READONLY); } hOut=CreateFile(buf,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); if (thisentry->which != 4) { if (hOut != INVALID_HANDLE_VALUE) { CloseHandle(hOut); hOut=(HANDLE)1; if (!DeleteFile(buf)) { log_printf2("InstNSPlug: error removing: %s\n",buf); hOut=INVALID_HANDLE_VALUE; } else log_printf2("InstNSPlug: removed: %s\n",buf); } else hOut=(HANDLE)1; } if (hOut == INVALID_HANDLE_VALUE) { if (MessageBox(g_hwnd,"Error accessing Netscape plug-in.\r\nMake sure all windows of Netscape are closed.\r\nHit Retry to try again, Cancel to skip",g_caption,MB_RETRYCANCEL|MB_APPLMODAL|MB_TOPMOST)==IDOK) goto retryagainns; log_printf2("InstNSPlug: install to %s aborted by user.\n",buf); } if (hOut != INVALID_HANDLE_VALUE && thisentry->which == 4) { int ret=GetCompressedDataFromDataBlock(hFile,offset+thisentry->offsets[1],hOut); CloseHandle(hOut); if (ret<0) { DeleteFile(buf); if (ret==-3) { log_printf("InstNSPlug: INSTALLER CORRUPTED (2)\n"); goto installer_corrupted; } log_printf2("InstNSPlug: couldn't write to: %s\n",buf); } else { update_status_text("installed netscape plug-in: ",buf); log_printf2("InstNSPlug: wrote: %s\n",buf); } } else if (thisentry->which == 11) { update_status_text("removed netscape plug-in: ",buf); } } } RegCloseKey(subKey); } } RegCloseKey(hKey); } else { log_printf("InstNSPlug: Netscape registry settings not found\n"); } return 0; } #endif log_printf("InstNSPlug: INSTALLER CORRUPTED\n"); break; case 12: if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf,sizeof(buf))) { int rootkey=thisentry->offsets[0]; if (thisentry->offsets[2] != -1) { HKEY hKey; if (RegOpenKey((HKEY)rootkey,buf,&hKey) == ERROR_SUCCESS) { if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf2,sizeof(buf2))) { if (process_string(buf,buf2,state_install_directory)) _tcscpy(buf,buf2); RegDeleteValue(hKey,buf); } RegCloseKey(hKey); } } else { log_printf3("DeleteRegKey: %d\\%s\n",rootkey,buf); RegDeleteKey((HKEY)rootkey,buf); } return 0; } break; case 5: // write registry value if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf,sizeof(buf)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf2,sizeof(buf2))) { int rootkey=thisentry->offsets[0]; int type=thisentry->offsets[4]; HKEY hKey; if (RegCreateKey((HKEY)rootkey,buf,&hKey) == ERROR_SUCCESS) { TCHAR buf4[MAX_PATH]; if (type == 1) { if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[3],buf4,sizeof(buf4))) { TCHAR buf3[MAX_PATH]; if (process_string(buf3,buf4,state_install_directory)) _tcscpy(buf3,buf4); if (process_string(buf4,buf2,state_install_directory)) _tcscpy(buf4,buf2); log_printf5("WriteRegStr: set %d\\%s\\%s to %s\n",rootkey,buf,buf4,buf3); RegSetValueEx(hKey,buf4,0,REG_SZ,buf3,_tcslen(buf3)+1); } } else if (type == 2) { if (process_string(buf4,buf2,state_install_directory)) _tcscpy(buf4,buf2); log_printf5("WriteRegDword: set %d\\%s\\%s to %d\n",rootkey,buf,buf4,thisentry->offsets[3]); RegSetValueEx(hKey,buf4,0,REG_DWORD,(BYTE*)&thisentry->offsets[3],4); } else if (type == 3) { BYTE data[512]; int len=GetCompressedDataFromDataBlockToMemory(hFile, offset+thisentry->offsets[3], data,sizeof(data)); if (len >= 0) { if (process_string(buf4,buf2,state_install_directory)) _tcscpy(buf4,buf2); RegSetValueEx(hKey,buf4,0,REG_BINARY,data,len); } log_printf5("WriteRegBin: set %d\\%s\\%s with %d bytes\n",rootkey,buf,buf4,len); } RegCloseKey(hKey); } else { log_printf3("WriteReg: error creating key %d\\%s\n",rootkey,buf); } if (type > 0 && type < 4) return 0; } log_printf("WriteReg: INSTALLER CORRUPTED\n"); break; case 6: { TCHAR section[MAX_PATH]; TCHAR name[MAX_PATH]; TCHAR t[MAX_PATH]; TCHAR t2[MAX_PATH]; if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],section,sizeof(section)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],name,sizeof(name)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf,sizeof(buf)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[3],buf2,sizeof(buf2))) { if (process_string(t,buf2,state_install_directory)) _tcscpy(t,buf2); if (process_string(buf2,buf,state_install_directory)) _tcscpy(buf2,buf); if (process_string(t2,name,state_install_directory)) _tcscpy(t2,name); if (process_string(buf,section,state_install_directory)) _tcscpy(buf,section); log_printf5("WriteINIStr: wrote [%s] %s=%s in %s\n",buf,t2,buf2,t); WritePrivateProfileString(buf,t2,buf2,t); return 0; } log_printf("WriteINIStr: INSTALLER CORRUPTED\n"); } break; case 7: #ifdef NSIS_SUPPORT_CREATESHORTCUT { TCHAR scf[MAX_PATH],iconfile[MAX_PATH], parms[MAX_PATH]; int iindex=thisentry->offsets[4]; if (GetStringFromDataBlock(hFile,offset+thisentry->offsets[3],buf,sizeof(buf))) break; if (process_string(iconfile,buf,state_install_directory)) break; if (GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf,sizeof(buf))) break; if (process_string(parms,buf,state_install_directory)) break; if (GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf,sizeof(buf))) break; if (process_string(buf2,buf,state_install_directory)) break; if (GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) break; if (process_string(scf,buf,state_install_directory)) break; log_printf6("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d\n",scf,buf2,parms,iconfile,iindex); CreateShortCut(g_hwnd, scf, iconfile[0]?iconfile:NULL, iindex, buf2, parms[0]?parms:NULL,state_output_directory); { INT32 args[] = { (INT32)scf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_CREATESHORTCUT, args); update_status_text(tmpbuf); } return 0; } #endif log_printf("CreateShortCut: INSTALLER CORRUPTED\n"); break; case 8: if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("Delete: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { HANDLE h; WIN32_FIND_DATA fd; LPTSTR p=buf; _tcscpy(buf,buf2); while (*p) p=CharNext(p); while (p > buf && *p != _T('\\')) p=CharPrev(buf, p); *p=_T('\0'); h=FindFirstFile(buf2,&fd); if (h != INVALID_HANDLE_VALUE) { do { if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { wsprintf(buf2,_T("%s\\%s"),buf,fd.cFileName); log_printf2("Delete: DeleteFile(\"%s\")\n",buf2); { INT32 args[] = { (INT32)buf2 }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_DELETEFILE, args); update_status_text(tmpbuf); } DeleteFile(buf2); } } while (FindNextFile(h,&fd)); FindClose(h); } } else { log_printf("Delete: error parsing parameter\n"); } return 0; } log_printf("Delete: INSTALLER CORRUPTED\n"); break; case 9: if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf,sizeof(buf))) { int whattodo=thisentry->offsets[0]; log_printf3("FindWindow: checking for window class: %s . whattodo=%d\n",buf,whattodo); if (whattodo==2) { if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf2,sizeof(buf2))) { while (FindWindow(buf,NULL)) { int r=noisy ? MessageBox(g_hwnd,buf2,g_caption,MB_ABORTRETRYIGNORE) : IDIGNORE; if (r == IDABORT) { log_printf("FindWindow: user abort\n"); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_ABORTED, args); update_status_text(tmpbuf); } return -2; } if (r == IDIGNORE) { log_printf("FindWindow: user ignore\n"); break; } } } else { log_printf("FindWindow: INSTALLER CORRUPTED\n"); break; } } else if (whattodo==1) { HWND hwnd=FindWindow(buf,NULL); if (hwnd) { log_printf2("FindWindow: closing window (%s) (one-shot)\n",buf); SendMessage(hwnd,WM_CLOSE,0,0); } } else if (whattodo==0) { HWND hwnd; int r=8; while ((hwnd=FindWindow(buf,NULL))) { SendMessage(hwnd,WM_CLOSE,0,0); Sleep(250); if (r--<0) { break; } } if (!hwnd) { log_printf3("FindWindow: closed window (%s) (multi-try). %d\n",buf,r); } else { log_printf2("FindWindow: gave up closing window (%s)\n",buf); } } return 0; } log_printf("FindWindow: INSTALLER CORRUPTED\n"); break; case 10: // MessageBox if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],buf,sizeof(buf))) { if (!process_string(buf2, buf, state_install_directory)) { log_printf3("MessageBox: %d,\"%s\"\n",thisentry->offsets[0],buf2); if (noisy) { DWORD ret=MessageBox(g_hwnd,buf2,g_caption,thisentry->offsets[0]); if ( ret == IDNO || ret == IDCANCEL) { state_return_value=0; } else { state_return_value=1; } } } else { log_printf("MessageBox: error parsing parameter\n"); } return 0; } log_printf("MessageBox: INSTALLER CORRUPTED\n"); break; case 13: //RMDir if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("RMDir: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { log_printf2("RMDir: RemoveDirectory(\"%s\")\n",buf2); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_REMOVEDIR, args); update_status_text(tmpbuf); } RemoveDirectory(buf2); } else { log_printf("RMDir: error parsing parameter\n"); } return 0; } log_printf("RMDir: INSTALLER CORRUPTED\n"); break; case 19: if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("RMDirRecursive: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { SHFILEOPSTRUCT fos; log_printf2("RMDirRecursive: RemoveDirectory(\"%s\")\n",buf2); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_REMOVEDIR, args); update_status_text(tmpbuf); } buf2[_tcslen(buf2)]=0; buf2[_tcslen(buf2)+1]=0; if (GetFileAttributes(buf2)!=0xffffffff) { // Only do SHFileOperation if file exists fos.hwnd = g_hwnd; fos.wFunc = FO_DELETE; fos.pFrom = buf2; fos.pTo = NULL; fos.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION; fos.hNameMappings = NULL; fos.lpszProgressTitle = NULL; SHFileOperation(&fos); } } else { log_printf("RMDirRecursive: error parsing parameter\n"); } return 0; } log_printf("RMDirRecursive: INSTALLER CORRUPTED\n"); break; case 14: // If if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("If: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { int ret=0; log_printf2("If(variables evaluated): (\"%s\")\n",buf2); if (!(ret=evalStr(buf2))) { skip=1; return 0; } } else { log_printf("If: error parsing parameter\n"); } return 0; } log_printf("If: INSTALLER CORRUPTED\n"); break; case 15: //EndIf skip=0; return 0; break; case 16: //RebootBox if (noisy) { GETRESOURCE(buf,JAVAWS_MESSAGE_REBOOT); if (MessageBox(g_hwnd,buf,g_caption,MB_YESNO|MB_ICONWARNING)==IDYES) { if (!ExitWindowsEx(EWX_REBOOT, (DWORD)0)) { GETRESOURCE(buf,JAVAWS_ERROR_EXITWINDOWS); if (noisy) MessageBox(g_hwnd,buf,g_caption,MB_OK); } } } return 0; break; case 17: //Browser if (!noisy) return 0; if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("Browser: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { ShellExecute(g_hwnd, "open", buf2, "-new", state_install_directory, 0); } else { log_printf("Browser: error parsing parameter\n"); } return 0; } log_printf("Browser: INSTALLER CORRUPTED\n"); break; case 18: // AltDirBox { TCHAR name[MAX_PATH]; TCHAR buf3[MAX_PATH]; TCHAR buf4[MAX_PATH]; if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[1],name,sizeof(name)) && !GetStringFromDataBlock(hFile,offset+thisentry->offsets[2],buf3,sizeof(buf3))) { if (!process_string(tmpbuf,buf,state_install_directory) && !process_string(buf4,buf3,state_install_directory) && !process_string(buf2,name,state_install_directory)) { _tcscpy(state_alt_directory,tmpbuf); _tcscpy(state_alt_name, buf2); _tcscpy(state_alt_version,buf4); state_return_value = noisy ? DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIR1),g_hwnd,DirProc2): 1; } return 0; } } break; case 41: if (!GetStringFromDataBlock(hFile,offset+thisentry->offsets[0],buf,sizeof(buf))) { log_printf2("MKDir: \"%s\"\n",buf); if (!process_string(buf2,buf,state_install_directory)) { log_printf2("MKDir: recursive_create_directory(\"%s\")\n",buf2); { INT32 args[] = { (INT32)buf }; GETRESOURCE2(tmpbuf, JAVAWS_STATUS_MAKEDIR, args); update_status_text(tmpbuf); } recursive_create_directory(buf2); } else { log_printf("RMDir: error parsing parameter\n"); } return 0; } log_printf("MKDir: INSTALLER CORRUPTED\n"); break; } installer_corrupted: { GETRESOURCE(tmpbuf, JAVAWS_ERROR_INSTCORRUPT); if (noisy) MessageBox(g_hwnd,tmpbuf,g_caption,MB_OK|MB_ICONSTOP); } return -1; }
static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_DESTROY) { GetDlgItemText(hwndDlg,IDC_DIR,state_install_directory,sizeof(state_install_directory)); if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)) state_docommoninstall=1; else state_docommoninstall=0; #ifdef NSIS_CONFIG_LOG wsprintf(g_log_file,"%s%sinstall.log",state_install_directory,state_install_directory[mini_strlen(state_install_directory)-1]=='\\'?"":"\\"); if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)) log_dolog=1; else log_dolog=0; #endif } if (uMsg == WM_INITDIALOG) { TCHAR str[MAX_PATH]; INT32 args[] = { (INT32)(m_header->name) }; #ifdef NSIS_CONFIG_LOG if (GetAsyncKeyState(VK_SHIFT)&0x8000) ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK1),SW_SHOWNA); #endif if (IsCurrentUserAdministratorOrPowerUser()) { ShowWindow(GetDlgItem(hwndDlg, IDC_CHECK1), SW_SHOWNA); SendDlgItemMessage(hwndDlg, IDC_CHECK1, BM_SETCHECK, BST_CHECKED, 0); } else { ShowWindow(GetDlgItem(hwndDlg, IDC_CHECK1), SW_HIDE); } SetDlgItemText(hwndDlg,IDC_DIR,state_install_directory); SetDlgItemText(hwndDlg,IDC_INTROTEXT,m_header->text); GETRESOURCE2(str, JAVAWS_MESSAGE_SELECTDIR2, args); SetDlgItemText(hwndDlg,IDC_SELDIRTEXT,str); SendMessage(hwndDlg,WM_USER+3,0,0); } if (uMsg == WM_COMMAND) { int id=LOWORD(wParam); if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE) { SendMessage(hwndDlg,WM_USER+3,0,0); } if (id == IDC_BROWSE) { TCHAR name[MAX_PATH]; BROWSEINFO bi={0,}; ITEMIDLIST *idlist; GetDlgItemText(hwndDlg,IDC_DIR,name,MAX_PATH); bi.hwndOwner = hwndDlg; bi.pszDisplayName = name; bi.lpfn=BrowseCallbackProc; bi.lParam=(LPARAM)hwndDlg; bi.lpszTitle = (LPTSTR)malloc(128 * sizeof(TCHAR)); GETRESOURCE(bi.lpszTitle, JAVAWS_MESSAGE_SELECTDIR3); bi.ulFlags = BIF_RETURNONLYFSDIRS; idlist = SHBrowseForFolder( &bi ); if (idlist) { LPTSTR p; SHGetPathFromIDList( idlist, name ); Shell_Free(idlist); p=name+_tcslen(name)-_tcslen(m_header->name); if (p <= name || *(CharPrev(name, p))!=_T('\\') || _tcsicmp(p,m_header->name)) { if ( *(CharPrev(name, &(name[_tcslen(name)]))) != _T('\\') ) _tcscat(name,_T("\\")); _tcscat(name,m_header->name); } SetDlgItemText(hwndDlg,IDC_DIR,name); uMsg = WM_USER+3; } } } if (uMsg == WM_USER+3) { int x; int total=m_section[0].size_kb, available=-1; TCHAR s[MAX_PATH]; DWORD spc,bps,fc,tc; LPTSTR p; GetDlgItemText(hwndDlg,IDC_DIR,s,MAX_PATH); p=s; if (*p == _T('\\') && *(CharNext(p)) == _T('\\')) { if (*(CharPrev(s, &s[_tcslen(s)]))!=_T('\\')) _tcscat(s,_T("\\")); } if (*(p=CharNext(p)) == _T(':')) { p=CharNext(p); *(CharNext(p))=0; } if (GetDiskFreeSpace(s,&spc,&bps,&fc,&tc)) { DWORD r; r=bps*spc*(fc>>10); if (!r) r=(bps*spc*fc)>>10; if (r > 0x7fffffff) r=0x7fffffff; available=(int)r; }
extern "C" int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst , __in LPSTR lpszCmdLine, int nCmdShow) { //----------------------------------------------------------------------------------------------------------------- // VARIABLES // //----------------------------------------------------------------------------------------------------------------- UINT uiRet = ERROR_SUCCESS; HRESULT hr = S_OK; char *szMsiFile = 0; char *szBaseURL = 0; char *szInstallPath = 0; char *szMsiCacheFile = 0; char *szOperation = 0; char *szProductName = 0; char *szMinimumMsi = 0; char *szProperties = 0; char *szInstProperties = 0; char *szTempPath = 0; char *szFilePart = 0; char *szBase = 0; char *szUpdate = 0; char *szRegisteredMsiFolder = 0; char *szMsiDllLocation = 0; char szAppTitle[MAX_STR_CAPTION] = {0}; char szError[MAX_STR_LENGTH] = {0}; char szText[MAX_STR_CAPTION] = {0}; char szBanner[MAX_STR_LENGTH] = {0}; char szAction[MAX_STR_LENGTH] = {0}; char szUserPrompt[MAX_STR_LENGTH] = {0}; char szProductCode[MAX_LENGTH_GUID] = {0}; char szModuleFile[MAX_PATH] = {0}; DWORD dwModuleFileSize = MAX_PATH; DWORD dwMsiFileSize = 0; DWORD dwBaseURLSize = 0; DWORD cchInstallPath = 0; DWORD dwMsiCacheFileSize = 0; DWORD dwOperationSize = 0; DWORD dwProductNameSize = 0; DWORD dwMinimumMsiSize = 0; DWORD dwPropertiesSize = 0; DWORD cchInstProperties = 0; DWORD cchTempPath = 0; DWORD dwLastError = 0; DWORD cchReturn = 0; DWORD dwBaseUpdateSize = 0; DWORD dwUpdateSize = 0; DWORD dwResult = 0; DWORD dwType = 0; DWORD dwProductCodeSize = MAX_LENGTH_GUID; DWORD dwRegisteredMsiFolderSize = 0; DWORD dwMsiDllLocationSize = 0; ULONG ulMsiMinVer = 0; char *szStopScan = NULL; bool fDelayRebootReq = false; bool fPatch = false; bool fQFE = false; bool fOSSupported = false; emEnum emExecMode = emPreset; HKEY hInstallerKey = 0; HMODULE hMsi = 0; PFnMsiSetInternalUI pfnMsiSetInternalUI = 0; PFnMsiInstallProduct pfnMsiInstallProduct = 0; PFnMsiApplyPatch pfnMsiApplyPatch = 0; PFnMsiReinstallProduct pfnMsiReinstallProduct = 0; PFnMsiQueryProductState pfnMsiQueryProductState = 0; PFnMsiOpenDatabase pfnMsiOpenDatabase = 0; PFnMsiDatabaseOpenView pfnMsiDatabaseOpenView = 0; PFnMsiViewExecute pfnMsiViewExecute = 0; PFnMsiViewFetch pfnMsiViewFetch = 0; PFnMsiRecordGetString pfnMsiRecordGetString = 0; PFnMsiCloseHandle pfnMsiCloseHandle = 0; MSIHANDLE hDatabase = 0; MSIHANDLE hView = 0; MSIHANDLE hRec = 0; INSTALLSTATE isProduct = INSTALLSTATE_UNKNOWN; const char * szAdminImagePath = 0; //----------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------- // create our UI object CDownloadUI DownloadUI; // Load our AppTitle (caption) WIN::LoadString(hInst, IDS_APP_TITLE, szAppTitle, sizeof(szAppTitle)/sizeof(char)); // Obtain path we are running from if (0 == WIN::GetModuleFileName(hInst, szModuleFile, dwModuleFileSize)) { // No UI displayed. Silent failure. uiRet = GetLastError(); goto CleanUp; } DebugMsg("[Info] we are running from --> %s\n", szModuleFile); // Figure out what we want to do emExecMode = GetExecutionMode (lpszCmdLine); if (emVerify == emExecMode) { // // We don't want any UI to be displayed in this case. The return value // from the exe is the result of the verification. Therefore, this // should be done before initializing the UI. // uiRet = VerifyFileSignature (szModuleFile, lpszCmdLine); if (ERROR_BAD_ARGUMENTS != uiRet) goto CleanUp; } if (ERROR_BAD_ARGUMENTS == uiRet || emHelp == emExecMode) { DisplayUsage(hInst, NULL, szAppTitle); goto CleanUp; } // // NOTE: // Delay handling admin. installs until we have determined if we are // patching an existing install or if we are doing a default install. // // initialize our UI object with desktop as parent DownloadUI.Initialize(hInst, /* hwndParent = */ 0, szAppTitle); // Check if we are installing on an OS that supports Windows Installer 3.0 fOSSupported = IsOSSupported(); if(!fOSSupported) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_OS_NOT_SUPPORTED); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } HANDLE hMutex = 0; // only run one instance at a time if (AlreadyInProgress(hMutex)) { // silently return - correct return code ? uiRet = ERROR_INSTALL_ALREADY_RUNNING; goto CleanUp; } // determine operation, default (if not present) is INSTALL if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_OPERATION, &szOperation, dwOperationSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } if (ERROR_SUCCESS != uiRet) { // set operation to default which is install if (szOperation) delete [] szOperation; szOperation = new char[lstrlen(szDefaultOperation) + 1]; if (!szOperation) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } if (FAILED(StringCchCopy(szOperation, lstrlen(szDefaultOperation) + 1, szDefaultOperation))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } // obtain name of product if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_PRODUCTNAME, &szProductName, dwProductNameSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } if (ERROR_SUCCESS != uiRet) { // use default if (szProductName) delete [] szProductName; szProductName = new char[MAX_STR_CAPTION]; if (!szProductName) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } WIN::LoadString(hInst, IDS_DEFAULT_PRODUCT, szProductName, MAX_STR_CAPTION); } // set banner text WIN::LoadString(hInst, IDS_BANNER_TEXT, szText, MAX_STR_CAPTION); StringCchPrintf(szBanner, sizeof(szBanner), szText, szProductName); if (irmCancel == DownloadUI.SetBannerText(szBanner)) { ReportUserCancelled(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } // Determine if this is a patch or a normal install. if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_DATABASE, &szMsiFile, dwMsiFileSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS != uiRet) { // look for patch if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_PATCH, &szMsiFile, dwMsiFileSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS != uiRet) { PostResourceNotFoundError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, ISETUPPROPNAME_DATABASE); goto CleanUp; } fPatch = true; } // // If we are here, this is either an admin. install or a default install. // File signature verification, help and other invalid parameters have // already been taken care of above. // if (emAdminInstall == emExecMode) { uiRet = GetAdminInstallInfo (fPatch, lpszCmdLine, &szAdminImagePath); if (ERROR_BAD_ARGUMENTS == uiRet) { DisplayUsage(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } } // // At this point, the validation of the commandline arguments is complete // and we have all the information we need. // // obtain minimum required MSI version if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_MINIMUM_MSI, &szMinimumMsi, dwMinimumMsiSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS != uiRet) { PostResourceNotFoundError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, ISETUPPROPNAME_MINIMUM_MSI); goto CleanUp; } // make sure required Msi version is a valid value -- must be >= 150 ulMsiMinVer = strtoul(szMinimumMsi, &szStopScan, 10); if (!szStopScan || (szStopScan == szMinimumMsi) || (*szStopScan != 0) || ulMsiMinVer < MINIMUM_SUPPORTED_MSI_VERSION) { // invalid minimum version string PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_VER_STR, szMinimumMsi, MINIMUM_SUPPORTED_MSI_VERSION); uiRet = ERROR_INVALID_PARAMETER; goto CleanUp; } DebugMsg("[Resource] Minimum Msi Value = %d\n", ulMsiMinVer); // compare minimum required MSI version to that which is on the machine if (IsMsiUpgradeNecessary(ulMsiMinVer)) { DebugMsg("[Info] Upgrade of Windows Installer is requested\n"); // make sure this is admin -- must have admin priviledges to upgrade Windows Installer if (!IsAdmin()) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_REQUIRES_ADMIN_PRIV); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } // Ask the user if they want to upgrade the installer WIN::LoadString(hInst, IDS_ALLOW_MSI_UPDATE, szUserPrompt, MAX_STR_LENGTH); if (IDYES != WIN::MessageBox(DownloadUI.GetCurrentWindow(), szUserPrompt, szAppTitle, MB_YESNO|MB_ICONQUESTION)) { // user decided to cancel ReportUserCancelled(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_UPDATE, &szUpdate, dwUpdateSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS != uiRet) { PostResourceNotFoundError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, ISETUPPROPNAME_UPDATE); goto CleanUp; } // determine if we need to download the Windows Installer update package from the web -- based on presence of UPDATELOCATION property if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_UPDATELOCATION, &szBase, dwBaseUpdateSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS == uiRet) { // presence of UPDATELOCATION property indicates assumption of URL source if (ERROR_SUCCESS != (uiRet = DownloadAndUpgradeMsi(hInst, &DownloadUI, szAppTitle, szBase, szUpdate, szModuleFile, ulMsiMinVer))) { if (ERROR_SUCCESS_REBOOT_REQUIRED == uiRet) { // successful, but must reboot at end fDelayRebootReq = true; } else goto CleanUp; } } else { // lack of UPDATELOCATION property indicates assumption of Media source if (ERROR_SUCCESS != (uiRet = UpgradeMsi(hInst, &DownloadUI, szAppTitle, szModuleFile, szUpdate, ulMsiMinVer))) { if (ERROR_SUCCESS_REBOOT_REQUIRED == uiRet) { // successful, but must reboot at end fDelayRebootReq = true; } else goto CleanUp; } } } DebugMsg("[Info] Windows Installer has been upgraded, or was already correct version\n"); // perform some extra authoring validation if (fPatch && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szMinPatchOperation, -1) && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szMajPatchOperation, -1) && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szDefaultOperation, -1)) { // wrong operation DebugMsg("[Error] Operation %s is not valid for a patch\n", szOperation); PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_OPERATION, szOperation); uiRet = ERROR_INVALID_PARAMETER; goto CleanUp; } else if (!fPatch && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szInstallOperation, -1) && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szInstallUpdOperation, -1) && CSTR_EQUAL != CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szDefaultOperation, -1)) { // wrong operation DebugMsg("[Error] Operation %s is not valid for a package\n", szOperation); PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_OPERATION, szOperation); uiRet = ERROR_INVALID_PARAMETER; goto CleanUp; } // by now we either have a MSI or a MSP if (CSTR_EQUAL == CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szMinPatchOperation, -1) || CSTR_EQUAL == CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szInstallUpdOperation, -1) || (fPatch && CSTR_EQUAL == CompareString(lcidLOCALE_INVARIANT, NORM_IGNORECASE, szOperation, -1, szDefaultOperation, -1))) fQFE = true; // obtain base URL if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_BASEURL, &szBaseURL, dwBaseURLSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); goto CleanUp; } else if (ERROR_SUCCESS == uiRet) { // presence of BASEURL property indicates assumption of URL source . . . // generate the path to the installation package == baseURL + msiFile // note: msiFile is a relative path cchTempPath = lstrlen(szBaseURL) + lstrlen(szMsiFile) + 2; // 1 for slash, 1 for null szTempPath = new char[cchTempPath ]; if (!szTempPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } if (FAILED(StringCchCopy(szTempPath, cchTempPath, szBaseURL))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } // check for trailing slash on szBaseURL char *pch = szBaseURL + lstrlen(szBaseURL) + 1; // put at null terminator pch = CharPrev(szBaseURL, pch); if (*pch != '/') { if (FAILED(StringCchCat(szTempPath, cchTempPath, szUrlPathSep))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } if (FAILED(StringCchCat(szTempPath, cchTempPath, szMsiFile))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } // canocialize the URL path cchInstallPath = cchTempPath*2; szInstallPath = new char[cchInstallPath]; if (!szInstallPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } dwLastError = 0; // success if (!InternetCanonicalizeUrl(szTempPath, szInstallPath, &cchInstallPath, 0)) { dwLastError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwLastError) { // try again delete [] szInstallPath; szInstallPath = new char[cchInstallPath]; if (!szInstallPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } dwLastError = 0; // reset to success for 2nd attempt if (!InternetCanonicalizeUrl(szTempPath, szInstallPath, &cchInstallPath, 0)) dwLastError = GetLastError(); } } if (0 != dwLastError) { // error -- invalid path/Url PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); uiRet = dwLastError; goto CleanUp; } // set action text for download WIN::LoadString(hInst, IDS_DOWNLOADING_PACKAGE, szText, MAX_STR_CAPTION); StringCchPrintf(szAction, sizeof(szAction), szText, szMsiFile); if (irmCancel == DownloadUI.SetActionText(szAction)) { ReportUserCancelled(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } // download the msi file so we can attempt a trust check -- must be local for WinVerifyTrust DebugMsg("[Info] Downloading msi file %s for WinVerifyTrust check\n", szInstallPath); szMsiCacheFile = new char[MAX_PATH]; dwMsiCacheFileSize = MAX_PATH; if (!szMsiCacheFile) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } hr = WIN::URLDownloadToCacheFile(NULL, szInstallPath, szMsiCacheFile, dwMsiCacheFileSize, 0, /* IBindStatusCallback = */ &CDownloadBindStatusCallback(&DownloadUI)); if (DownloadUI.HasUserCanceled()) { ReportUserCancelled(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } if (FAILED(hr)) { // error during download -- probably because file not found (or lost connection) PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_NOMSI, szInstallPath); uiRet = ERROR_FILE_NOT_FOUND; goto CleanUp; } DebugMsg("[Info] Msi file was cached to %s\n", szMsiCacheFile); // set action text for trust verification WIN::LoadString(hInst, IDS_VALIDATING_SIGNATURE, szText, MAX_STR_CAPTION); StringCchPrintf(szAction, sizeof(szAction), szText, szMsiFile); if (irmCancel == DownloadUI.SetActionText(szAction)) { ReportUserCancelled(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } // perform trust check itvEnum itv = IsPackageTrusted(szModuleFile, szMsiCacheFile, DownloadUI.GetCurrentWindow()); if (itvWintrustNotOnMachine == itv) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_NO_WINTRUST); uiRet = ERROR_CALL_NOT_IMPLEMENTED; goto CleanUp; } else if (itvUnTrusted == itv) { PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_UNTRUSTED, szInstallPath); uiRet = HRESULT_CODE(TRUST_E_SUBJECT_NOT_TRUSTED); goto CleanUp; } } else { // lack of BASEURL property indicates assumption of Media source // generate the path to the Msi file = szModuleFile + msiFile // note: msiFile is a relative path cchTempPath = lstrlen(szModuleFile) + lstrlen(szMsiFile) + 2; // 1 for null terminator, 1 for back slash szTempPath = new char[cchTempPath]; if (!szTempPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } // find 'setup.exe' in the path so we can remove it if (0 == GetFullPathName(szModuleFile, cchTempPath, szTempPath, &szFilePart)) { uiRet = GetLastError(); PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); goto CleanUp; } if (szFilePart) *szFilePart = '\0'; if (FAILED(StringCchCat(szTempPath, cchTempPath, szMsiFile))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } cchInstallPath = 2*cchTempPath; szInstallPath = new char[cchInstallPath]; if (!szInstallPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } // normalize the path cchReturn = GetFullPathName(szTempPath, cchInstallPath, szInstallPath, &szFilePart); if (cchReturn > cchInstallPath) { // try again, with larger buffer delete [] szInstallPath; cchInstallPath = cchReturn; szInstallPath = new char[cchInstallPath]; if (!szInstallPath) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } cchReturn = GetFullPathName(szTempPath, cchInstallPath, szInstallPath, &szFilePart); } if (0 == cchReturn) { // error -- invalid path PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); uiRet = dwLastError; goto CleanUp; } // no download is necessary -- but we can check for the file's existence DWORD dwFileAttrib = GetFileAttributes(szInstallPath); if (0xFFFFFFFF == dwFileAttrib) { // package is missing PostFormattedError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_NOMSI, szInstallPath); uiRet = ERROR_FILE_NOT_FOUND; goto CleanUp; } } // // good to go -- terminate our UI and let the Windows Installer take over // // retrieve the optional command line PROPERTY = VALUE strings if available if (ERROR_OUTOFMEMORY == (uiRet = SetupLoadResourceString(hInst, ISETUPPROPNAME_PROPERTIES, &szProperties, dwPropertiesSize))) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } else if (ERROR_SUCCESS != uiRet) { // PROPERTY=VALUE pairs not specified if (szProperties) delete [] szProperties; szProperties = NULL; } DownloadUI.Terminate(); // // perform install // hMsi = LoadLibrary(MSI_DLL); if (hMsi) { pfnMsiSetInternalUI = (PFnMsiSetInternalUI)GetProcAddress(hMsi, MSIAPI_MsiSetInternalUI); pfnMsiInstallProduct = (PFnMsiInstallProduct)GetProcAddress(hMsi, MSIAPI_MsiInstallProduct); pfnMsiApplyPatch = (PFnMsiApplyPatch)GetProcAddress(hMsi, MSIAPI_MsiApplyPatch); pfnMsiReinstallProduct = (PFnMsiReinstallProduct)GetProcAddress(hMsi, MSIAPI_MsiReinstallProduct); pfnMsiQueryProductState = (PFnMsiQueryProductState)GetProcAddress(hMsi, MSIAPI_MsiQueryProductState); pfnMsiOpenDatabase = (PFnMsiOpenDatabase)GetProcAddress(hMsi, MSIAPI_MsiOpenDatabase); pfnMsiDatabaseOpenView = (PFnMsiDatabaseOpenView)GetProcAddress(hMsi, MSIAPI_MsiDatabaseOpenView); pfnMsiViewExecute = (PFnMsiViewExecute)GetProcAddress(hMsi, MSIAPI_MsiViewExecute); pfnMsiViewFetch = (PFnMsiViewFetch)GetProcAddress(hMsi, MSIAPI_MsiViewFetch); pfnMsiRecordGetString = (PFnMsiRecordGetString)GetProcAddress(hMsi, MSIAPI_MsiRecordGetString); pfnMsiCloseHandle = (PFnMsiCloseHandle)GetProcAddress(hMsi, MSIAPI_MsiCloseHandle); } if (!hMsi || !pfnMsiSetInternalUI || !pfnMsiInstallProduct || !pfnMsiApplyPatch || !pfnMsiReinstallProduct || !pfnMsiQueryProductState || !pfnMsiDatabaseOpenView || !pfnMsiViewExecute || !pfnMsiViewFetch || !pfnMsiRecordGetString || !pfnMsiCloseHandle) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_FAILED_TO_UPGRADE_MSI); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } DebugMsg("[Info] Setting Internal UI level to FULL...\n"); pfnMsiSetInternalUI(INSTALLUILEVEL_FULL, 0); if (!fPatch) { // performing install or reinstall/recache DebugMsg("[Info] Calling MsiInstallProduct with szInstallPath = %s", szInstallPath); DebugMsg(" and szCommandLine = %s\n", szProperties ? szProperties : "{null}"); // default operation for a package is INSTALL if (fQFE) { // check to see if this product is already installed if (ERROR_SUCCESS == pfnMsiOpenDatabase(szMsiCacheFile ? szMsiCacheFile : szInstallPath, MSIDBOPEN_READONLY, &hDatabase) && ERROR_SUCCESS == pfnMsiDatabaseOpenView(hDatabase, sqlProductCode, &hView) && ERROR_SUCCESS == pfnMsiViewExecute(hView, 0) && ERROR_SUCCESS == pfnMsiViewFetch(hView, &hRec) && ERROR_SUCCESS == pfnMsiRecordGetString(hRec, 1, szProductCode, &dwProductCodeSize)) { isProduct = pfnMsiQueryProductState(szProductCode); DebugMsg("[Info] MsiQueryProductState returned %d\n", isProduct); if (INSTALLSTATE_ADVERTISED != isProduct && INSTALLSTATE_DEFAULT != isProduct) { // product is unknown, so this will be a first time install DebugMsg("[Info] The product code '%s' is unknown. Will use first time install logic...\n", szProductCode); fQFE = false; } else { // product is known, use QFE syntax DebugMsg("[Info] The product code '%s' is known. Will use QFE recache and reinstall upgrade logic...\n", szProductCode); } } else { // some failure occurred when processing the product code, so treat as non-QFE DebugMsg("[Info] Unable to process product code. Will treat as first time install...\n"); fQFE = false; } if (hDatabase) pfnMsiCloseHandle(hDatabase); if (hView) pfnMsiCloseHandle(hView); if (hRec) pfnMsiCloseHandle(hRec); } // // Set up the properties to be passed into MSIInstallProduct // if (fQFE && !szProperties) cchInstProperties = lstrlen (szDefaultInstallUpdCommandLine); else if (szProperties) cchInstProperties = lstrlen (szProperties); if (emAdminInstall == emExecMode) cchInstProperties += lstrlen (szAdminInstallProperty); szInstProperties = new char[cchInstProperties + 1]; if (! szInstProperties) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } if (fQFE && !szProperties) { if (FAILED(StringCchCopy(szInstProperties, cchInstProperties + 1, szDefaultInstallUpdCommandLine))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } else if (szProperties) { if (FAILED(StringCchCopy(szInstProperties, cchInstProperties + 1, szProperties))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } else szInstProperties[0] = '\0'; if (emAdminInstall == emExecMode) { if (FAILED(StringCchCat(szInstProperties, cchInstProperties + 1, szAdminInstallProperty))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } uiRet = pfnMsiInstallProduct(szInstallPath, szInstProperties); if (ERROR_SUCCESS != uiRet) { // attempt to display an error message stored in msi.dll PostMsiError(hInst, hMsi, DownloadUI.GetCurrentWindow(), szAppTitle, uiRet); } DebugMsg("[Info] MsiInstallProduct returned %d\n", uiRet); } else { // default Operation for a patch is MINPATCH // if szProperties is NULL, use our default value for QFE patches if (!szProperties && fQFE) { DebugMsg("[Info] Patch is a MINPATCH (small or minor update patch) so using default command line '%s'\n", szDefaultMinPatchCommandLine); szProperties = new char[lstrlen(szDefaultMinPatchCommandLine) + 1]; if (!szProperties) { ReportErrorOutOfMemory(hInst, DownloadUI.GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } if (FAILED(StringCchCopy(szProperties, lstrlen(szDefaultMinPatchCommandLine) + 1, szDefaultMinPatchCommandLine))) { PostError(hInst, DownloadUI.GetCurrentWindow(), szAppTitle, IDS_INTERNAL_ERROR); uiRet = ERROR_INSTALL_FAILURE; goto CleanUp; } } if (emAdminInstall == emExecMode) { // performing a patch DebugMsg("[Info] Calling MsiApplyPatch with szPatchPackage = %s", szMsiCacheFile); DebugMsg(" and szInstallPackage = %s and eInstallType = INSTALLTYPE_NETWORK_IMAGE", szAdminImagePath); DebugMsg(" and szCommandLine = %s\n", szProperties ? szProperties : "{null}"); uiRet = pfnMsiApplyPatch(szMsiCacheFile, szAdminImagePath, INSTALLTYPE_NETWORK_IMAGE, szProperties); } else { // performing a patch DebugMsg("[Info] Calling MsiApplyPatch with szPatchPackage = %s", szInstallPath); DebugMsg(" and szInstallPackage = {null} and eInstallType = INSTALLTYPE_DEFAULT"); DebugMsg(" and szCommandLine = %s\n", szProperties ? szProperties : "{null}"); uiRet = pfnMsiApplyPatch(szInstallPath, NULL, INSTALLTYPE_DEFAULT, szProperties); } if (ERROR_SUCCESS != uiRet) { // attempt to display an error message stored in msi.dll PostMsiError(hInst, hMsi, DownloadUI.GetCurrentWindow(), szAppTitle, uiRet); } DebugMsg("[Info] MsiApplyPatch returned %d\n", uiRet); } CleanUp: if (szMsiFile) delete [] szMsiFile; if (szBaseURL) delete [] szBaseURL; if (szInstallPath) delete [] szInstallPath; if (szMsiCacheFile) { WIN::DeleteUrlCacheEntry(szMsiCacheFile); delete [] szMsiCacheFile; } if (szProductName) delete [] szProductName; if (szMinimumMsi) delete [] szMinimumMsi; if (szProperties) delete [] szProperties; if (szTempPath) delete [] szTempPath; if (szBase) delete [] szBase; if (szUpdate) delete [] szUpdate; if (szRegisteredMsiFolder) delete [] szRegisteredMsiFolder; if (szMsiDllLocation) delete [] szMsiDllLocation; if (szOperation) delete [] szOperation; if(hMutex) CloseHandle(hMutex); if (hMsi) FreeLibrary(hMsi); DebugMsg("[Info] Setup exit code is %d\n", uiRet); if (fDelayRebootReq) { // need to reboot machine for updating Windows Installer WIN::LoadString(hInst, IDS_REBOOT_REQUIRED, szAction, MAX_STR_LENGTH); if (IDYES == MessageBox(NULL, szAction, szAppTitle, MB_YESNO|MB_ICONQUESTION)) { // must first aquire system shutdown privileges on NT/Win2K AcquireShutdownPrivilege(); // initiate system shutdown for reboot WIN::ExitWindowsEx(EWX_REBOOT, PCLEANUI | SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION); } } return uiRet; }
__declspec(dllexport) void download (HWND parent, int string_size, char *variables, stack_t **stacktop) { char buf[1024]; char url[1024]; char filename[1024]; static char proxy[1024]; BOOL bSuccess=FALSE; int timeout_ms=30000; int getieproxy=1; int manualproxy=0; char *error=NULL; static char szDownloading[1024];//= "Downloading %s"; static char szConnecting[1024];//= "Connecting ..."; static char szSecond[1024];//= "second"; static char szMinute[1024];//= "minute"; static char szHour[1024];//= "hour"; static char szPlural[1024];//= "s"; static char szProgress[1024];//= "%dkB (%d%%) of %dkB @ %d.%01dkB/s"; static char szRemaining[1024];//= " (%d %s%s remaining)"; EXDLL_INIT(); popstring(url); if (!lstrcmpi(url, "/TRANSLATE")) { popstring(szDownloading); popstring(szConnecting); popstring(szSecond); popstring(szMinute); popstring(szHour); popstring(szPlural); popstring(szProgress); popstring(szRemaining); popstring(url); } else { lstrcpy(szDownloading, "Downloading %s"); lstrcpy(szConnecting, "Connecting ..."); lstrcpy(szSecond, "second"); lstrcpy(szMinute, "minute"); lstrcpy(szHour, "hour"); lstrcpy(szPlural, "s"); lstrcpy(szProgress, "%dkB (%d%%) of %dkB @ %d.%01dkB/s"); lstrcpy(szRemaining, " (%d %s%s remaining)"); } lstrcpyn(buf, url, 10); if (!lstrcmpi(buf, "/TIMEOUT=")) { timeout_ms=my_atoi(url+9); popstring(url); } if (!lstrcmpi(url, "/PROXY")) { getieproxy=0; manualproxy=1; popstring(proxy); popstring(url); } if (!lstrcmpi(url, "/NOIEPROXY")) { getieproxy=0; popstring(url); } popstring(filename); HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL); if (hFile == INVALID_HANDLE_VALUE) { wsprintf(buf, "Unable to open %s", filename); error = buf; } else { if (parent) { uMsgCreate = RegisterWindowMessage("nsisdl create"); lpWndProcOld = (void *)SetWindowLong(parent,GWL_WNDPROC,(long)ParentWndProc); SendMessage(parent, uMsgCreate, TRUE, (LPARAM) parent); // set initial text char *p = filename; while (*p) p++; while (*p != '\\' && p != filename) p = CharPrev(filename, p); wsprintf(buf, szDownloading, p != filename ? p + 1 : p); SetDlgItemText(childwnd, 1006, buf); SetWindowText(g_hwndStatic, szConnecting); } { WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); JNL_HTTPGet *get = 0; static char main_buf[8192]; char *buf=main_buf; char *p=NULL; HKEY hKey; if (getieproxy && RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) { DWORD l = 4; DWORD t; DWORD v; if (RegQueryValueEx(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD && v) { l=8192; if (RegQueryValueEx(hKey,"ProxyServer",NULL,&t,(unsigned char *)buf,&l ) == ERROR_SUCCESS && t == REG_SZ) { p=strstr(buf,"http="); if (!p) p=buf; else { p+=5; } char *tp=strstr(p,";"); if (tp) *tp=0; char *p2=strstr(p,"="); if (p2) p=0; // we found the wrong proxy } } buf[8192-1]=0; RegCloseKey(hKey); } if (manualproxy == 1) { p = proxy; } DWORD start_time=GetTickCount(); get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL); int st; int has_printed_headers = 0; int cl; int len; int sofar = 0; DWORD last_recv_time=start_time; get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)"); get->addheader ("Accept: */*"); get->connect (url); while (1) { if (g_cancelled) error = "cancel"; if (error) { if (parent) { SendMessage(parent, uMsgCreate, FALSE, (LPARAM) parent); SetWindowLong(parent, GWL_WNDPROC, (long)lpWndProcOld); } break; } Sleep(25); st = get->run (); if (st == -1) { lstrcpyn(url, get->geterrorstr(), sizeof(url)); error = url; } else if (st == 1) { if (sofar < cl) error="download incomplete"; else { bSuccess=TRUE; error = "success"; } } else { if (get->get_status () == 0) { // progressFunc ("Connecting ...", 0); if (last_recv_time+timeout_ms < GetTickCount()) error = "Timed out on connecting."; } else if (get->get_status () == 1) { progress_callback("Reading headers", 0); if (last_recv_time+timeout_ms < GetTickCount()) error = "Timed out on getting headers."; } else if (get->get_status () == 2) { if (! has_printed_headers) { has_printed_headers = 1; last_recv_time=GetTickCount(); cl = get->content_length (); if (cl == 0) error = "Server did not specify content length."; else if (g_hwndProgressBar) { SendMessage(g_hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 30000)); g_file_size = cl; } } while ((len = get->bytes_available ()) > 0) { if (len > 8192) len = 8192; len = get->get_bytes (buf, len); if (len > 0) { last_recv_time=GetTickCount(); DWORD dw; WriteFile(hFile,buf,len,&dw,NULL); sofar += len; int time_sofar=(GetTickCount()-start_time)/1000; int bps=sofar/(time_sofar?time_sofar:1); int remain=MulDiv(time_sofar,cl,sofar) - time_sofar; char *rtext=szSecond; if (remain >= 60) { remain/=60; rtext=szMinute; if (remain >= 60) { remain/=60; rtext=szHour; } } wsprintf (buf, szProgress, sofar/1024, MulDiv(100,sofar,cl), cl/1024, bps/1024,((bps*10)/1024)%10 ); if (remain) wsprintf(buf+lstrlen(buf),szRemaining, remain, rtext, remain==1?"":szPlural ); progress_callback(buf, sofar); } else { if (sofar < cl) error = "Server aborted."; } } if (GetTickCount() > last_recv_time+timeout_ms) error = "Downloading timed out."; } else { error = "Bad response status."; } } } // Clean up the connection then release winsock if (get) delete get; WSACleanup(); } CloseHandle(hFile); } if (g_cancelled || !bSuccess) { DeleteFile(filename); } pushstring(error); }
UINT DownloadAndUpgradeMsi(HINSTANCE hInst, CDownloadUI *piDownloadUI, LPCSTR szAppTitle, LPCSTR szUpdateLocation, LPCSTR szUpdate, LPCSTR szModuleFile, ULONG ulMinVer) { char *szTempPath = 0; char *szUpdatePath = 0; char *szUpdateCacheFile = 0; const char *pch = 0; DWORD cchTempPath = 0; DWORD cchUpdatePath = 0; DWORD cchUpdateCacheFile = 0; DWORD dwLastError = 0; UINT uiRet = 0; HRESULT hr = 0; DWORD Status = ERROR_SUCCESS; char szDebugOutput[MAX_STR_LENGTH] = {0}; char szText[MAX_STR_CAPTION] = {0}; // generate the path to the update == UPDATELOCATION + szUpdate // note: szUpdate is a relative path cchTempPath = lstrlen(szUpdateLocation) + lstrlen(szUpdate) + 2; // 1 for slash, 1 for null szTempPath = new char[cchTempPath]; if (!szTempPath) { ReportErrorOutOfMemory(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } memset((void*)szTempPath, 0x0, cchTempPath*sizeof(char)); hr = StringCchCopy(szTempPath, cchTempPath, szUpdateLocation); if (FAILED(hr)) { uiRet = HRESULT_CODE(hr); PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); goto CleanUp; } // check for trailing slash on szUpdateLocation pch = szUpdateLocation + lstrlen(szUpdateLocation) + 1; // put at null terminator pch = CharPrev(szUpdateLocation, pch); if (*pch != '/') { hr = StringCchCat(szTempPath, cchTempPath, szUrlPathSep); if (FAILED(hr)) { uiRet = HRESULT_CODE(hr); PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); goto CleanUp; } } hr = StringCchCat(szTempPath, cchTempPath, szUpdate); if (FAILED(hr)) { uiRet = HRESULT_CODE(hr); PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); goto CleanUp; } // canonicalize the URL path cchUpdatePath = cchTempPath*2; szUpdatePath = new char[cchUpdatePath]; if (!szUpdatePath) { ReportErrorOutOfMemory(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } if (!InternetCanonicalizeUrl(szTempPath, szUpdatePath, &cchUpdatePath, 0)) { dwLastError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwLastError) { // try again delete [] szUpdatePath; szUpdatePath = new char[cchUpdatePath]; if (!szUpdatePath) { ReportErrorOutOfMemory(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } dwLastError = 0; // reset to success for 2nd attempt if (!InternetCanonicalizeUrl(szTempPath, szUpdatePath, &cchUpdatePath, 0)) dwLastError = GetLastError(); } } if (0 != dwLastError) { // error -- invalid path/Url PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_INVALID_PATH, szTempPath); uiRet = dwLastError; goto CleanUp; } DebugMsg("[Info] Downloading update package from --> %s\n", szUpdatePath); // set action text for download WIN::LoadString(hInst, IDS_DOWNLOADING_UPDATE, szText, MAX_STR_CAPTION); if (irmCancel == piDownloadUI->SetActionText(szText)) { ReportUserCancelled(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } // download the Update file so we can run it -- must be local to execute szUpdateCacheFile = new char[MAX_PATH]; cchUpdateCacheFile = MAX_PATH; if (!szUpdateCacheFile) { ReportErrorOutOfMemory(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_OUTOFMEMORY; goto CleanUp; } hr = WIN::URLDownloadToCacheFile(NULL, szUpdatePath, szUpdateCacheFile, cchUpdateCacheFile, 0, /* IBindStatusCallback = */ &CDownloadBindStatusCallback(piDownloadUI)); if (piDownloadUI->HasUserCanceled()) { ReportUserCancelled(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle); uiRet = ERROR_INSTALL_USEREXIT; goto CleanUp; } if (FAILED(hr)) { // error during download -- probably because file not found (or lost connection) PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_NOUPDATE, szUpdatePath); uiRet = ERROR_FILE_NOT_FOUND; goto CleanUp; } // // Perform trust check on MSI. Note, this must be done in a separate process. // This is because MSI 2.0 and higher register sip callbacks for verifying // digital signatures on msi files. At this point, it is quite likely that // the SIP callbacks have not been registered. So we don't want to load // wintrust.dll into this process's image yet, otherwise it will remain unaware // of the sip callbacks registered by WindowsInstaller-KB884016-x86.exe and will // fail later when it tries to verify the signature on the msi file downloaded // from the web. // Status = ExecuteVerifyUpdate(szModuleFile, szUpdateCacheFile); if (TRUST_E_PROVIDER_UNKNOWN == Status) { PostError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_NO_WINTRUST); uiRet = ERROR_CALL_NOT_IMPLEMENTED; goto CleanUp; } else if (ERROR_SUCCESS != Status) { PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_UNTRUSTED, szUpdateCacheFile); uiRet = HRESULT_CODE(TRUST_E_SUBJECT_NOT_TRUSTED); goto CleanUp; } // continue other validations uiRet = ValidateUpdate(hInst, piDownloadUI, szAppTitle, szUpdateCacheFile, szModuleFile, ulMinVer); CleanUp: if (szTempPath) delete [] szTempPath; if (szUpdatePath) delete [] szUpdatePath; if (szUpdateCacheFile) { WIN::DeleteUrlCacheEntry(szUpdateCacheFile); delete [] szUpdateCacheFile; } return uiRet; }
int ui_doinstall(HANDLE hFile,int offset,header *head, section *sec, entry *ent, uninstall_header *uhead) { TCHAR tmpbuf[MAX_PATH]; int ret = 3; m_hFile=hFile; m_offset=offset; m_section=sec; m_entry=ent; m_header=head; if (!uhead) { if (noisy) { noisy=!(head->silent_install); } else { head->silent_install = !noisy; } /* Setup localized strings */ if ((g_strings = getStrings(NULL)) == NULL) { GETRESOURCE(tmpbuf, JAVAWS_ERROR_STRINGTABLE); if (noisy) MessageBox(NULL,tmpbuf,g_caption,MB_OK|MB_ICONWARNING); } _tcscpy(tmpbuf, m_header->name); process_string(m_header->name, tmpbuf, NULL); _tcscpy(tmpbuf, m_header->licensetext); process_string(m_header->licensetext, tmpbuf, NULL); _tcscpy(tmpbuf, m_header->componenttext); process_string(m_header->componenttext, tmpbuf, NULL); _tcscpy(tmpbuf, m_header->text); process_string(m_header->text, tmpbuf, NULL); } #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT m_uninstheader=uhead; if (uhead) { INT32 args[] = { (INT32)m_uninstheader->name }; g_strings = getStrings(NULL); _tcscpy(tmpbuf, m_uninstheader->uninstalltext); process_string(m_uninstheader->uninstalltext, tmpbuf, NULL); GETRESOURCE2(tmpbuf, JAVAWS_MESSAGE_UNINSTALL, args); wsprintf(g_caption,tmpbuf); return DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST),GetDesktopWindow(),DialogProcUninstall); } else #endif { TCHAR buf[MAX_PATH]; int st=0; state_install_directory[0]=0; if (head->install_reg_key[0]) { HKEY hKey; if ( RegOpenKeyEx((HKEY)head->install_reg_rootkey,head->install_reg_key,0,KEY_READ,&hKey) == ERROR_SUCCESS) { int l = sizeof(buf); int t=REG_SZ; if (RegQueryValueEx(hKey,head->install_reg_value,NULL,&t,buf,&l ) == ERROR_SUCCESS && t == REG_SZ && buf[0]) { LPTSTR e; LPTSTR p=buf; while (*p && *p != _T('\"')) p=CharNext(p); if (*p) { LPTSTR p2; p=CharNext(p); p2 = p; while (*p2 && *p2 != _T('\"')) p2=CharNext(p2); if (*p2) { *p2=0; } else p=buf; } else p=buf; // p is the path now, check for .exe extension e=p; while (*e) e=CharNext(e); while (e>p && *e != _T('.') && *e != _T('\\')) e=CharPrev(p, e); if (*e ==_T('.')) { if ((e[1] == _T('e') || e[1]==_T('E')) && (e[2] == _T('x') || e[2]==_T('X')) && (e[3] == _T('e') || e[3]==_T('E'))) // check extension { DWORD d; e[4]=0; d=GetFileAttributes(p); // get the file attributes if (d == 0xFFFFFFFFF || !(d&FILE_ATTRIBUTE_DIRECTORY)) // if not exists, or not directory, then remove suffix { while (e>p && *e != _T('\\')) e=CharPrev(p, e); if (*e == _T('\\')) *e=0; } } } _tcscpy(state_install_directory,buf); } RegCloseKey(hKey); } } if (!state_install_directory[0]) { _tcscpy(state_install_directory,head->install_directory); #ifdef NSIS_CONFIG_WINAMPHACKCHECK #warning NSIS_CONFIG_WINAMPHACKCHECK defined, this section NOT internationalized, proceed with caution! if (!mini_stricmp(state_install_directory,"$PROGRAMFILES\\Winamp")) { HKEY hKey; if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Winamp",0,KEY_READ,&hKey) == ERROR_SUCCESS) { int l = sizeof(buf); int t=REG_SZ; if (RegQueryValueEx(hKey,"UninstallString",NULL,&t,buf,&l ) == ERROR_SUCCESS && t == REG_SZ) { char *p=buf+mini_strlen(buf); while (p >= buf && *p != '\\') p--; if ( p >= buf) { char *i=buf; *p=0; while (*i == ' ' || *i == '\"') i++; mini_strcpy(state_install_directory,i); st=1; } } RegCloseKey(hKey); } } #endif if (!st && !process_string(buf,state_install_directory,NULL)) { _tcscpy(state_install_directory,buf); } } { INT32 args[] = { (INT32)head->name }; GETRESOURCE2(tmpbuf, JAVAWS_MESSAGE_SETUP, args); wsprintf(g_caption,"%s Setup",head->name); } #ifdef NSIS_CONFIG_LOG if (head->silent_install==2) { wsprintf(g_log_file,"%s%sinstall.log",state_install_directory,state_install_directory[mini_strlen(state_install_directory)-1]=='\\'?"":"\\"); log_dolog=1; } #endif if (!head->silent_install && autoinstall != 1) { ret = DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST), GetDesktopWindow(),DialogProc); /* if ret was 3 we only showed the license agreement, */ /* so continue as if we are doing an autoinstall and */ /* run the install thread without a UI. */ if (ret != 3) return ret; } m_section[0].default_state=0x80000000; return install_thread(NULL); } }
__declspec(dllexport) void download (HWND parent, int string_size, char *variables, stack_t **stacktop) { static char buf[1024]; static char url[1024]; static char filename[1024]; int wasen=0; HWND hwndL=0; HWND hwndB=0; static char szDownloading[32];//= "Downloading %s"; static char szConnecting[32];//= "Connecting ..."; static char szSecond[32];//= "second"; static char szMinute[32];//= "minute"; static char szHour[32];//= "hour"; static char szPlural[32];//= "s"; static char szProgress[128];//= "%dkB (%d%%) of %dkB @ %d.%01dkB/s"; static char szRemaining[128];//= " (%d %s%s remaining)"; g_parent = parent; EXDLL_INIT(); popstring(url); if (!lstrcmpi(url, "/TRANSLATE")) { popstring(szDownloading); popstring(szConnecting); popstring(szSecond); popstring(szMinute); popstring(szHour); popstring(szPlural); popstring(szProgress); popstring(szRemaining); popstring(url); } else { lstrcpy(szDownloading, "Downloading %s"); lstrcpy(szConnecting, "Connecting ..."); lstrcpy(szSecond, "second"); lstrcpy(szMinute, "minute"); lstrcpy(szHour, "hour"); lstrcpy(szPlural, "s"); lstrcpy(szProgress, "%dkB (%d%%) of %dkB @ %d.%01dkB/s"); lstrcpy(szRemaining, " (%d %s%s remaining)"); } lstrcpyn(buf, url, 10); if (!lstrcmpi(buf, "/TIMEOUT=")) { g_timeout_ms=my_atoi(url+9); popstring(url); } popstring(filename); HANDLE hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL); if (hFile == INVALID_HANDLE_VALUE) { wsprintf (buf, "Unable to open %s", filename); setuservariable(INST_0, buf); } else { if (g_parent) { g_childwnd=FindWindowEx(g_parent,NULL,"#32770",NULL); hwndL=GetDlgItem(g_childwnd,1016); hwndB=GetDlgItem(g_childwnd,1027); if (hwndL && IsWindowVisible(hwndL)) ShowWindow(hwndL,SW_HIDE); else hwndL=NULL; if (hwndB && IsWindowVisible(hwndB)) ShowWindow(hwndB,SW_HIDE); else hwndB=NULL; wasen=EnableWindow(GetDlgItem(g_parent,IDCANCEL),1); lpWndProcOld = (void *) GetWindowLong(g_parent,GWL_WNDPROC); SetWindowLong(g_parent,GWL_WNDPROC,(long)ParentWndProc); g_dialog = CreateDialog((HINSTANCE)hModule, MAKEINTRESOURCE(IDD_DIALOG1), g_childwnd, DownloadDialogProc); if (g_dialog) { GetWindowRect(g_dialog,&cr); ScreenToClient(g_dialog,(LPPOINT)&cr); ScreenToClient(g_dialog,((LPPOINT)&cr)+1); GetWindowRect(GetDlgItem(g_childwnd,1016),&r); ScreenToClient(g_childwnd,(LPPOINT)&r); ScreenToClient(g_childwnd,((LPPOINT)&r)+1); SetWindowPos(g_dialog,0,r.left,r.top,r.right-r.left,cr.bottom-cr.top,SWP_NOACTIVATE|SWP_NOZORDER); AdjustSize(IDC_STATIC2); AdjustSize(IDC_PROGRESS1); ShowWindow(g_dialog,SW_SHOWNA); char *p=filename; while (*p) p++; while (*p != '\\' && p != filename) p=CharPrev(filename,p); wsprintf(buf,szDownloading, p+1); SetDlgItemText(g_childwnd,1006,buf); SetDlgItemText (g_dialog, IDC_STATIC2, szConnecting); } } g_hwndProgressBar = GetDlgItem (g_dialog, IDC_PROGRESS1); JNL_HTTPGet *get; char *error=NULL; { WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); static char buf[8192]=""; char *p=NULL; HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) { DWORD l = 4; DWORD t; DWORD v; if (RegQueryValueEx(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD && v) { l=8192; if (RegQueryValueEx(hKey,"ProxyServer",NULL,&t,(unsigned char *)buf,&l ) == ERROR_SUCCESS && t == REG_SZ) { p=strstr(buf,"http="); if (!p) p=buf; else { p+=5; } char *tp=strstr(p,";"); if (tp) *tp=0; char *p2=strstr(p,"="); if (p2) p=0; // we found the wrong proxy } } buf[8192-1]=0; RegCloseKey(hKey); } DWORD start_time=GetTickCount(); get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL); int st; int has_printed_headers = 0; int cl; int len; int sofar = 0; DWORD last_recv_time=start_time; get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)"); get->addheader ("Accept: */*"); get->connect (url); while (1) { if (g_dialog) { MSG msg; while (PeekMessage(&msg,g_dialog,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } Sleep(25); if (g_cancelled) break; st = get->run (); if (st == -1) { error=get->geterrorstr(); break; } else if (st == 1) { if (sofar < cl) error="download incomplete"; break; } else { if (get->get_status () == 0) { // progressFunc ("Connecting ...", 0); if (last_recv_time+g_timeout_ms < GetTickCount()) { error = "Timed out on connecting."; break; } } else if (get->get_status () == 1) { progress_callback("Reading headers", 0); if (last_recv_time+g_timeout_ms < GetTickCount()) { error = "Timed out on getting headers."; break; } } else if (get->get_status () == 2) { if (! has_printed_headers) { has_printed_headers = 1; last_recv_time=GetTickCount(); cl = get->content_length (); if (cl == 0) { error = "Server did not specify content length."; break; } else if (g_dialog) { SendMessage(g_hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,30000)); g_file_size=cl; } } while ((len = get->bytes_available ()) > 0) { if (len > 8192) len = 8192; len = get->get_bytes (buf, len); if (len > 0) { last_recv_time=GetTickCount(); DWORD dw; WriteFile(hFile,buf,len,&dw,NULL); sofar += len; int time_sofar=(GetTickCount()-start_time)/1000; int bps=sofar/(time_sofar?time_sofar:1); int remain=MulDiv(time_sofar,cl,sofar) - time_sofar; char *rtext=szSecond; if (remain >= 60) { remain/=60; rtext=szMinute; if (remain >= 60) { remain/=60; rtext=szHour; } } wsprintf (buf, szProgress, sofar/1024, MulDiv(100,sofar,cl), cl/1024, bps/1024,((bps*10)/1024)%10 ); if (remain) wsprintf(buf+lstrlen(buf),szRemaining, remain, rtext, remain==1?"":szPlural ); progress_callback(buf, sofar); } else { if (sofar < cl) error = "Server aborted."; break; } } if (GetTickCount() > last_recv_time+g_timeout_ms) { error = "Downloading timed out."; break; } } else { error = "Bad response status."; break; } } } WSACleanup(); } CloseHandle(hFile); if (g_parent) { if (g_dialog) DestroyWindow(g_dialog); if (lpWndProcOld) SetWindowLong(g_parent,GWL_WNDPROC,(long)lpWndProcOld); if (g_childwnd) { if (hwndB) ShowWindow(hwndB,SW_SHOWNA); if (hwndL) ShowWindow(hwndL,SW_SHOWNA); } if (wasen) EnableWindow(GetDlgItem(g_parent,IDCANCEL),0); } if (g_cancelled) { setuservariable(INST_0, "cancel"); DeleteFile(filename); } else if (error == NULL) { setuservariable(INST_0, "success"); } else { DeleteFile(filename); setuservariable(INST_0, error); } delete get; } }
void ExecScript(int log) { TCHAR szRet[128] = _T(""); TCHAR meDLLPath[MAX_PATH]; TCHAR *executor; TCHAR *g_exec; TCHAR *pExec; unsigned int g_to; BOOL bOEM; if (!IsWOW64()) { TCHAR* p; int nComSpecSize; nComSpecSize = GetModuleFileName(g_hInst, meDLLPath, MAX_PATH) + 2; // 2 chars for quotes g_exec = (TCHAR *)GlobalAlloc(GPTR, sizeof(TCHAR)*(g_stringsize+nComSpecSize+2)); // 1 for space, 1 for null p = meDLLPath + nComSpecSize - 2; // point p at null char of meDLLPath *g_exec = _T('"'); executor = g_exec + 1; // Look for the last '\' in path. do { if (*p == _T('\\')) break; p = CharPrev(meDLLPath, p); } while (p > meDLLPath); if (p == meDLLPath) { // bad path pushstring(_T("error")); GlobalFree(g_exec); return; } *p = 0; GetTempFileName(meDLLPath, _T("ns"), 0, executor); // executor = new temp file name in module path. *p = _T('\\'); if (CopyFile(meDLLPath, executor, FALSE)) // copy current DLL to temp file in module path. { HANDLE hFile, hMapping; LPBYTE pMapView; PIMAGE_NT_HEADERS pNTHeaders; hFile = CreateFile(executor, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0); hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); pMapView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0); if (pMapView) { pNTHeaders = (PIMAGE_NT_HEADERS)(pMapView + ((PIMAGE_DOS_HEADER)pMapView)->e_lfanew); // Turning the copied DLL into a stripped down executable. pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE; // Windows character-mode user interface (CUI) subsystem. pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; // g_hInst is assumed to be the very base of the DLL in memory. // WinMain will have the address of the WinMain function in memory. // Getting the difference gets you the relative location of the // WinMain function. pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD) ((DWORD_PTR)AsExeWinMain - (DWORD_PTR)g_hInst); UnmapViewOfFile(pMapView); } CloseHandle(hMapping); CloseHandle(hFile); } lstrcat(g_exec, _T("\"")); // add space pExec = g_exec + lstrlen(g_exec); *pExec = _T(' '); pExec++; } else { executor = NULL; g_exec = (TCHAR *)GlobalAlloc(GPTR, sizeof(TCHAR)*(g_stringsize+1)); // 1 for NULL pExec = g_exec; } g_to = 0; // default is no timeout bOEM = FALSE; // default is no OEM->ANSI conversion g_hwndList = NULL; // g_hwndParent = the caller, usually NSIS installer. if (g_hwndParent) // The window class name for dialog boxes is "#32770" g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,_T("#32770"),NULL),NULL,_T("SysListView32"),NULL); // g_exec is the complete command to run: It has the copy of this DLL turned // into an executable right now. params: // Get the command I need to run from the NSIS stack. popstring(pExec); if (my_strstr(pExec, _T("/TIMEOUT=")) == pExec) { TCHAR *szTimeout = pExec + 9; g_to = my_atoi(szTimeout); *pExec = 0; goto params; } if (!lstrcmpi(pExec, _T("/OEM"))) { bOEM = TRUE; *pExec = 0; goto params; } if (!pExec[0]) { pushstring(_T("error")); if (pExec-2 >= g_exec) *(pExec-2) = _T('\0'); // skip space and quote if (executor) DeleteFile(executor); GlobalFree(g_exec); return; } // Got all the params off the stack. { STARTUPINFO si={sizeof(si),}; SECURITY_ATTRIBUTES sa={sizeof(sa),}; SECURITY_DESCRIPTOR sd={0,}; PROCESS_INFORMATION pi={0,}; const BOOL isNT = sizeof(void*) > 4 || (GetVersion() < 0x80000000); HANDLE newstdout=0,read_stdout=0; HANDLE newstdin=0,read_stdin=0; DWORD dwRead = 1; DWORD dwExit = 0; DWORD dwWait = WAIT_TIMEOUT; DWORD dwLastOutput; static TCHAR szBuf[1024]; #ifdef _UNICODE static char ansiBuf[1024]; #endif HGLOBAL hUnusedBuf = NULL; TCHAR *szUnusedBuf = 0; if (log) { hUnusedBuf = GlobalAlloc(GHND, log & 2 ? (g_stringsize*sizeof(TCHAR)) : sizeof(szBuf)*4); // Note: will not grow if (log & 2) if (!hUnusedBuf) { lstrcpy(szRet, _T("error")); goto done; } szUnusedBuf = (TCHAR *)GlobalLock(hUnusedBuf); } sa.bInheritHandle = true; sa.lpSecurityDescriptor = NULL; if (isNT) { InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd,true,NULL,false); sa.lpSecurityDescriptor = &sd; } if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { lstrcpy(szRet, _T("error")); goto done; } if (!CreatePipe(&read_stdin,&newstdin,&sa,0)) { lstrcpy(szRet, _T("error")); goto done; } GetStartupInfo(&si); si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdInput = newstdin; si.hStdOutput = newstdout; si.hStdError = newstdout; if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) { lstrcpy(szRet, _T("error")); goto done; } dwLastOutput = GetTickCount(); // Now I'm talking with an executable copy of myself. while (dwWait != WAIT_OBJECT_0 || dwRead) { PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); if (dwRead) { dwLastOutput = GetTickCount(); #ifdef _UNICODE ReadFile(read_stdout, ansiBuf, sizeof(ansiBuf)-1, &dwRead, NULL); ansiBuf[dwRead] = 0; WideConvertIfASCII(ansiBuf, dwRead, szBuf, sizeof(szBuf)/sizeof(szBuf[0])); #else ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL); szBuf[dwRead] = '\0'; #endif if (log) { if (log & 2) { lstrcpyn(szUnusedBuf + lstrlen(szUnusedBuf), szBuf, g_stringsize - lstrlen(szUnusedBuf)); } else { TCHAR *p, *p2; SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf) + 1; if (GlobalSize(hUnusedBuf) < iReqLen*sizeof(TCHAR)) { GlobalUnlock(hUnusedBuf); hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen*sizeof(TCHAR)+sizeof(szBuf), GHND); if (!hUnusedBuf) { lstrcpy(szRet, _T("error")); break; } szUnusedBuf = (TCHAR *)GlobalLock(hUnusedBuf); } p = szUnusedBuf; // get the old left overs lstrcat(p, szBuf); while ((p = my_strstr(p, _T("\t")))) { if ((int)(p - szUnusedBuf) > (int)(GlobalSize(hUnusedBuf)/sizeof(TCHAR) - TAB_REPLACE_SIZE - 1)) { *p++ = _T(' '); } else { int len = lstrlen(p); TCHAR *c_out=(TCHAR*)p+TAB_REPLACE_SIZE+len; TCHAR *c_in=(TCHAR *)p+len; while (len-- > 0) { *c_out--=*c_in--; } lstrcpy(p, TAB_REPLACE); p += TAB_REPLACE_SIZE; *p = _T(' '); } } p = szUnusedBuf; // get the old left overs for (p2 = p; *p2;) { if (*p2 == _T('\r')) { *p2++ = 0; continue; } if (*p2 == _T('\n')) { *p2 = 0; while (!*p && p != p2) p++; LogMessage(p, bOEM); p = ++p2; continue; } p2 = CharNext(p2); } // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf if (p != szUnusedBuf) { TCHAR *p2 = szUnusedBuf; while (*p) *p2++ = *p++; *p2 = 0; } } } } else { if (g_to && GetTickCount() > dwLastOutput+g_to) { TerminateProcess(pi.hProcess, -1); lstrcpy(szRet, _T("timeout")); } else Sleep(LOOPTIMEOUT); } dwWait = WaitForSingleObject(pi.hProcess, 0); GetExitCodeProcess(pi.hProcess, &dwExit); PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); } done: if (log & 2) pushstring(szUnusedBuf); if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf, bOEM); if ( dwExit == STATUS_ILLEGAL_INSTRUCTION ) lstrcpy(szRet, _T("error")); if (!szRet[0]) wsprintf(szRet,_T("%d"),dwExit); pushstring(szRet); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(newstdin); CloseHandle(read_stdin); if (pExec-2 >= g_exec) *(pExec-2) = _T('\0'); // skip space and quote if (executor) DeleteFile(executor); GlobalFree(g_exec); if (log) { GlobalUnlock(hUnusedBuf); GlobalFree(hUnusedBuf); } } }
BOOL CALLBACK DirProc2(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg== WM_INITDIALOG) { TCHAR str[MAX_PATH]; TCHAR msg[128]; TCHAR msg2[128]; INT32 args[] = {(INT32)(m_header->name), (INT32)msg}; INT32 args2[] ={(INT32)msg2}; wsprintf(msg2,"%s %s", state_alt_name, state_alt_version); GETRESOURCE(msg, JAVAWS_MESSAGE_INSTDIR); GETRESOURCE2(str, JAVAWS_MESSAGE_SETUP2, args); SetWindowText(hwndDlg, str); GETRESOURCE(str, JAVAWS_MESSAGE_JRE); SetDlgItemText(hwndDlg,IDC_DIR,state_alt_directory); SetDlgItemText(hwndDlg,IDC_INTROTEXT, str); GETRESOURCE2(str, JAVAWS_MESSAGE_SELECTDIR2, args2); SetDlgItemText(hwndDlg,IDC_SELDIRTEXT,str); SendMessage(hwndDlg,WM_USER+3,0,0); } if (uMsg == WM_COMMAND) { int id=LOWORD(wParam); if (id == IDC_OK) { GetDlgItemText(hwndDlg, IDC_DIR, state_alt_directory, MAX_PATH); EndDialog(hwndDlg, 1); } if (id == IDC_CANCEL) { state_alt_directory[0]=0; EndDialog(hwndDlg, 0); } if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE) { SendMessage(hwndDlg,WM_USER+3,0,0); } if (id == IDC_BROWSE) { TCHAR name[MAX_PATH]; BROWSEINFO bi={0,}; ITEMIDLIST *idlist; GetDlgItemText(hwndDlg,IDC_DIR,name,MAX_PATH); bi.hwndOwner = hwndDlg; bi.pszDisplayName = name; bi.lpfn=BrowseCallbackProc; bi.lParam=(LPARAM)hwndDlg; bi.lpszTitle = (LPTSTR)malloc(128 * sizeof(TCHAR)); GETRESOURCE(bi.lpszTitle, JAVAWS_MESSAGE_SELECTDIR3); bi.ulFlags = BIF_RETURNONLYFSDIRS; idlist = SHBrowseForFolder( &bi ); if (idlist) { LPTSTR p; SHGetPathFromIDList( idlist, name ); Shell_Free(idlist); p=name+_tcslen(name)-_tcslen(state_alt_version); if (p <= name || *(CharPrev(name, p))!=_T('\\') || _tcsicmp(p,state_alt_version)) { if ( *(CharPrev(name, &(name[_tcslen(name)]))) != _T('\\') ) _tcscat(name,_T("\\")); _tcscat(name,state_alt_version); } SetDlgItemText(hwndDlg,IDC_DIR,name); uMsg = WM_USER+3; } } } if (uMsg == WM_USER+3) { EnableWindow(GetDlgItem(GetParent(hwndDlg),IDOK),1); } return 0; }