Skip to main content
added 251 characters in body
Source Link
jdt
  • 2.4k
  • 5
  • 20
#include <windows.h> 
#include <stdio.h>

#define MAX_CMDLINE 8191 
#define BUFFER_SIZE 4096

BOOL executeAndGetResults(LPCSTR currentDirectory, LPCSTR applicationName, LPCSTR commandLine, LPSTR buffer, DWORD buflen, DWORD* exitCode)
{
    BOOL ok = TRUE;
    HANDLE stdInPipeRead = NULL;
    HANDLE stdInPipeWrite = NULL;
    HANDLE stdOutPipeRead = NULL;
    HANDLE stdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    if (!CreatePipe(&stdInPipeRead, &stdInPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create input pipes\n");
        return FALSE;
    }

    if (!CreatePipe(&stdOutPipeRead, &stdOutPipeWrite, &sa, 0))
    {
        CloseHandle(stdInPipeRead);
        CloseHandle(stdInPipeWrite);
        fprintf(stderr, "Failed to create output pipes\n");
        return FALSE;
    }

    // copy command line to non-constant string
    char commandLineCopy[MAX_CMDLINE];
    strcpy_s(commandLineCopy, MAX_CMDLINE, commandLine);

    // Create the process.
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = stdOutPipeWrite;
    si.hStdOutput = stdOutPipeWrite;
    si.hStdInput = stdInPipeRead;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    LPSECURITY_ATTRIBUTES processAttributes = NULL;
    LPSECURITY_ATTRIBUTES threadAttribute = NULL;
    BOOL inheritHandles = TRUE;
    DWORD creationFlags = 0;
    LPVOID environment = NULL;
    if (!CreateProcessA(applicationName,
        commandLineCopy,
        processAttributes,
        threadAttribute,
        inheritHandles,
        creationFlags,
        environment,
        currentDirectory,
        &si,
        &pi))
    {
        CloseHandle(stdInPipeRead);
        CloseHandle(stdInPipeWrite);
        CloseHandle(stdOutPipeRead);
        CloseHandle(stdOutPipeWrite);
        fprintf(stderr, "Failed to create process\n");
        return FALSE;
    }

    // Close pipes we do not need.
    CloseHandle(stdOutPipeWrite);
    CloseHandle(stdInPipeRead);

    // The main loop for reading output from the command
    DWORD read = 0;
    char* ptr = buffer;
    while (ReadFile(stdOutPipeRead, ptr, buflen, &read, NULL))
    {
        ptr += read;
        buflen -= read;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(stdOutPipeRead);
    CloseHandle(stdInPipeWrite);
    GetExitCodeProcess(pi.hProcess, exitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return TRUE;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[BUFFER_SIZE + 1];
    DWORD retcode = 0;
    if (!executeAndGetResults(NULL, pingPath, ""ping.exe www.google.com", buffer, BUFFER_SIZE, &retcode))
        return EXIT_FAILURE;

    printf("retcode: [%d]\n", retcode);
    printf("results: [%s]\n", buffer);
}
#include <windows.h> 
#include <stdio.h>

#define MAX_CMDLINE 8191 
#define BUFFER_SIZE 4096

BOOL executeAndGetResults(LPCSTR currentDirectory, LPCSTR applicationName, LPCSTR commandLine, LPSTR buffer, DWORD buflen, DWORD* exitCode)
{
    BOOL ok = TRUE;
    HANDLE stdInPipeRead = NULL;
    HANDLE stdInPipeWrite = NULL;
    HANDLE stdOutPipeRead = NULL;
    HANDLE stdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    if (!CreatePipe(&stdInPipeRead, &stdInPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create input pipes\n");
        return FALSE;
    }

    if (!CreatePipe(&stdOutPipeRead, &stdOutPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create output pipes\n");
        return FALSE;
    }

    // copy command line to non-constant string
    char commandLineCopy[MAX_CMDLINE];
    strcpy_s(commandLineCopy, MAX_CMDLINE, commandLine);

    // Create the process.
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = stdOutPipeWrite;
    si.hStdOutput = stdOutPipeWrite;
    si.hStdInput = stdInPipeRead;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    LPSECURITY_ATTRIBUTES processAttributes = NULL;
    LPSECURITY_ATTRIBUTES threadAttribute = NULL;
    BOOL inheritHandles = TRUE;
    DWORD creationFlags = 0;
    LPVOID environment = NULL;
    if (!CreateProcessA(applicationName,
        commandLineCopy,
        processAttributes,
        threadAttribute,
        inheritHandles,
        creationFlags,
        environment,
        currentDirectory,
        &si,
        &pi))
    {
        fprintf(stderr, "Failed to create process\n");
        return FALSE;
    }

    // Close pipes we do not need.
    CloseHandle(stdOutPipeWrite);
    CloseHandle(stdInPipeRead);

    // The main loop for reading output from the command
    DWORD read = 0;
    char* ptr = buffer;
    while (ReadFile(stdOutPipeRead, ptr, buflen, &read, NULL))
    {
        ptr += read;
        buflen -= read;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(stdOutPipeRead);
    CloseHandle(stdInPipeWrite);
    GetExitCodeProcess(pi.hProcess, exitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return TRUE;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[BUFFER_SIZE + 1];
    DWORD retcode = 0;
    if (!executeAndGetResults(NULL, pingPath, " www.google.com", buffer, BUFFER_SIZE, &retcode))
        return EXIT_FAILURE;

    printf("retcode: [%d]\n", retcode);
    printf("results: [%s]\n", buffer);
}
#include <windows.h> 
#include <stdio.h>

#define MAX_CMDLINE 8191 
#define BUFFER_SIZE 4096

BOOL executeAndGetResults(LPCSTR currentDirectory, LPCSTR applicationName, LPCSTR commandLine, LPSTR buffer, DWORD buflen, DWORD* exitCode)
{
    BOOL ok = TRUE;
    HANDLE stdInPipeRead = NULL;
    HANDLE stdInPipeWrite = NULL;
    HANDLE stdOutPipeRead = NULL;
    HANDLE stdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    if (!CreatePipe(&stdInPipeRead, &stdInPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create input pipes\n");
        return FALSE;
    }

    if (!CreatePipe(&stdOutPipeRead, &stdOutPipeWrite, &sa, 0))
    {
        CloseHandle(stdInPipeRead);
        CloseHandle(stdInPipeWrite);
        fprintf(stderr, "Failed to create output pipes\n");
        return FALSE;
    }

    // copy command line to non-constant string
    char commandLineCopy[MAX_CMDLINE];
    strcpy_s(commandLineCopy, MAX_CMDLINE, commandLine);

    // Create the process.
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = stdOutPipeWrite;
    si.hStdOutput = stdOutPipeWrite;
    si.hStdInput = stdInPipeRead;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    LPSECURITY_ATTRIBUTES processAttributes = NULL;
    LPSECURITY_ATTRIBUTES threadAttribute = NULL;
    BOOL inheritHandles = TRUE;
    DWORD creationFlags = 0;
    LPVOID environment = NULL;
    if (!CreateProcessA(applicationName,
        commandLineCopy,
        processAttributes,
        threadAttribute,
        inheritHandles,
        creationFlags,
        environment,
        currentDirectory,
        &si,
        &pi))
    {
        CloseHandle(stdInPipeRead);
        CloseHandle(stdInPipeWrite);
        CloseHandle(stdOutPipeRead);
        CloseHandle(stdOutPipeWrite);
        fprintf(stderr, "Failed to create process\n");
        return FALSE;
    }

    // Close pipes we do not need.
    CloseHandle(stdOutPipeWrite);
    CloseHandle(stdInPipeRead);

    // The main loop for reading output from the command
    DWORD read = 0;
    char* ptr = buffer;
    while (ReadFile(stdOutPipeRead, ptr, buflen, &read, NULL))
    {
        ptr += read;
        buflen -= read;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(stdOutPipeRead);
    CloseHandle(stdInPipeWrite);
    GetExitCodeProcess(pi.hProcess, exitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return TRUE;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[BUFFER_SIZE + 1];
    DWORD retcode = 0;
    if (!executeAndGetResults(NULL, pingPath, "ping.exe www.google.com", buffer, BUFFER_SIZE, &retcode))
        return EXIT_FAILURE;

    printf("retcode: [%d]\n", retcode);
    printf("results: [%s]\n", buffer);
}
added 411 characters in body
Source Link
jdt
  • 2.4k
  • 5
  • 20

The correct, but rather boring and long and boring, way to do this on Windows is to use CreateProcess. Here is a basic example of how to use it:

#include <windows.h> 
#include <stdio.h>

int#define MAX_CMDLINE 8191 
#define BUFFER_SIZE 4096

BOOL executeAndGetResults(LPCSTR lpCurrentDirectorycurrentDirectory, LPCSTR lpApplicationNameapplicationName, LPCSTR lpCommandLinecommandLine, LPSTR buffer, DWORD buflen, DWORD* exitCode)
{
    BOOL ok = TRUE;
    HANDLE hStdInPipeReadstdInPipeRead = NULL;
    HANDLE hStdInPipeWritestdInPipeWrite = NULL;
    HANDLE hStdOutPipeReadstdOutPipeRead = NULL;
    HANDLE hStdOutPipeWritestdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    ok =if (!CreatePipe(&hStdInPipeRead&stdInPipeRead, &hStdInPipeWrite&stdInPipeWrite, &sa, 0);)
    if{
        fprintf(okstderr, =="Failed FALSEto create input pipes\n");
        return -1;FALSE;
    ok}

 =   if (!CreatePipe(&hStdOutPipeRead&stdOutPipeRead, &hStdOutPipeWrite&stdOutPipeWrite, &sa, 0);)
    if{
        fprintf(okstderr, =="Failed FALSEto create output pipes\n");
        return FALSE;
    }

    // copy command line to non-1;constant string
    char commandLineCopy[MAX_CMDLINE];
    strcpy_s(commandLineCopy, MAX_CMDLINE, commandLine);

    // Create the process.
    STARTUPINFO sisi;
 = { } memset(&si, 0, sizeof(si));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = hStdOutPipeWrite;stdOutPipeWrite;
    si.hStdOutput = hStdOutPipeWrite;stdOutPipeWrite;
    si.hStdInput = hStdInPipeRead;stdInPipeRead;
    PROCESS_INFORMATION pipi;
 = { } memset(&pi, 0, sizeof(pi));
    LPSECURITY_ATTRIBUTES lpProcessAttributesprocessAttributes = NULL;
    LPSECURITY_ATTRIBUTES lpThreadAttributethreadAttribute = NULL;
    BOOL bInheritHandlesinheritHandles = TRUE;
    DWORD dwCreationFlagscreationFlags = 0;
    LPVOID lpEnvironmentenvironment = NULL;
    ok =if (!CreateProcessA(applicationName,
        lpApplicationNamecommandLineCopy,
        (LPSTR)lpCommandLineprocessAttributes,
        lpProcessAttributesthreadAttribute,
        lpThreadAttributeinheritHandles,
        bInheritHandlescreationFlags,
        dwCreationFlagsenvironment,
        lpEnvironmentcurrentDirectory,
        lpCurrentDirectory&si,
        &si,&pi))
    {
    &pi);
    if fprintf(okstderr, =="Failed FALSE)to create process\n");
        return -1;FALSE;
    }

    // Close pipes we do not need.
    CloseHandle(hStdOutPipeWritestdOutPipeWrite);
    CloseHandle(hStdInPipeReadstdInPipeRead);

    // The main loop for reading output from the DIR command.
    DWORD dwRead = 0;
    DWORD dwAvailread = 0;
    char* ptr = buffer;
    while (ReadFile(hStdOutPipeReadstdOutPipeRead, ptr, buflen, &dwRead&read, NULL))
    {
        ptr += dwRead;read;
        buflen -= dwRead;read;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(hStdOutPipeReadstdOutPipeRead);
    CloseHandle(hStdInPipeWritestdInPipeWrite);
 
    DWORD dwExitCode = 0;
    GetExitCodeProcess(pi.hProcess, &dwExitCodeexitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return dwExitCode;TRUE;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[4097];buffer[BUFFER_SIZE + 1];
    intDWORD resretcode = 0;
    if (!executeAndGetResults(NULL, pingPath, " www.google.com", buffer, 4096BUFFER_SIZE, &retcode);)
    if (res)
   return EXIT_FAILURE;

    returnprintf("retcode: res;
[%d]\n", retcode);
    printf("results:\n[%s]" [%s]\n", buffer);
}

The correct, but rather boring and long, way to do this on Windows is to use CreateProcess. Here is a basic example of how to use it:

#include <windows.h> 
#include <stdio.h>

int executeAndGetResults(LPCSTR lpCurrentDirectory, LPCSTR lpApplicationName, LPCSTR lpCommandLine, LPSTR buffer, DWORD buflen)
{
    BOOL ok = TRUE;
    HANDLE hStdInPipeRead = NULL;
    HANDLE hStdInPipeWrite = NULL;
    HANDLE hStdOutPipeRead = NULL;
    HANDLE hStdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    ok = CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0);
    if (ok == FALSE) return -1;
    ok = CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0);
    if (ok == FALSE) return -1;

    // Create the process.
    STARTUPINFO si = { };
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = hStdOutPipeWrite;
    si.hStdOutput = hStdOutPipeWrite;
    si.hStdInput = hStdInPipeRead;
    PROCESS_INFORMATION pi = { };
    LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
    LPSECURITY_ATTRIBUTES lpThreadAttribute = NULL;
    BOOL bInheritHandles = TRUE;
    DWORD dwCreationFlags = 0;
    LPVOID lpEnvironment = NULL;
    ok = CreateProcessA(
        lpApplicationName,
        (LPSTR)lpCommandLine,
        lpProcessAttributes,
        lpThreadAttribute,
        bInheritHandles,
        dwCreationFlags,
        lpEnvironment,
        lpCurrentDirectory,
        &si,
        &pi);
    if (ok == FALSE) 
        return -1;

    // Close pipes we do not need.
    CloseHandle(hStdOutPipeWrite);
    CloseHandle(hStdInPipeRead);

    // The main loop for reading output from the DIR command.
    DWORD dwRead = 0;
    DWORD dwAvail = 0;
    char* ptr = buffer;
    while (ReadFile(hStdOutPipeRead, ptr, buflen, &dwRead, NULL))
    {
        ptr += dwRead;
        buflen -= dwRead;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(hStdOutPipeRead);
    CloseHandle(hStdInPipeWrite);
 
    DWORD dwExitCode = 0;
    GetExitCodeProcess(pi.hProcess, &dwExitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return dwExitCode;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[4097];
    int res = executeAndGetResults(NULL, pingPath, " www.google.com", buffer, 4096);
    if (res)
        return res;

    printf("results:\n[%s]", buffer);
}

The correct, but rather long and boring, way to do this on Windows is to use CreateProcess. Here is a basic example of how to use it:

#include <windows.h> 
#include <stdio.h>

#define MAX_CMDLINE 8191 
#define BUFFER_SIZE 4096

BOOL executeAndGetResults(LPCSTR currentDirectory, LPCSTR applicationName, LPCSTR commandLine, LPSTR buffer, DWORD buflen, DWORD* exitCode)
{
    BOOL ok = TRUE;
    HANDLE stdInPipeRead = NULL;
    HANDLE stdInPipeWrite = NULL;
    HANDLE stdOutPipeRead = NULL;
    HANDLE stdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    if (!CreatePipe(&stdInPipeRead, &stdInPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create input pipes\n");
        return FALSE;
    }

    if (!CreatePipe(&stdOutPipeRead, &stdOutPipeWrite, &sa, 0))
    {
        fprintf(stderr, "Failed to create output pipes\n");
        return FALSE;
    }

    // copy command line to non-constant string
    char commandLineCopy[MAX_CMDLINE];
    strcpy_s(commandLineCopy, MAX_CMDLINE, commandLine);

    // Create the process.
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = stdOutPipeWrite;
    si.hStdOutput = stdOutPipeWrite;
    si.hStdInput = stdInPipeRead;
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    LPSECURITY_ATTRIBUTES processAttributes = NULL;
    LPSECURITY_ATTRIBUTES threadAttribute = NULL;
    BOOL inheritHandles = TRUE;
    DWORD creationFlags = 0;
    LPVOID environment = NULL;
    if (!CreateProcessA(applicationName,
        commandLineCopy,
        processAttributes,
        threadAttribute,
        inheritHandles,
        creationFlags,
        environment,
        currentDirectory,
        &si,
        &pi))
    {
        fprintf(stderr, "Failed to create process\n");
        return FALSE;
    }

    // Close pipes we do not need.
    CloseHandle(stdOutPipeWrite);
    CloseHandle(stdInPipeRead);

    // The main loop for reading output from the command
    DWORD read = 0;
    char* ptr = buffer;
    while (ReadFile(stdOutPipeRead, ptr, buflen, &read, NULL))
    {
        ptr += read;
        buflen -= read;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(stdOutPipeRead);
    CloseHandle(stdInPipeWrite);
    GetExitCodeProcess(pi.hProcess, exitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return TRUE;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[BUFFER_SIZE + 1];
    DWORD retcode = 0;
    if (!executeAndGetResults(NULL, pingPath, " www.google.com", buffer, BUFFER_SIZE, &retcode))
        return EXIT_FAILURE;

    printf("retcode: [%d]\n", retcode);
    printf("results: [%s]\n", buffer);
}
Source Link
jdt
  • 2.4k
  • 5
  • 20

Using system and piping the results into a temp file can get you in trouble. What happens if you do not have the correct privileges to write to the current folder? Running more than one instance of your program at the same time?

The correct, but rather boring and long, way to do this on Windows is to use CreateProcess. Here is a basic example of how to use it:

#include <windows.h> 
#include <stdio.h>

int executeAndGetResults(LPCSTR lpCurrentDirectory, LPCSTR lpApplicationName, LPCSTR lpCommandLine, LPSTR buffer, DWORD buflen)
{
    BOOL ok = TRUE;
    HANDLE hStdInPipeRead = NULL;
    HANDLE hStdInPipeWrite = NULL;
    HANDLE hStdOutPipeRead = NULL;
    HANDLE hStdOutPipeWrite = NULL;

    // Create two pipes.
    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    ok = CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0);
    if (ok == FALSE) return -1;
    ok = CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0);
    if (ok == FALSE) return -1;

    // Create the process.
    STARTUPINFO si = { };
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = hStdOutPipeWrite;
    si.hStdOutput = hStdOutPipeWrite;
    si.hStdInput = hStdInPipeRead;
    PROCESS_INFORMATION pi = { };
    LPSECURITY_ATTRIBUTES lpProcessAttributes = NULL;
    LPSECURITY_ATTRIBUTES lpThreadAttribute = NULL;
    BOOL bInheritHandles = TRUE;
    DWORD dwCreationFlags = 0;
    LPVOID lpEnvironment = NULL;
    ok = CreateProcessA(
        lpApplicationName,
        (LPSTR)lpCommandLine,
        lpProcessAttributes,
        lpThreadAttribute,
        bInheritHandles,
        dwCreationFlags,
        lpEnvironment,
        lpCurrentDirectory,
        &si,
        &pi);
    if (ok == FALSE) 
        return -1;

    // Close pipes we do not need.
    CloseHandle(hStdOutPipeWrite);
    CloseHandle(hStdInPipeRead);

    // The main loop for reading output from the DIR command.
    DWORD dwRead = 0;
    DWORD dwAvail = 0;
    char* ptr = buffer;
    while (ReadFile(hStdOutPipeRead, ptr, buflen, &dwRead, NULL))
    {
        ptr += dwRead;
        buflen -= dwRead;
    }
    *ptr = '\0';

    // Clean up and exit.
    CloseHandle(hStdOutPipeRead);
    CloseHandle(hStdInPipeWrite);

    DWORD dwExitCode = 0;
    GetExitCodeProcess(pi.hProcess, &dwExitCode);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return dwExitCode;
}

int main()
{
    printf("pinging google...\n");

    char systemPath[_MAX_PATH];
    GetSystemDirectoryA(systemPath, _MAX_PATH);

    char pingPath[_MAX_PATH];
    snprintf(pingPath, _MAX_PATH, "%s\\ping.exe", systemPath);
 
    char buffer[4097];
    int res = executeAndGetResults(NULL, pingPath, " www.google.com", buffer, 4096);
    if (res)
        return res;

    printf("results:\n[%s]", buffer);
}