0

I am capturing the output of a command run through CreateProcess after redirecting the output to a file and then reading the file contents. I store the string read from the file into a char array inside the function and print it. All good so far. Then I return the char array to the main function and attempt to print it from there. It seems to print inconsistent garbage. I am not sure why. Throwing the executable in a debugger, I see that the printf inside main is called with correct pointer address. I am at loss understanding why it behaves the way it does. Need some pointers. Here is my code:

#include <Windows.h>
#include <stdio.h>

char * run_cmd(char * cmd ) {


    char output[2000];

    SECURITY_ATTRIBUTES sa;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    HANDLE hFile;

    hFile = CreateFileA("out.log",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        &sa, // this seems important!
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    BOOL ret = FALSE;
    DWORD flags = CREATE_NO_WINDOW;

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdError = NULL;
    si.hStdOutput = hFile;

    ret = CreateProcessA(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);

    Sleep(2000);

    CloseHandle(hFile);

    DWORD lpNumberOfBytesRead; // return value

    hFile = CreateFileA("out.log",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    DWORD dwBytesToRead = GetFileSize(hFile, NULL);

    ReadFile(hFile, (void *)output, dwBytesToRead, &lpNumberOfBytesRead, NULL);

    output[lpNumberOfBytesRead] = '\0';

    CloseHandle(hFile);

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    printf("%s\n", output);

    printf("------------------------------------------------------------------------");

    return output;


}

int main(void) {

    printf("%s\n", run_cmd("ipconfig"));

}
``
user1720897
  • 1,216
  • 3
  • 12
  • 27
  • 1
    `output` is allocated on the stack, and returning a pointer to it is undefined behaviour. You need to allocate a copy of the memory and return that; e.g. in a `std::string`. – Jonathan Potter Apr 19 '20 at 06:54
  • 1
    You can't return a pointer to a stack allocated variable from a function, use `std::string` instead – Alan Birtles Apr 19 '20 at 06:55
  • 1
    I'm pretty sure MSVC warns about this with `/W4` (probably less). – chris Apr 19 '20 at 06:55
  • Warning [C4172](https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4172) is issued at warning level 1. – IInspectable Apr 19 '20 at 07:01
  • @IInspectable It did. But I didnt understand what it meant then, now I do! – user1720897 Apr 19 '20 at 07:13

0 Answers0