Blame | Last modification | View Log | RSS feed
/*============================================================================** COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.**============================================================================**** Project/Product : JATS ( core)devl)** Filename : gunzip.cpp** Author(s) : dpurdie** Created : 08-Mar-18**** Description : Implement gunzip by invoking gzip with a -d option****** Information :** Compiler : ANSI C++** Target :*****==========================================================================*/////#include "stdafx.h"#include <Windows.h>#include <string>#include <iostream>using namespace std;/*----------------------------------------------------------------------------** FUNCTION : ArgvQuote**** DESCRIPTION : Append an argument to a string with correct** quoting for passing as a command line argumentThis routine appends the given argument to a command line suchthat CommandLineToArgvW will return the argument string unchanged.Arguments in a command line should be separated by spaces; thisfunction does not add these spaces.**** INPUTS : Argument - Supplies the argument to encode** CommandLine - Append to this string** Force - True: Force quotes**** RETURNS : Nothing**----------------------------------------------------------------------------*/void ArgvQuote( const std::wstring& Argument,std::wstring& CommandLine, bool Force ){//// Unless we're told otherwise, don't quote unless we actually// need to do so --- hopefully avoid problems if programs won't// parse quotes properly//if (Force == false &&Argument.empty() == false &&Argument.find_first_of(L" \t\n\v\"") == Argument.npos){CommandLine.append(Argument);}else {CommandLine.append(L"\"");for (std::wstring::const_iterator It = Argument.begin(); ; ++It) {unsigned NumberBackslashes = 0;while (It != Argument.end() && *It == L'\\') {++It;++NumberBackslashes;}if (It == Argument.end()) {//// Escape all backslashes, but let the terminating// double quotation mark we add below be interpreted// as a metacharacter.//CommandLine.append(NumberBackslashes * 2, L'\\');break;}else if (*It == L'"') {//// Escape all backslashes and the following// double quotation mark.//CommandLine.append(NumberBackslashes * 2 + 1, L'\\');CommandLine.append(1, *It);}else {//// Backslashes aren't special here.//CommandLine.append(NumberBackslashes, L'\\');CommandLine.append(1, *It);}}CommandLine.append(L"\"");}}/*----------------------------------------------------------------------------** FUNCTION : s2ws**** DESCRIPTION : String to Wide String****** INPUTS : str - std:string**** RETURNS : A widestring**----------------------------------------------------------------------------*/std::wstring s2ws(const std::string& str){int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);std::wstring wstrTo(size_needed, 0);MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);return wstrTo;}/*----------------------------------------------------------------------------** FUNCTION : main**** DESCRIPTION : Invoke gzip with a '-d' option****** INPUTS : As per gzip**** RETURNS : Exit code of the gzip utility**----------------------------------------------------------------------------*/int main(int argc, char** argv){BOOL rv;//// Replace gunzip.exe with gzip.exe -d//// Retrieve the command line arguments as an array of pointers to strings// First string will be the program path//// Remove program name - keep path// Assume we will find the gzip in the same location us this program or via the same path mechanism// Handle aaaa\bbbb\cccc// aaaa/bbbb/ccccc// cccc//std::wstring arg = s2ws(argv[0]);int index = arg.find_last_of(L"\\", arg.size());if (index == std::string::npos) {index = arg.find_last_of(L"/", arg.size());if (index == std::string::npos) {index = -1;}}arg.erase(index + 1);arg.append(L"gzip.exe");//// Convert the arglist into a fully quoted command line string// Inserting a '-d' option//std::wstring args = wstring();ArgvQuote(arg, args, FALSE);args.append(L" ");ArgvQuote(L"-d", args, FALSE);for (int ii = 1; ii < argc; ii++) {args.append(L" ");ArgvQuote(s2ws(argv[ii]), args, FALSE);}//std::wcout << L"Cmd:" << args << std::endl;// additional informationSTARTUPINFO si;PROCESS_INFORMATION pi;DWORD exitStatus = 250;// set the size of the structuresZeroMemory(&si, sizeof(si));ZeroMemory(&pi, sizeof(pi));// start the program uprv = CreateProcess(NULL, // the path(LPWSTR)args.c_str(), // Command lineNULL, // Process handle not inheritableNULL, // Thread handle not inheritableTRUE, // Set handle inheritance to TRUE0, // Opens file in a separate consoleNULL, // Use parent's environment blockNULL, // Use parent's starting directory&si, // Pointer to STARTUPINFO structure&pi // Pointer to PROCESS_INFORMATION structure);if (!rv) {DWORD eCode = GetLastError();exitStatus = eCode;//std::wcout << L"CreateProcess Error:" << eCode << std::endl;return exitStatus;}// Close process and thread handles.WaitForSingleObject(pi.hProcess, INFINITE);rv = GetExitCodeProcess(pi.hProcess, &exitStatus);if (!rv) {DWORD eCode = GetLastError();//std::wcout << L"GetExitCodeProcess Error:" << eCode << std::endl;exitStatus = 248;}CloseHandle(pi.hProcess);CloseHandle(pi.hThread);//std::wcout << L"Exit Status:" << exitStatus << std::endl;return exitStatus;}