bool ChildData::restoreEnvironment() { TCHAR buf[1024]; for (int i=0; i<environmentLength; i++) { ts_strcpy(buf, environment[i].name); ts_strcat(buf, "="); ts_strcat(buf, environment[i].value); //JMW _tputenv(buf); } return true; }
int stat(const char* filename, struct stat* st) { if (filename == NULL || st == NULL) { errno = EINVAL; return -1; } TCHAR filenameT[1000]; ts_strcpy(filenameT, filename); WIN32_FILE_ATTRIBUTE_DATA fad; if (!GetFileAttributesEx(filenameT, GetFileExInfoStandard, (LPVOID)&fad)) { errno = ENOENT; return -1; } st->st_dev = 0; st->st_ino = 0; st->st_mode = 0; if (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { st->st_mode |= _S_IFDIR; st->st_mode |= _S_IEXEC; // search permission } else { st->st_mode |= _S_IFREG; if (strlen(filename) >= 4 && _stricmp(filename+strlen(filename)-4, ".exe") == 0) st->st_mode |= _S_IEXEC; // execute permission } st->st_mode |= _S_IREAD; // TODO: assuming readable, but this may not be the case if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) st->st_mode |= _S_IWRITE; st->st_nlink = 1; // TODO: NTFS can have links, so get the correct value st->st_uid = 0; st->st_gid = 0; st->st_rdev = 0; st->st_size = fad.nFileSizeLow; /* JMW don't need this? TODO st->st_atime = w32_filetime_to_time_t(&fad.ftLastAccessTime); st->st_mtime = w32_filetime_to_time_t(&fad.ftLastWriteTime); st->st_ctime = w32_filetime_to_time_t(&fad.ftCreationTime); */ return 0; }
bool ChildData::addEnvironmentVar(WCHAR* env) { bool result = false; WCHAR* equals; int nameLen; TCHAR* name = NULL; TCHAR* value = NULL; equals = wcschr(env, L'='); if (equals == NULL) goto cleanup; nameLen = equals - env; if (nameLen == 0) goto cleanup; name = (TCHAR*)malloc((nameLen+1)*sizeof(TCHAR)); if (name == NULL) goto cleanup; ts_strncpy(name, env, nameLen); name[nameLen] = '\0'; value = (TCHAR*)malloc((ts_strlen(equals+1)+1)*sizeof(TCHAR)); if (value == NULL) goto cleanup; ts_strcpy(value, equals+1); environment = (NameValuePair*)realloc(environment, (environmentLength+1)*sizeof(NameValuePair)); if (environment == NULL) goto cleanup; environment[environmentLength].name = name; environment[environmentLength].value = value; environmentLength++; result = true; cleanup: if (result == false) { if (name != NULL) free(name); if (value != NULL) free(value); } return result; }
// if childData is NULL, the size will be returned in childDataLen bool ChildData::encode(void* childData, int* childDataSize) { int currentDirectorySize = (currentDirectory == NULL) ? sizeof(WCHAR) : ts_strsizez(currentDirectory); int redirSize = 0; for (int i=0; i<numRedirArgs; i++) { redirSize += sizeof(DWORD) + sizeof(DWORD) + sizeof(DWORD); if (redirArgs[i].redirType == RT_PIPE_UNSPEC || redirArgs[i].redirType == RT_PIPE_STDIN || redirArgs[i].redirType == RT_PIPE_STDOUT || redirArgs[i].redirType == RT_PIPE_STDERR || redirArgs[i].redirType == RT_FILE) { if (redirArgs[i].filename != NULL) redirSize += ts_strsizez(redirArgs[i].filename); } } DWORD envSize = 0; if (environment != NULL) { for (int i=0; i<environmentLength; i++) envSize += (_tcslen(environment[i].name) + 1 + _tcslen(environment[i].value) + 1) * sizeof(WCHAR); envSize += sizeof(WCHAR); // list termination } int totalSize = 0; totalSize += sizeof(DWORD); // length totalSize += sizeof(DWORD); // reserved totalSize += currentDirectorySize; // current directory totalSize += sizeof(DWORD); // number of redirs totalSize += redirSize; // redirs totalSize += sizeof(DWORD); // environment length totalSize += envSize; // environment variable list if (childDataSize != NULL) *childDataSize = totalSize; if (childData != NULL) { char* p = (char*)childData; // total size memcpy(p, &totalSize, sizeof(DWORD)); //*(DWORD*)p = totalSize; p += sizeof(DWORD); // reserved { DWORD reserved = 0; memcpy(p, &reserved, sizeof(DWORD)); //*(DWORD*)p = 0; p += sizeof(DWORD); } // current directory if (currentDirectory == NULL) { WCHAR zero = '\0'; *p = '\0'; memcpy(p, &zero, sizeof(WCHAR)); //*p = '\0'; p += sizeof(WCHAR); } else { ts_strcpy((WCHAR*)p, currentDirectory); p += (ts_strlen((WCHAR*)p) + 1) * 2; } // num redirs memcpy(p, &numRedirArgs, sizeof(DWORD)); //*(DWORD*)p = numRedirArgs; p += sizeof(DWORD); // redirs for (int i=0; i<numRedirArgs; i++) { // determine if filename is present bool filenamePresent = false; if (redirArgs[i].redirType == RT_PIPE_UNSPEC || redirArgs[i].redirType == RT_PIPE_STDIN || redirArgs[i].redirType == RT_PIPE_STDOUT || redirArgs[i].redirType == RT_PIPE_STDERR || redirArgs[i].redirType == RT_FILE) { if (redirArgs[i].filename != NULL) filenamePresent = true; } // flags DWORD flags = 0; if (redirArgs[i].redirType == RT_FILE) flags |= 0x00000001; else if (redirArgs[i].redirType == RT_HANDLE) flags |= 0x00000002; if (filenamePresent) flags |= 0x00000004; if (redirArgs[i].append) flags |= 0x00000008; if (redirArgs[i].openForRead) flags |= 0x00000010; if (redirArgs[i].openForWrite) flags |= 0x00000020; memcpy(p, &flags, sizeof(DWORD)); //*(DWORD*)p = flags; p += sizeof(DWORD); // fd memcpy(p, &redirArgs[i].fd, sizeof(DWORD)); //*(DWORD*)p = redirArgs[i].fd; p += sizeof(DWORD); // fd2 memcpy(p, &redirArgs[i].fd2, sizeof(DWORD)); //*(DWORD*)p = redirArgs[i].fd2; p += sizeof(DWORD); // pipe/file name if (filenamePresent) { ts_strcpy((WCHAR*)p, redirArgs[i].filename); p += (ts_strlen((WCHAR*)p) + 1) * 2; } } // environment size memcpy(p, &envSize, sizeof(DWORD)); //*(DWORD*)p = ENVIRONMENTLENGTH * 2; p += sizeof(DWORD); // environment if (envSize != 0) { for (int i=0; i<environmentLength; i++) { ts_strcpy((WCHAR*)p, environment[i].name); p += ts_strlen((WCHAR*)p) * sizeof(WCHAR); ts_strcpy((WCHAR*)p, L"="); p += sizeof(WCHAR); ts_strcpy((WCHAR*)p, environment[i].value); p += (ts_strlen((WCHAR*)p) + 1) * sizeof(WCHAR); } // terminate the environment list WCHAR zero = '\0'; memcpy(p, &zero, sizeof(WCHAR)); //*p = '\0'; p += sizeof(WCHAR); } } return true; }
// generate argc/argv from program name and lpCmdLine // returns 0 on failure, or argc on success int processCmdLine(LPTSTR lpCmdLine, char*** pArgv) { BOOL success = FALSE; int argc = 0; char** argv = NULL; TCHAR programName[1024]; const int maxArgChars = 1024; TCHAR argW[maxArgChars]; char arg[maxArgChars]; ArgType argType; // get program name if (GetModuleFileName(NULL, programName, 1024) <= 0) goto cleanup; programName[1023] = 0; // make sure it's terminated when result is truncated // add program name to args argc++; argv = (char**)realloc(argv, argc*sizeof(char*)); if (argv == NULL) goto cleanup; argv[argc-1] = (char*)malloc((wcslen(programName)+1)*2); if (argv[argc-1] == NULL) goto cleanup; unicode2ascii(programName, argv[argc-1], wcslen(programName)+1); while ((argType = getCmdLineArg(&lpCmdLine, argW, maxArgChars, NULL, NULL)) > 0) { ts_strcpy(arg, argW); // convert to unicode (if we're in unicode) if (argType == TOK_STRING) { HANDLE findHandle; char* expandedArg; if ((strchr(arg,'*')==NULL && strchr(arg,'?')==NULL) || !wildcardFindFirst(arg, &findHandle, &expandedArg)) { // not a wildcard, or is but doesn't match anything, so just add arg to argv argc++; argv = (char**)realloc(argv, argc*sizeof(char*)); if (argv == NULL) goto cleanup; argv[argc-1] = (char*)malloc(strlen(arg)+1); if (argv[argc-1] == NULL) goto cleanup; strcpy(argv[argc-1], arg); } else { // handle wildcards int firstExpandedArgIndex = argc; int lastExpandedArgIndex = argc; int numPathCharsToCopyFromArg = 0; char* lastSlash = max(strrchr(arg,'\\'), strrchr(arg,'/')); if (lastSlash != NULL) numPathCharsToCopyFromArg = lastSlash - arg + 1; do { argc++; argv = (char**)realloc(argv, argc*sizeof(char*)); if (argv == NULL) { free(expandedArg); goto cleanup; } if (numPathCharsToCopyFromArg == 0) argv[argc-1] = expandedArg; else { argv[argc-1] = (char*)malloc(numPathCharsToCopyFromArg + strlen(expandedArg) + 1); if (argv[argc-1] == NULL) goto cleanup; strncpy(argv[argc-1], arg, numPathCharsToCopyFromArg); strcpy(argv[argc-1]+numPathCharsToCopyFromArg, expandedArg); } lastExpandedArgIndex = argc-1; } while (wildcardFindNext(findHandle, &expandedArg)); qsort(&argv[firstExpandedArgIndex], lastExpandedArgIndex-firstExpandedArgIndex+1, sizeof(char*), qsort_stricmp); } } } // success success = TRUE; cleanup: if (!success) { if (argv != NULL) { int i; for (i=0; i<argc; i++) free(argv[i]); free(argv); } argc = 0; } else *pArgv = argv; return argc; }