void CTrayIconController::patch() { QString file = openDialog(); if (file.isNull()) return; DWORD type; if (!GetBinaryType(qUtf16Printable(file), &type)) return; QString dir = QCoreApplication::applicationDirPath(); QStringList files; if (type == SCS_32BIT_BINARY) { files.append(dir + "/Revive/x86/LibRevive32_1.dll"); files.append(dir + "/Revive/x86/LibRevive32_1.dll"); files.append(dir + "/Revive/x86/openvr_api.dll"); } if (type == SCS_64BIT_BINARY) { files.append(dir + "/Revive/x64/LibRevive64_1.dll"); files.append(dir + "/Revive/x64/LibRevive64_1.dll"); files.append(dir + "/Revive/x64/openvr_api.dll"); } QStringList names = { "xinput1_3.dll", "xinput9_1_0.dll", "openvr_api.dll" }; QFileInfo info(file); WindowsServices::CopyFiles(files, info.absolutePath(), names); }
static int exm_file_check(Exm *exm, const char *filename) { char *iter; size_t length; DWORD ret = -1; if (!filename || !*filename) return 0; if (!GetBinaryType(filename, &ret) || ((ret != SCS_32BIT_BINARY) && (ret != SCS_64BIT_BINARY))) { printf("file %s is not an executable program or its path is wrong (%ld)\n", filename, ret); return 0; } length = strlen(filename); exm->filename = malloc(sizeof(char) * (length + 1)); if (!exm->filename) return 0; memcpy(exm->filename, filename, length + 1); /* '/' replaced by '\' */ iter = exm->filename; while (*iter) { if (*iter == '/') *iter = '\\'; iter++; } return 1; }
int nt_access(char *filename, int mode) { DWORD attribs=(DWORD)-1, bintype; int tries=0; char buf[512];/*FIXBUF*/ if (!filename) { errno = ENOENT; return -1; } (void)StringCbPrintf(buf,sizeof(buf),"%s",filename); retry: attribs = GetFileAttributes(buf); tries++; if (attribs == (DWORD) -1) { if( (GetLastError() == ERROR_FILE_NOT_FOUND) && (mode & X_OK) ) { switch(tries) { case 1: (void)StringCbPrintf(buf,sizeof(buf),"%s.exe",filename); break; case 2: (void)StringCbPrintf(buf,sizeof(buf),"%s.cmd",filename); break; case 3: (void)StringCbPrintf(buf,sizeof(buf),"%s.bat",filename); break; case 4: (void)StringCbPrintf(buf,sizeof(buf),"%s.com",filename); break; default: goto giveup; break; } goto retry; } } giveup: if (attribs == (DWORD)-1 ) { errno = EACCES; return -1; } if ( (mode & W_OK) && (attribs & FILE_ATTRIBUTE_READONLY) ) { errno = EACCES; return -1; } if (mode & X_OK) { if ((mode & XD_OK) && (attribs & FILE_ATTRIBUTE_DIRECTORY) ) { errno = EACCES; return -1; } if ((!(attribs & FILE_ATTRIBUTE_DIRECTORY)) && !GetBinaryType(buf,&bintype) &&(tries >4) ) { errno = EACCES; return -1; } } return 0; }
/* * patch based on work by Chun-Pong Yu (bol.pacific.net.sg) */ BOOL is_nt_executable(char *path,char *extension) { DWORD exetype; if (GetBinaryType(path,&exetype)) return TRUE; if (*extension && find_no_assoc(extension)) return TRUE; return FALSE; }
static DWORD get_file_attributes(const char *filename, const char *extension, int hasext, int mode, int *isx) { char *buf; size_t filenamelen; DWORD attribs, bintype; filenamelen = strlen(filename); if (hasext) { buf = (char *)_alloca(filenamelen + 1); strcpy(buf, filename); } else { buf = (char *)_alloca(filenamelen + strlen(extension) + 1); strcpy(buf, filename); strcpy(buf + filenamelen, extension); } attribs = GetFileAttributes(buf); if ((attribs != (DWORD)(-1)) && (mode & X_OK) && (GetBinaryType(buf, &bintype) || is_pathext(extension))) /* found, and executable */ *isx = 1; else *isx = 0; return attribs; }
static Exm * exm_new(void) { #ifdef _MSC_VER char buf[MAX_PATH]; #endif Exm *exm; HMODULE kernel32; size_t l1; size_t l2; DWORD type; /* Check if CreateRemoteThread() is available. */ /* MSDN suggests to check the availability of a */ /* function instead of checking the Windows version. */ kernel32 = LoadLibrary("kernel32.dll"); if (!kernel32) { printf("no kernel32.dll found\n"); return 0; } if (!GetProcAddress(kernel32, "CreateRemoteThread")) { printf("no CreateRemoteThread found\n"); goto free_kernel32; } exm = (Exm *)calloc(1, sizeof(Exm)); if (!exm) goto free_kernel32; exm->ll = (_load_library)_exm_symbol_get("kernel32.dll", "LoadLibraryA"); if (!exm->ll) goto free_exm; exm->fl = (_free_library)_exm_symbol_get("kernel32.dll", "FreeLibrary"); if (!exm->fl) goto free_exm; #ifdef _MSC_VER _getcwd(buf, MAX_PATH); l1 = strlen(buf); #else l1 = strlen(PACKAGE_BIN_DIR); #endif l2 = strlen("/examine_dll.dll"); exm->dll_fullname = malloc(sizeof(char) * (l1 + l2 + 1)); if (!exm->dll_fullname) goto free_exm; #ifdef _MSC_VER _getcwd(buf, MAX_PATH); memcpy(exm->dll_fullname, buf, l1); #else memcpy(exm->dll_fullname, PACKAGE_BIN_DIR, l1); #endif memcpy(exm->dll_fullname + l1, "/examine_dll.dll", l2); exm->dll_fullname[l1 + l2] = '\0'; if (GetBinaryType(exm->dll_fullname, &type)) { printf("%s is not a valid DLL\n", exm->dll_fullname); goto free_exm; } else { if (GetLastError() != ERROR_BAD_EXE_FORMAT) { printf("%s is not a valid DLL\n", exm->dll_fullname); goto free_exm; } } exm->dll_length = l1 + l2 + 1; printf(" * DLL to inject: %s\n", exm->dll_fullname); FreeLibrary(kernel32); return exm; free_exm: free(exm); free_kernel32: FreeLibrary(kernel32); return 0; }
void main(int argc, char *argv[]) { int error, i; DWORD dwNumWritten; char pszUserName[100], pszPipeName[MAX_PATH]; DWORD length; char pBuffer[4096]; int nGroupId; int nNproc = 1; bool bGetHosts = false; bool bUseNP = false; //char pszCmdLine[1024]; WSADATA wsaData; int err; //TCHAR pszJobID[100]; //TCHAR pszEnv[MAX_PATH] = TEXT(""); TCHAR pszDir[MAX_PATH] = TEXT("."); // Start the Winsock dll. if ((err = WSAStartup( MAKEWORD( 2, 0 ), &wsaData )) != 0) { printf("Winsock2 dll not initialized, error: %d\n", err); return; } /* bGetHosts = !GetOpt(argc, argv, "-np", &nNproc); if (argc == 1) { printf("No command line specified\n"); return; } //*/ GetOpt(argc, argv, "-env", g_pszEnv); if (!GetOpt(argc, argv, "-dir", pszDir)) GetCurrentDirectory(MAX_PATH, pszDir); SetCurrentDirectory(pszDir); DWORD dwType; if (GetBinaryType(argv[1], &dwType)) { // The first argument is an executable so set things up to run one process g_nHosts = 1; TCHAR pszTempExe[MAX_PATH], *namepart; _tcscpy(g_pszExe, argv[1]); GetFullPathName(g_pszExe, MAX_PATH, pszTempExe, &namepart); // Quote the executable in case there are spaces in the path _stprintf(g_pszExe, TEXT("\"%s\""), pszTempExe); g_pszArgs[0] = TEXT('\0'); for (int i=2; i<argc; i++) { _tcscat(g_pszArgs, argv[i]); if (i < argc-1) _tcscat(g_pszArgs, TEXT(" ")); } RunLocal(true); return; } else { if (GetOpt(argc, argv, "-np", &g_nHosts)) { if (g_nHosts < 1) { printf("Error: must specify a number greater than 0 after the -np option\n"); return; } if (argc < 2) { printf("Error: not enough arguments.\n"); return; } _tcscpy(g_pszExe, argv[1]); g_pszArgs[0] = TEXT('\0'); for (int i=2; i<argc; i++) { _tcscat(g_pszArgs, argv[i]); if (i < argc-1) _tcscat(g_pszArgs, TEXT(" ")); } bUseNP = true; } else if (GetOpt(argc, argv, "-localonly", &g_nHosts)) { bool bDoSMP = !GetOpt(argc, argv, "-tcp"); if (g_nHosts < 1) { printf("Error: must specify a number greater than 0 after the -localonly option\n"); return; } if (argc < 2) { printf("Error: not enough arguments.\n"); return; } TCHAR pszTempExe[MAX_PATH], *namepart; _tcscpy(g_pszExe, argv[1]); GetFullPathName(g_pszExe, MAX_PATH, pszTempExe, &namepart); // Quote the executable in case there are spaces in the path _stprintf(g_pszExe, TEXT("\"%s\""), pszTempExe); g_pszArgs[0] = TEXT('\0'); for (int i=2; i<argc; i++) { _tcscat(g_pszArgs, argv[i]); if (i < argc-1) _tcscat(g_pszArgs, TEXT(" ")); } RunLocal(bDoSMP); return; } else { ParseConfigFile(argv[1]); if ((_tcslen(g_pszArgs) > 0) && (argc > 2)) _tcscat(g_pszArgs, TEXT(" ")); for (int i=2; i<argc; i++) { _tcscat(g_pszArgs, argv[i]); if (i < argc-1) _tcscat(g_pszArgs, TEXT(" ")); } } } TCHAR pszTempExe[MAX_PATH], *namepart; GetFullPathName(g_pszExe, MAX_PATH, pszTempExe, &namepart); // Quote the executable in case there are spaces in the path _stprintf(g_pszExe, TEXT("\"%s\""), pszTempExe); // Figure out how many processes to launch nNproc = 0; if (bUseNP) nNproc = g_nHosts; else { HostNode *n = g_pHosts; while (n) { nNproc += n->nSMPProcs; n = n->next; } } length = 100; if (GetUserName(pszUserName, &length)) sprintf(pszPipeName, "\\\\.\\pipe\\mpd%s", pszUserName); else strcpy(pszPipeName, "\\\\.\\pipe\\mpdpipe"); //printf("MPIRunMPD connecting to pipe '%s'\n", pszPipeName); HANDLE hPipe = CreateFile( pszPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPipe != INVALID_HANDLE_VALUE) { HANDLE hOutputPipe; HANDLE hIOThread, hReadyEvent; strcat(pszPipeName, "out"); hOutputPipe = CreateNamedPipe( pszPipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH, PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0,0,0, NULL ); if (hOutputPipe == INVALID_HANDLE_VALUE) { error = GetLastError(); printf("Unable to create pipe: error %d on pipe '%s'\n", error, pszPipeName); CloseHandle(hPipe); ExitProcess(error); } WriteFile(hPipe, pszPipeName, strlen(pszPipeName)+1, &dwNumWritten, NULL); //printf("MPIRunMPD waiting for connection back on pipe '%s'\n", pszPipeName); if (ConnectNamedPipe(hOutputPipe, NULL)) { strcpy(pBuffer, "create group\n"); WriteFile(hPipe, pBuffer, strlen(pBuffer), &dwNumWritten, NULL); GetString(hOutputPipe, pBuffer); nGroupId = atoi(pBuffer); //printf("group id acquired: %d\n", nGroupId); LaunchNode *pList = NULL, *p; if (bUseNP) { p = pList = new LaunchNode; pList->pNext = NULL; sprintf(pBuffer, "next %d\n", nNproc); WriteFile(hPipe, pBuffer, strlen(pBuffer), &dwNumWritten, NULL); for (i=0; i<nNproc; i++) { GetString(hOutputPipe, pBuffer); //printf("host%d: %s\n", i, pBuffer); //strcpy(p->pszCmdLine, pszCmdLine); strcpy(p->pszCmdLine, g_pszExe); strcpy(p->pszArgs, g_pszArgs); strcpy(p->pszIPPort, pBuffer); strcpy(p->pszDir, "."); p->pszEnv[0] = '\0'; p->nIP = 0; p->nPort = 0; p->pNext = NULL; if (i<nNproc-1) { p->pNext = new LaunchNode; p = p->pNext; } } } else { int iproc = 0; int nShmLow = 0, nShmHigh = 0; unsigned long nCurIP; int nCurPort; while (g_pHosts) { nShmLow = iproc; nShmHigh = iproc + g_pHosts->nSMPProcs - 1; sprintf(pBuffer, "find %s\n", g_pHosts->host); WriteFile(hPipe, pBuffer, strlen(pBuffer), &dwNumWritten, NULL); GetString(hOutputPipe, pBuffer); nCurPort = atoi(pBuffer); NT_get_ip(g_pHosts->host, &nCurIP); for (int i=0; i<g_pHosts->nSMPProcs; i++) { if (pList == NULL) { pList = p = new LaunchNode; pList->pNext = NULL; } else { p->pNext = new LaunchNode; p = p->pNext; p->pNext = NULL; } if (strlen(g_pHosts->exe) > 0) strcpy(p->pszCmdLine, g_pHosts->exe); else strcpy(p->pszCmdLine, g_pszExe); strcpy(p->pszArgs, g_pszArgs); p->nIP = nCurIP; p->nPort = nCurPort; sprintf(p->pszEnv, "MPICH_USE_MPD=1|MPICH_JOBID=mpi%d|MPICH_NPROC=%d|MPICH_IPROC=%d|MPICH_SHM_LOW=%d|MPICH_SHM_HIGH=%d", nGroupId, nNproc, iproc, nShmLow, nShmHigh); if (strlen(g_pszEnv) > 0) { strcat(p->pszEnv, "|"); strcat(p->pszEnv, g_pszEnv); } iproc++; } HostNode *n = g_pHosts; g_pHosts = g_pHosts->next; delete n; } } hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); DWORD dwThreadID; hIOThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RedirectIOLoopThread, hReadyEvent, 0, &dwThreadID); if (WaitForSingleObject(hReadyEvent, 5000) != WAIT_OBJECT_0) { printf("Wait for hReadyEvent failed, error %d\n", GetLastError()); ExitProcess(1); } //printf("IO loop waiting on socket: %s:%d\n", g_pszIOListenHost, g_nIOListenPort); // launch processes g_nConnectionsLeft = nNproc * 2; // 1 for stdout and 1 for stderr p = pList; for (i=0; i<nNproc; i++) { if (i == 0) sprintf(pBuffer, "launch h'%s'c'%s'a'%s'g'%d'r'%d'0'%s:%d'1'%s:%d'2'%s:%d'\n", p->pszIPPort, p->pszCmdLine, p->pszArgs, nGroupId, i, g_pszIOListenHost, g_nIOListenPort, g_pszIOListenHost, g_nIOListenPort, g_pszIOListenHost, g_nIOListenPort); else sprintf(pBuffer, "launch h'%s'c'%s'a'%s'g'%d'r'%d'1'%s:%d'2'%s:%d'\n", p->pszIPPort, p->pszCmdLine, p->pszArgs, nGroupId, i, g_pszIOListenHost, g_nIOListenPort, g_pszIOListenHost, g_nIOListenPort); WriteFile(hPipe, pBuffer, strlen(pBuffer), &dwNumWritten, NULL); p = p->pNext; delete pList; pList = p; } strcpy(pBuffer, "done\n"); WriteFile(hPipe, pBuffer, strlen(pBuffer), &dwNumWritten, NULL); CloseHandle(hPipe); CloseHandle(hOutputPipe); WaitForSingleObject(g_hNoMoreConnectionsEvent, INFINITE); } else { error = GetLastError(); printf("unable to connect to client pipe: error %d\n", error); CloseHandle(hPipe); CloseHandle(hOutputPipe); } } WSACleanup(); }
TSRM_API int tsrm_win32_access(const char *pathname, int mode) { time_t t; HANDLE thread_token = NULL; PSID token_sid; SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; DWORD priv_set_length = sizeof(PRIVILEGE_SET); PRIVILEGE_SET privilege_set = {0}; DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0; BYTE * psec_desc = NULL; BOOL fAccess = FALSE; realpath_cache_bucket * bucket = NULL; char * real_path = NULL; if (mode == 1 /*X_OK*/) { DWORD type; return GetBinaryType(pathname, &type) ? 0 : -1; } else { if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) { real_path = (char *)malloc(MAX_PATH); if(tsrm_realpath(pathname, real_path) == NULL) { goto Finished; } pathname = real_path; } if(access(pathname, mode)) { free(real_path); return errno; } /* If only existence check is made, return now */ if (mode == 0) { free(real_path); return 0; } /* Only in NTS when impersonate==1 (aka FastCGI) */ /* AccessCheck() requires an impersonation token. We first get a primary token and then create a duplicate impersonation token. The impersonation token is not actually assigned to the thread, but is used in the call to AccessCheck. Thus, this function itself never impersonates, but does use the identity of the thread. If the thread was impersonating already, this function uses that impersonation context. */ if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) { if (GetLastError() == ERROR_NO_TOKEN) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) { TWG(impersonation_token) = NULL; goto Finished; } } } /* token_sid will be freed in tsrmwin32_dtor */ token_sid = tsrm_win32_get_token_sid(thread_token); if (!token_sid) { if (TWG(impersonation_token_sid)) { free(TWG(impersonation_token_sid)); } TWG(impersonation_token_sid) = NULL; goto Finished; } /* Different identity, we need a new impersontated token as well */ if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) { if (TWG(impersonation_token_sid)) { free(TWG(impersonation_token_sid)); } TWG(impersonation_token_sid) = token_sid; /* Duplicate the token as impersonated token */ if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) { goto Finished; } } else { /* we already have it, free it then */ free(token_sid); } if (CWDG(realpath_cache_size_limit)) { t = time(0); bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t); if(bucket == NULL && real_path == NULL) { /* We used the pathname directly. Call tsrm_realpath */ /* so that entry is created in realpath cache */ real_path = (char *)malloc(MAX_PATH); if(tsrm_realpath(pathname, real_path) != NULL) { pathname = real_path; bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t); } } } /* Do a full access check because access() will only check read-only attribute */ if(mode == 0 || mode > 6) { if(bucket != NULL && bucket->is_rvalid) { fAccess = bucket->is_readable; goto Finished; } desired_access = FILE_GENERIC_READ; } else if(mode <= 2) { if(bucket != NULL && bucket->is_wvalid) { fAccess = bucket->is_writable; goto Finished; } desired_access = FILE_GENERIC_WRITE; } else if(mode <= 4) { if(bucket != NULL && bucket->is_rvalid) { fAccess = bucket->is_readable; goto Finished; } desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS; } else { // if(mode <= 6) if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) { fAccess = bucket->is_readable & bucket->is_writable; goto Finished; } desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; } if(TWG(impersonation_token) == NULL) { goto Finished; } /* Get size of security buffer. Call is expected to fail */ if(GetFileSecurity(pathname, sec_info, NULL, 0, &sec_desc_length)) { goto Finished; } psec_desc = (BYTE *)malloc(sec_desc_length); if(psec_desc == NULL || !GetFileSecurity(pathname, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) { goto Finished; } MapGenericMask(&desired_access, &gen_map); if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) { goto Finished_Impersonate; } /* Keep the result in realpath_cache */ if(bucket != NULL) { if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) { bucket->is_rvalid = 1; bucket->is_readable = fAccess; } else if(desired_access == FILE_GENERIC_WRITE) { bucket->is_wvalid = 1; bucket->is_writable = fAccess; } else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) { bucket->is_rvalid = 1; bucket->is_readable = fAccess; bucket->is_wvalid = 1; bucket->is_writable = fAccess; } } Finished_Impersonate: if(psec_desc != NULL) { free(psec_desc); psec_desc = NULL; } Finished: if(thread_token != NULL) { CloseHandle(thread_token); } if(real_path != NULL) { free(real_path); real_path = NULL; } if(fAccess == FALSE) { errno = EACCES; return errno; } else { return 0; } } }
VOID cmdCheckBinary (VOID) { LPSTR lpAppName; ULONG BinaryType; PPARAMBLOCK lpParamBlock; PCHAR lpCommandTail,lpTemp; ULONG AppNameLen,CommandTailLen = 0; USHORT CommandTailOff,CommandTailSeg,usTemp; NTSTATUS Status; UNICODE_STRING Unicode; OEM_STRING OemString; ANSI_STRING AnsiString; if(DontCheckDosBinaryType){ setCF(0); return; // DOS Exe } lpAppName = (LPSTR) GetVDMAddr (getDS(),getDX()); Unicode.Buffer = NULL; AnsiString.Buffer = NULL; RtlInitString((PSTRING)&OemString, lpAppName); Status = RtlOemStringToUnicodeString(&Unicode,&OemString,TRUE); if ( NT_SUCCESS(Status) ) { Status = RtlUnicodeStringToAnsiString(&AnsiString, &Unicode, TRUE); } if ( !NT_SUCCESS(Status) ) { Status = RtlNtStatusToDosError(Status); } else if (GetBinaryType (AnsiString.Buffer,(LPLONG)&BinaryType) == FALSE) { Status = GetLastError(); } if (Unicode.Buffer != NULL) { RtlFreeUnicodeString( &Unicode ); } if (AnsiString.Buffer != NULL) { RtlFreeAnsiString( &AnsiString); } if (Status){ setCF(1); setAX((USHORT)Status); return; // Invalid path } if (BinaryType == SCS_DOS_BINARY) { setCF(0); return; // DOS Exe } // Prevent certain WOW apps from being spawned by DOS exe's // This is for win31 compatibility else if (BinaryType == SCS_WOW_BINARY) { if (!IsWowAppRunnable(lpAppName)) { setCF(0); return; // Run as DOS Exe } } if (VDMForWOW && BinaryType == SCS_WOW_BINARY && IsFirstWOWCheckBinary) { IsFirstWOWCheckBinary = FALSE; setCF(0); return; // Special Hack for krnl286.exe } // dont allow running 32bit binaries from autoexec.nt. Reason is that // running non-dos binary requires that we should have read the actual // command from GetNextVDMCommand. Otherwise the whole design gets into // synchronization problems. if (IsFirstCall) { setCF(1); setAX((USHORT)ERROR_FILE_NOT_FOUND); return; } // Its a 32bit exe, replace the command with "command.com /z" and add the // original binary name to command tail. AppNameLen = strlen (lpAppName); lpParamBlock = (PPARAMBLOCK) GetVDMAddr (getES(),getBX()); if (lpParamBlock) { CommandTailOff = FETCHWORD(lpParamBlock->OffCmdTail); CommandTailSeg = FETCHWORD(lpParamBlock->SegCmdTail); lpCommandTail = (PCHAR) GetVDMAddr (CommandTailSeg,CommandTailOff); if (lpCommandTail){ CommandTailLen = *(PCHAR)lpCommandTail; lpCommandTail++; // point to the actual command tail if (CommandTailLen) CommandTailLen++; // For CR } // We are adding 3 below for "/z<space>" and anothre space between // AppName and CommandTail. if ((3 + AppNameLen + CommandTailLen ) > 128){ setCF(1); setAX((USHORT)ERROR_NOT_ENOUGH_MEMORY); return; } } // copy the stub command.com name strcpy ((PCHAR)&pSCSInfo->SCS_ComSpec,lpszComSpec+8); lpTemp = (PCHAR) &pSCSInfo->SCS_ComSpec; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setDS(usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setDX((usTemp)); // Form the command tail, first "3" is for "/z " pSCSInfo->SCS_CmdTail [0] = (UCHAR)(3 + AppNameLen + CommandTailLen); RtlCopyMemory ((PCHAR)&pSCSInfo->SCS_CmdTail[1],"/z ",3); strcpy ((PCHAR)&pSCSInfo->SCS_CmdTail[4],lpAppName); if (CommandTailLen) { pSCSInfo->SCS_CmdTail[4+AppNameLen] = ' '; RtlCopyMemory ((PCHAR)((ULONG)&pSCSInfo->SCS_CmdTail[4]+AppNameLen+1), lpCommandTail, CommandTailLen); } else { pSCSInfo->SCS_CmdTail[4+AppNameLen] = 0xd; } // Set the parameter Block if (lpParamBlock) { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,lpParamBlock->SegEnv); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,lpParamBlock->pFCB1); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,lpParamBlock->pFCB2); } else { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,0); } lpTemp = (PCHAR) &pSCSInfo->SCS_CmdTail; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); STOREWORD(pSCSInfo->SCS_ParamBlock.OffCmdTail,usTemp); usTemp = (USHORT)((ULONG)lpTemp >> 4); STOREWORD(pSCSInfo->SCS_ParamBlock.SegCmdTail,usTemp); lpTemp = (PCHAR) &pSCSInfo->SCS_ParamBlock; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setES (usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setBX (usTemp); setCF(0); return; }
static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo, const gchar *cmdline) { const gchar *cmd = NULL; gchar buf[BUFFSIZE]; if (!cmdline) { #ifdef G_OS_WIN32 DWORD dwtype; if (g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE) || str_has_suffix_case(filename, ".scr") || str_has_suffix_case(filename, ".pif") || GetBinaryType(filename, &dwtype)) { alertpanel_full (_("Opening executable file"), _("This is an executable file. Opening executable file is restricted for security.\n" "If you want to launch it, save it to somewhere and make sure it is not an virus or something like a malicious program."), ALERT_WARNING, G_ALERTDEFAULT, FALSE, GTK_STOCK_OK, NULL, NULL); return; } execute_open_file(filename, partinfo->content_type); return; #elif defined(__APPLE__) if (g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE) || str_has_suffix_case(filename, ".py") || str_has_suffix_case(filename, ".rb") || str_has_suffix_case(filename, ".sh")) { alertpanel_full (_("Opening executable file"), _("This is an executable file. Opening executable file is restricted for security.\n" "If you want to launch it, save it to somewhere and make sure it is not an virus or something like a malicious program."), ALERT_WARNING, G_ALERTDEFAULT, FALSE, GTK_STOCK_OK, NULL, NULL); return; } execute_open_file(filename, partinfo->content_type); return; #else if (MIME_IMAGE == partinfo->mime_type) cmd = prefs_common.mime_image_viewer; else if (MIME_AUDIO == partinfo->mime_type) cmd = prefs_common.mime_audio_player; else if (MIME_TEXT_HTML == partinfo->mime_type) cmd = prefs_common.uri_cmd; if (!cmd) { if (prefs_common.mime_cmd) { if (str_find_format_times (prefs_common.mime_cmd, 's') == 2) { g_snprintf(buf, sizeof(buf), prefs_common.mime_cmd, partinfo->content_type, "%s"); cmd = buf; } else cmd = prefs_common.mime_cmd; } else { procmime_execute_open_file (filename, partinfo->content_type); return; } } #endif } else cmd = cmdline; if (cmd && str_find_format_times(cmd, 's') == 1) { gchar *cmdbuf; cmdbuf = g_strdup_printf(cmd, filename); execute_command_line(cmdbuf, TRUE); g_free(cmdbuf); } else if (cmd) g_warning("MIME viewer command line is invalid: '%s'", cmd); }
int nt_execve(const char *prog, const char *const *args, const char *const *envir) { STARTUPINFO si; PROCESS_INFORMATION pi; enum {none, directex, shellex} execmode; DWORD exitcode; DWORD dwCreationflags; int priority; char *argv0; char *cmdstr, *cmdend; unsigned int cmdsize; size_t prognamelen, cmdlen; int hasext; char extension[_MAX_FNAME]; const char *begin, *end, *extptr; static char exts[MAX_PATH]; UNREFERENCED_PARAMETER(envir); /* get default PATHEXT or use empty exts */ if (!*exts) { DWORD rc; /* not initialized */ rc = GetEnvironmentVariable("PATHEXT", exts, sizeof(exts)); if ((rc == 0) || (rc >= sizeof(exts))) /* if error or PATHEXT too big will retry at the next call */ *exts = 0; } /* if prog has an extension initialize begin end to skip PATHEXT search */ prognamelen = strlen(prog); extptr = prog + prognamelen - 1; hasext = 0; while (extptr > prog && !ISPATHSEP(*extptr)) { if (*extptr == '.' && *(extptr - 1) != ':' && !ISPATHSEP(*(extptr - 1))) { hasext++; break; } extptr--; } if (hasext) { begin = "."; end = ""; strcpy(extension, extptr); } else { begin = exts; end = exts; *extension = '\0'; } argv0 = (char *)heap_alloc(MAX_PATH); /* (prognamelen + 1) does not really matter, argv0 is '\0' filled */ memcpy(argv0, prog, prognamelen + 1); errno = 0; execmode = none; /* NOTE: loops over PATHEXT if no extension found */ while (*begin) { size_t extlen; if (GetBinaryType(argv0, &exitcode)) { /* exists and is executable NOTE: an "xxx.exe" without a correct PE header (i.e. a text file) has type "DOS binary", but execution will generate a WOW error */ execmode = directex; break; } if (GetLastError() == ERROR_BAD_EXE_FORMAT) { /* exists but is not "executable" */ execmode = shellex; break; } if (hasext) break; /* get next PATHEXT extension */ while (*begin && (*begin != '.')) begin++; while (*end && (*end != ';')) end++; if (!*begin) break; extlen = end - begin; if (extlen < sizeof(extension)) { memcpy(extension, begin, extlen); extension[extlen] = '\0'; /* prognamelen ignores the last '\r' if present */ memcpy(argv0, prog, prognamelen); /* update argv0 adding the extension to prog */ memcpy(argv0 + prognamelen, extension, extlen + 1); } begin = end; /* skip sequences of ';' */ while (*end && *end == ';') end++; }; cmdstr = (char *)heap_alloc(MAX_PATH << 2); cmdsize = MAX_PATH << 2; cmdlen = 0; cmdend = cmdstr; dbgprintf(PR_VERBOSE, "%s(): execute [%s] extension=[%s] mode=%d hasext=%d\n", __FUNCTION__, argv0, extension, execmode, hasext); /* skip over program name */ args++; /* the file (after PATHEXT search) exists, but it's not "executable" */ if (execmode == shellex) { /* if prog had no extension or has the extension associated to shell scripts */ if ((hasext == 0 && *extension == '\0') || is_shell_script(extension)) { int res = process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize); if (res < 0) { execmode = none; } else if (res == 0) { char *newargv[2]; cmdlen = copy_quote_and_fix_slashes(gModuleName, cmdstr); cmdend = cmdstr + cmdlen; newargv[0] = path_to_slash(argv0); newargv[1] = NULL; concat_args_and_quote((const char *const *)newargv, &cmdstr, &cmdlen, &cmdend, &cmdsize); *cmdend = 0; argv0 = gModuleName; execmode = directex; } else { cmdend = cmdstr + cmdlen; execmode = directex; } } else { unsigned long shflags = 0L; /* if the file extension is in pathext, use the same console and wait for child. StrStrI() is from shlwapi */ if (StrStrI(exts, extension)) shflags = SEE_MASK_NO_CONSOLE | SEE_MASK_NOCLOSEPROCESS; if (try_shell_ex(argv0, args, shflags, &cmdstr, &cmdsize)) return (0); /* ShellExecute failed, the file has an unknown extension, but it may be a shell script with a shebang */ if (process_shebang(argv0, (const char *const *)&cmdstr, &cmdlen, &cmdend, &cmdsize) > 0) { cmdend = cmdstr + cmdlen; execmode = directex; } else { /* the file extension is NOT known and the file has NO shebang: returns EPERM, see NOTES */ errno = EPERM; return (-1); } } } else if (execmode == directex) { cmdlen = copy_quote_and_fix_slashes(prog, cmdstr); cmdend = cmdstr + cmdlen; } if (execmode == none) { /* error: prog not found even after trying PATHEXT extensions */ errno = ENOENT; return (-1); } concat_args_and_quote(args, &cmdstr, &cmdlen, &cmdend, &cmdsize); if (*cmdstr == ' ') { /* if we left a ' ' for the quote and there is no quote */ cmdstr++; cmdlen--; } *cmdend = 0; init_startupinfo(&si); dwCreationflags = GetPriorityClass(GetCurrentProcess()); priority = GetThreadPriority(GetCurrentThread()); #if defined(W32DEBUG) /* DebugView output is very difficult to read with overlong lines */ if (cmdlen < 128) dbgprintf(PR_EXEC, "%s(): CreateProcess(%s, ..) cmdstr=[%s]\n", __FUNCTION__, argv0, cmdstr); else { char shortbuf[128+4]; memcpy(shortbuf, cmdstr, 128); memcpy(shortbuf + 128, "...", 4); dbgprintf(PR_EXEC, "nt_execve(): CreateProcess(%s, ..) cmdstr=[%s]\n", argv0, shortbuf); } #endif if (!CreateProcess(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles dwCreationflags | CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { exitcode = GetLastError(); if (exitcode == ERROR_BAD_EXE_FORMAT) { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error BAD_EXE_FORMAT in %s\n", argv0, __FUNCTION__); errno = ENOEXEC; } else if (exitcode == ERROR_INVALID_PARAMETER) { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error INVALID_PARAMETER in %s, cmdstr len=%u\n", argv0, __FUNCTION__, strlen(cmdstr)); /* exceeded command line */ /* return NOT found, ENAMETOOLONG is correct but not understood by the shell that will retry with another path ... */ errno = ENOENT; } else { dbgprintf(PR_ERROR, "!!! CreateProcess(%s, ..) error %ld in %s\n", argv0, exitcode, __FUNCTION__); errno = ENOENT; } goto fail_return; } else { exitcode = 0; if (!SetThreadPriority(pi.hThread, priority)) dbgprintf(PR_ERROR, "!!! SetThreadPriority(0x%p) failed, error %ld\n", pi.hThread, GetLastError()); ResumeThread(pi.hThread); if (!is_gui(argv0)) { if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0) dbgprintf(PR_ERROR, "!!! error %ld waiting for process %ld\n", GetLastError(), pi.dwProcessId); if (!GetExitCodeProcess(pi.hProcess, &exitcode)) dbgprintf(PR_ERROR, "!!! GetExitCodeProcess(0x%p, ..) error %ld in %s\n", pi.hProcess, GetLastError(), __FUNCTION__); } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); close_si_handles(); /* @@@@ should wait for the clipboard ? if (is_dev_clipboard_active) { CloseHandle((HANDLE)_get_osfhandle(0)); CloseHandle((HANDLE)_get_osfhandle(1)); CloseHandle((HANDLE)_get_osfhandle(2)); ... WaitForSingleObject(ghdevclipthread,60*1000); } */ dbgprintf(PR_ALL, "--- %s(): Exec'd process %ld terminated with exitcode %ld\n", __FUNCTION__, pi.dwProcessId, exitcode); exec_exit((int)exitcode); } fail_return: heap_free(cmdstr); close_si_handles(); exec_exit(-1); return (-1); }
void nt_execve_wrapped(char *prog, char**args, char**envir ) { STARTUPINFO si; PROCESS_INFORMATION pi; BOOL bRet; DWORD type=0; char *argv0; char **savedargs = args; unsigned int cmdsize,cmdlen; char *cmdstr ,*cmdend; // int rc=0; // unused variable int retries=0; int is_winnt; int hasdot=0; char myself[512]; memset(&si,0,sizeof(si)); /* * This memory is not freed because we are exec()ed and will * not be alive long. */ /* This version avoids realloc in concat_args_and_quote, so it should be a little bit safer */ /* cmdsize = 65500; * cmdstr= heap_alloc(cmdsize); */ cmdsize = MAX_PATH << 2; cmdstr= heap_alloc(MAX_PATH<<2); is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); /* replace /bin/sh with myself to be executed */ if( strcmp(prog, "/bin/sh") == 0 ) { if (GetModuleFileName(GetModuleHandle(NULL),myself,512) <= 512) { prog = myself; } } cmdlen = copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); cmdend = cmdstr + cmdlen; *cmdend = 0; if (!is_winnt) { argv0 = NULL; goto win95_directly_here; } else { argv0 = heap_alloc(MAX_PATH); wsprintf(argv0,"%s",prog); } retry: bRet=GetBinaryType(argv0,&type); if (is_winnt && !bRet ) { /* Don't append .EXE if it could be a script file */ if (GetLastError() == ERROR_BAD_EXE_FORMAT) { try_shell_ex(args,1); errno = ENOEXEC; return; } else if (retries) { /* If argv[0] got parsed as \\foo (stupid paths with '/' as one * of the components will do it,) and if argv[1] is not the same, * then this is not a real UNC name. * In other cases, argv[0] and argv[1] here must be the same * anyway. -amol 5/1/6/98 */ if ( ( (*prog == '\\') ||(*prog == '/') ) && ( (prog[1] == '\\') ||(prog[1] == '/') ) && ((*args[0] == *prog) && (args[0][1] == prog[1])) && (!args[1]) ) try_shell_ex(args,1); errno = ENOENT; } if (retries > 2) { return; } if (retries == 0) { wsprintf(argv0,"%s.EXE",prog); retries++; } else if (prog[0] == '\\' && retries == 1) { char ptr[80]; if(GetEnvironmentVariable("ZSHROOT",ptr,80)) { wsprintf(argv0,"%s%s",ptr,prog); } retries++; } else if (prog[0] == '\\' && retries == 2) { char ptr[80]; if(GetEnvironmentVariable("ZSHROOT",ptr,80)) { wsprintf(argv0,"%s%s.EXE",ptr,prog); } retries++; } else retries += 2; goto retry; } else if (bRet && retries > 0) { //re-fix argv0 cmdlen = copy_quote_and_fix_slashes(argv0,cmdstr,&hasdot); cmdend = cmdstr + cmdlen; *cmdend = 0; } win95_directly_here: si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = (HANDLE)_get_osfhandle(0); si.hStdOutput = (HANDLE)_get_osfhandle(1); si.hStdError = (HANDLE)_get_osfhandle(2); *args++; // ignore argv[0]; concat_args_and_quote(args,&cmdstr,&cmdlen,&cmdend,&cmdsize); *cmdend = 0; if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) { if (!SetConsoleCtrlHandler(NULL,FALSE)) { errno = ENOENT; } } fix_path_for_child(); if (cmdlen < 1000) dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr); if (!CreateProcess(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles 0, NULL,//envcrap, NULL, &si, &pi) ) { if (GetLastError() == ERROR_BAD_EXE_FORMAT) { try_shell_ex(savedargs,1); errno = ENOEXEC; } else if (GetLastError() == ERROR_INVALID_PARAMETER) { /* exceeded command line */ errno = ENAMETOOLONG; } else errno = ENOENT; } else { errno= 0; // { DWORD exitcode=0; int gui_app = 0; if (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS) { SetConsoleCtrlHandler(NULL,TRUE); } if (isset(WINNTWAITFORGUIAPPS)) gui_app = 0; else if (is_winnt) gui_app = is_gui(argv0); else gui_app = is_9x_gui(prog); if (!gui_app) { WaitForSingleObject(pi.hProcess,INFINITE); } (void)GetExitCodeProcess(pi.hProcess,&exitcode); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); ExitProcess(exitcode); } } }
bool CReadDebugData::Read(TCHAR* pchPEFileName) { DWORD dwBinType = 0; //判断是否为32位可执行文件 if((!GetBinaryType(pchPEFileName,&dwBinType)) || (dwBinType != SCS_32BIT_BINARY)) { return false; } CPeFile peFile; peFile.SetFileName(pchPEFileName); if(!peFile.LoadFile())//加载PE文件 { return false; } PIMAGE_FILE_HEADER pFH=NULL; PIMAGE_SECTION_HEADER pSH=NULL; PIMAGE_OPTIONAL_HEADER pOH=NULL; pFH = peFile.GetFileHeader(); pOH = peFile.GetOptionalHeader(); pSH = peFile.GetFirstSectionHeader(); m_strarrSourceFileNameList.RemoveAll(); m_debugDataItemLine.ClearList(); bool bResult = false; for(int i=0;i<pFH->NumberOfSections;i++) { //如果段具有可执行属性则说明是代码段 if((pSH->Characteristics & IMAGE_SCN_MEM_EXECUTE) == IMAGE_SCN_MEM_EXECUTE) { m_uiCodeSegmentAddr = pOH->ImageBase + pSH->VirtualAddress; m_uiCodeSegmentLength = pSH->SizeOfRawData; } //如果是数据段 else if(strcmp((char*)pSH->Name,".data") == 0) { m_uiDataSegmentAddr = pOH->ImageBase + pSH->VirtualAddress; m_uiDataSegmentLength = pSH->SizeOfRawData; } //如果是调试段 else if(strcmp((char*)pSH->Name,".odebug") == 0) { unsigned char *pSectionData = (unsigned char*)(pSH->PointerToRawData + (unsigned char*)peFile.m_stMapFile.ImageBase); unsigned char *pSectionDataStart = pSectionData; //如果在调试段数据范围内且最开始的两个字节是"OD"标识则表示是合法的调试数据 while((pSectionData < pSectionDataStart+pSH->SizeOfRawData) && (pSectionData[0] == 'O') && (pSectionData[1] == 'D')) { pSectionData += 2; unsigned short usSourceFileNameCount = *(unsigned short*)pSectionData; pSectionData += sizeof(unsigned short); int* pIndexArray = new int[usSourceFileNameCount]; if(pIndexArray) { //读取源代码文件名 CString strSourceFileName; for(unsigned short i=0;i<usSourceFileNameCount;++i) { strSourceFileName = (char*)pSectionData; pIndexArray[i] = SearchSourceFileNameList(strSourceFileName); if(pIndexArray[i] < 0)//没有搜索到 { m_strarrSourceFileNameList.Add(strSourceFileName); pIndexArray[i] = m_strarrSourceFileNameList.GetCount() - 1; } pSectionData += strlen((char*)pSectionData); pSectionData ++; } //读取调试数据项 unsigned long usDebugItemCount = *(unsigned long*)pSectionData; pSectionData += sizeof(unsigned long); for(unsigned long i=0;i<usDebugItemCount;++i) { unsigned short usDebugItemType = *(unsigned short*)pSectionData; pSectionData += sizeof(unsigned short); switch(usDebugItemType) { //行数据 case DEBUG_NODE_TYPE_LINE: { DEBUG_DATA_ITEM_LINE debug_data_item_line; debug_data_item_line.m_usFileIndex = *(unsigned short*)pSectionData; if( (debug_data_item_line.m_usFileIndex >= 0) && (debug_data_item_line.m_usFileIndex < usSourceFileNameCount)) { debug_data_item_line.m_usFileIndex = pIndexArray[debug_data_item_line.m_usFileIndex]; pSectionData += sizeof(unsigned short); debug_data_item_line.m_lLine = *(long*)pSectionData; debug_data_item_line.m_lLine --; //实际的行号与得到的行号差1 pSectionData += sizeof(long); debug_data_item_line.m_ulAddr = *(unsigned long*)pSectionData; pSectionData += sizeof(unsigned long); m_debugDataItemLine.Add(debug_data_item_line); } break; } } } delete[] pIndexArray; } } bResult = true; } pSH++; } //peFile.UnLoadFile(); return bResult; }
void nt_execve(char *prog, char**args, char**envir ) { STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE htemp; BOOL bRet; DWORD type=0; DWORD dwCreationflags; unsigned int priority; char *argv0; char *cmdstr, *cmdend ; char *originalPtr; unsigned int cmdsize,cmdlen; char *p2; char **savedargs; int retries=0; int hasdot =0; int is_winnt ; memset(&si,0,sizeof(si)); savedargs = args; /* * This memory is not freed because we are exec()ed and will * not be alive long. */ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2); is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); cmdsize = MAX_PATH<<2; p2 = cmdstr; cmdlen = 0; cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); p2 += cmdlen; /* If the command was not quoted , skip initial character we left for quote */ if (*cmdstr != '"') { *cmdstr = 'A'; cmdstr++; cmdsize--; } *p2 = 0; cmdend = p2; if (!is_winnt){ argv0 = NULL; goto win95_directly_here; } else { argv0 = heap_alloc(MAX_PATH); /* not freed */ wsprintf(argv0,"%s",prog); } retry: bRet=GetBinaryType(argv0,&type); dprintf("binary type for %s is %d\n",argv0,bRet); // // For NT, append .EXE and retry // if (is_winnt && !bRet ) { /* Don't append .EXE if it could be a script file */ if (GetLastError() == ERROR_BAD_EXE_FORMAT){ errno = ENOEXEC; if (!__nt_only_start_exes) try_shell_ex(args,1,FALSE); //can't throw on error return; } else if ( retries ){ if ( ( (argv0[0] == '\\') ||(argv0[0] == '/') ) && ( (argv0[1] == '\\') ||(argv0[1] == '/') ) && (!args[1]) ) if (!__nt_only_start_exes) try_shell_ex(args,1,FALSE); errno = ENOENT; } if (retries > 1){ return; } // Try uppercase once and then lower case // if (!retries) wsprintf(argv0,"%s.exe",prog); else wsprintf(argv0,"%s.EXE",prog); /* fix for clearcase */ retries++; goto retry; } win95_directly_here: si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; htemp= (HANDLE)_get_osfhandle(0); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(1); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(2); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS); *args++; // the first arg is the command dprintf("nt_execve calling c_a_a_q"); if(!concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend, &cmdsize)) { dprintf("concat_args_and_quote failed\n"); heap_free(originalPtr); errno = ENOMEM; goto fail_return; } *cmdend = 0; dwCreationflags = GetPriorityClass(GetCurrentProcess()); if (__nt_child_nohupped) { dwCreationflags |= DETACHED_PROCESS; } priority = GetThreadPriority(GetCurrentThread()); (void)fix_path_for_child(); if (is_winnt) dwCreationflags |= CREATE_SUSPENDED; re_cp: dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr); bRet = CreateProcessA(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles dwCreationflags, NULL, NULL, &si, &pi); if (!bRet){ if (GetLastError() == ERROR_BAD_EXE_FORMAT) { if (!__nt_only_start_exes) try_shell_ex(savedargs,1,FALSE); errno = ENOEXEC; } else if (GetLastError() == ERROR_INVALID_PARAMETER) { /* can't get invalid parameter, so this must be * the case when we exceed the command length limit. */ errno = ENAMETOOLONG; } else { errno = ENOENT; } if (!is_winnt && !hasdot) { //append '.' to the end if needed lstrcat(cmdstr,"."); hasdot=1; goto re_cp; } } else{ int gui_app ; char guivar[50]; if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50)) gui_app=0; else { if (is_winnt || hasdot) gui_app= is_gui(argv0); else gui_app = is_9x_gui(prog); } if (is_winnt && !SetThreadPriority(pi.hThread,priority) ) { priority =GetLastError(); } if (is_winnt) ResumeThread(pi.hThread); errno= 0; if (__nt_really_exec||__nt_child_nohupped || gui_app){ ExitProcess(0); } else { DWORD exitcode=0; WaitForSingleObject(pi.hProcess,INFINITE); (void)GetExitCodeProcess(pi.hProcess,&exitcode); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); /* * If output was redirected to /dev/clipboard, * we need to close the pipe handles */ if (is_dev_clipboard_active) { CloseHandle((HANDLE)_get_osfhandle(0)); CloseHandle((HANDLE)_get_osfhandle(1)); CloseHandle((HANDLE)_get_osfhandle(2)); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); WaitForSingleObject(ghdevclipthread,60*1000); } ExitProcess(exitcode); } } fail_return: CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); return; }
// // Do checking of the .exe type in the background so the UI doesn't // get hung up while we scan. This is particularly important with // the .exe is over the network or on a floppy. // void CheckRunInSeparateThread( LPVOID lpVoid ) { LONG lBinaryType; DWORD cch; LPTSTR lpszFilePart; TCHAR szFile[MAX_PATH+1]; TCHAR szFullFile[MAX_PATH+1]; TCHAR szExp[MAX_PATH+1]; HWND hDlg = (HWND)lpVoid; BOOL fCheck = TRUE, fEnable = FALSE; DebugMsg( DM_TRACE, TEXT("CheckRunInSeparateThread created and running") ); while( g_bCheckRunInSep ) { WaitForSingleObject( g_hCheckNow, INFINITE ); ResetEvent( g_hCheckNow ); if (g_bCheckRunInSep) { LPRUNDLG_DATA lprd; LPTSTR pszT; BOOL f16bit = FALSE; szFile[0] = TEXT('\0'); szFullFile[0] = TEXT('\0'); cch = 0; GetWindowText( GetDlgItem( hDlg, IDD_COMMAND ), szFile, MAX_PATH ); // Remove & throw away arguments PathRemoveBlanks(szFile); if (PathIsUNC(szFile) || IsRemoteDrive(DRIVEID(szFile))) { f16bit = TRUE; fCheck = FALSE; fEnable = TRUE; goto ChangeTheBox; } // if the unquoted sting exists as a file just use it if (!PathFileExists(szFile)) { pszT = PathGetArgs(szFile); if (*pszT) *(pszT - 1) = TEXT('\0'); PathUnquoteSpaces(szFile); } if (szFile[0]) { ExpandEnvironmentStrings( szFile, szExp, MAX_PATH ); szExp[ MAX_PATH ] = TEXT('\0'); if (PathIsUNC(szExp) || IsRemoteDrive(DRIVEID(szExp))) { f16bit = TRUE; fCheck = FALSE; fEnable = TRUE; goto ChangeTheBox; } cch = SearchPath( NULL, szExp, TEXT(".EXE"), MAX_PATH+1, szFullFile, &lpszFilePart ); } if ((cch != 0) && (cch <= MAX_PATH)) { if ( (GetBinaryType( szFullFile, &lBinaryType) && (lBinaryType==SCS_WOW_BINARY)) ) { f16bit = TRUE; fCheck = FALSE; fEnable = TRUE; } else { f16bit = FALSE; fCheck = TRUE; fEnable = FALSE; } } else { f16bit = FALSE; fCheck = TRUE; fEnable = FALSE; } ChangeTheBox: CheckDlgButton( hDlg, IDD_RUNINSEPARATE, fCheck ? 1 : 0 ); EnableWindow( GetDlgItem( hDlg, IDD_RUNINSEPARATE ), fEnable ); ENTERCRITICAL; lprd = (LPRUNDLG_DATA)GetWindowLong(hDlg, DWL_USER); if (lprd) { if (f16bit) lprd->dwFlags |= RFD_WOW_APP; else lprd->dwFlags &= (~RFD_WOW_APP); } LEAVECRITICAL; } } CloseHandle( g_hCheckNow ); g_hCheckNow = NULL; DebugMsg( DM_TRACE, TEXT("CheckRunInSeparateThread exiting now...") ); ExitThread( 0 ); }
BOOL SheConvertPathW( LPWSTR lpCmdLine, LPWSTR lpFile, UINT cchCmdBuf) /*++ Routine Description: Takes a command line and file and shortens both if the app in the command line is dos/wow. Returns: BOOL T=converted Arguments: INOUT lpCmdLine Command line to test exe must be in DQuotes if it has spaces, on return, will have DQuotes if necessary INOUT lpFile Fully qualified file to shorten May be in DQuotes, but on return will not have DQuotes (since single file) IN cchCmdBuf Size of buffer in characters Return Value: VOID, but lpFile shortened (in place) if lpCmdLine is dos/wow. There are pathalogoical "lfns" (Single unicode chars) that can actually get longer when they are shortened. In this case, we won't AV, but we will truncate the parms! // Qualify path assumes that the second parm is a buffer of // size atleast CBCOMMAND, which is nicely equivalent to MAX_PATH // needs cleanup! --*/ { LPWSTR lpszFullPath; LONG lBinaryType; BOOL bInQuote = FALSE; LPWSTR lpArgs; UINT cchNewLen; BOOL bRetVal = FALSE; lpszFullPath = (LPWSTR) LocalAlloc(LMEM_FIXED, cchCmdBuf*sizeof(*lpCmdLine)); if (!lpszFullPath) return bRetVal; // // We must do the swap here since we need to copy the // parms back to lpCmdLine. // lstrcpy(lpszFullPath, lpCmdLine); if (QualifyAppName(lpszFullPath, lpCmdLine, &lpArgs)) { if (!GetBinaryType(lpCmdLine, &lBinaryType) || lBinaryType == SCS_DOS_BINARY || lBinaryType == SCS_WOW_BINARY) { SheShortenPath(lpCmdLine, TRUE); if (lpFile) { SheShortenPath(lpFile, TRUE); } bRetVal = TRUE; } // // Must readd quotes // CheckEscapes(lpCmdLine, cchCmdBuf); cchNewLen = lstrlen(lpCmdLine); StrNCpy(lpCmdLine+cchNewLen, lpArgs, cchCmdBuf-cchNewLen); } else { // // QualifyAppName failed, restore the command line back // to the original state. // lstrcpy(lpCmdLine, lpszFullPath); } LocalFree((HLOCAL)lpszFullPath); return bRetVal; }
int nt_texec(char *prog, char**args ) { STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE htemp; DWORD type=0; DWORD dwCreationflags; unsigned int priority; char *argv0 = NULL, *savepath = NULL; char *cmdstr,*cmdend ; char *originalPtr = NULL; unsigned int cmdsize,cmdlen; char *p2; char **savedargs; int retries=0; int hasdot =0; int is_winnt=0; int retval = 1; memset(&si,0,sizeof(si)); savedargs = args; /* MUST FREE !! */ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2); cmdsize = MAX_PATH<<2; is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); p2 = cmdstr; cmdlen = 0; cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); p2 += cmdlen; if (*cmdstr != '"') { // If not quoted, skip initial character we left for quote *cmdstr = 'A'; cmdstr++; cmdsize--; } *p2 = 0; cmdend = p2; if (!is_winnt) { argv0 = NULL; } else { argv0= heap_alloc(MAX_PATH); (void)StringCbPrintf(argv0,MAX_PATH,"%s",prog); } si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; htemp= (HANDLE)_get_osfhandle(SHIN); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(SHOUT); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS); htemp= (HANDLE)_get_osfhandle(SHDIAG); DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS); /* quotespace hack needed since execv() would have separated args, but createproces doesnt -amol 9/14/96 */ args++; // the first arg is the command dprintf("nt_texec calling c_a_a_q"); if(concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend,&cmdsize) == NULL) { retval = 1; errno = ENOMEM; heap_free(originalPtr); goto free_mem; } *cmdend = 0; dwCreationflags = GetPriorityClass(GetCurrentProcess()); priority = GetThreadPriority(GetCurrentThread()); if (is_winnt) { retries = 0; // For NT, try ShellExecuteEx first do { if (GetBinaryType(argv0,&type)) break; if (GetLastError() == ERROR_BAD_EXE_FORMAT){ errno = ENOEXEC; if (!__nt_only_start_exes) try_shell_ex(savedargs,0,FALSE); if (errno) { retval = 1; goto free_mem; } else { retval = 0; goto free_mem; } } // only try shellex again after appending ".exe fails else if ( retries > 1 ){ if ( ( (argv0[0] == '\\') ||(argv0[0] == '/') ) && ( (argv0[1] == '\\') ||(argv0[1] == '/') ) && (!args[1]) ) if (!__nt_only_start_exes) try_shell_ex(savedargs,0,FALSE); errno = ENOENT; } if (retries == 0) (void)StringCbPrintf(argv0,MAX_PATH,"%s.exe",prog); else if (retries == 1) { (void)StringCbPrintf(argv0,MAX_PATH,"%s.EXE",prog); } retries++; }while(retries < 3); } savepath = fix_path_for_child(); re_cp: dprintf("nt_texec cmdstr %s\n",cmdstr); if (!CreateProcess(argv0, cmdstr, NULL, NULL, TRUE, // need this for redirecting std handles dwCreationflags, NULL,//envcrap, NULL, &si, &pi) ){ if (GetLastError() == ERROR_BAD_EXE_FORMAT) { errno = ENOEXEC; } else if (GetLastError() == ERROR_INVALID_PARAMETER) { errno = ENAMETOOLONG; }else { errno = ENOENT; } if (!is_winnt && !hasdot) { //append '.' to the end if needed StringCbCat(cmdstr,cmdsize,"."); hasdot=1; goto re_cp; } retval = 1; } else{ int gui_app ; DWORD exitcode; char guivar[50]; if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50)) gui_app=0; else gui_app= is_gui(argv0); if(!gui_app) { WaitForSingleObject(pi.hProcess,INFINITE); (void)GetExitCodeProcess(pi.hProcess,&exitcode); setv(STRstatus, putn(exitcode), VAR_READWRITE);/*FIXRESET*/ } retval = 0; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } free_mem: CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); if(savepath) restore_path(savepath); heap_free(originalPtr); if (argv0) heap_free(argv0); return retval; }