Basic Process Management

Illustrative examples for common tasks like creating, terminating, and managing processes.

Creating a New Process

Demonstrates using CreateProcess to launch an external executable.


#include <windows.h>
#include <iostream>

int main() {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // Path to the executable you want to start
    const char* programPath = "C:\\Windows\\System32\\notepad.exe";

    if (CreateProcess(
        programPath,   // Application name.
        NULL,          // Command line.
        NULL,          // Process handle not inheritable.
        NULL,          // Thread handle not inheritable.
        FALSE,         // Set handle inheritance to FALSE.
        0,             // No creation flags.
        NULL,          // Use parent's environment block.
        NULL,          // Use parent's starting directory.
        &si,           // Pointer to STARTUPINFO structure.
        &pi )          // Pointer to PROCESS_INFORMATION structure.
    ) {
        std::cout << "Process created successfully!" << std::endl;
        std::cout << "Process ID: " << pi.dwProcessId << std::endl;

        // Wait until child process exits.
        WaitForSingleObject(pi.hProcess, INFINITE);

        // Close process and thread handles.
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    } else {
        std::cerr << "CreateProcess failed (" << GetLastError() << ")." << std::endl;
        return 1;
    }

    return 0;
}
                    

Terminating a Process

Shows how to forcefully terminate a process using its process ID.


#include <windows.h>
#include <iostream>

int main() {
    DWORD processIdToTerminate = 1234; // Replace with the actual Process ID

    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processIdToTerminate);

    if (hProcess != NULL) {
        if (TerminateProcess(hProcess, 1)) { // Exit code 1
            std::cout << "Process " << processIdToTerminate << " terminated successfully." << std::endl;
        } else {
            std::cerr << "Failed to terminate process " << processIdToTerminate << ". Error: " << GetLastError() << std::endl;
        }
        CloseHandle(hProcess);
    } else {
        std::cerr << "Failed to open process " << processIdToTerminate << ". Error: " << GetLastError() << std::endl;
    }

    return 0;
}
                    

File I/O Operations

Examples for reading from and writing to files using Windows API functions.

Writing to a File

Using CreateFile and WriteFile to write data to a text file.


#include <windows.h>
#include <string>
#include <iostream>

int main() {
    const char* fileName = "example.txt";
    const char* dataToWrite = "This is some text written to the file using Windows API.";
    DWORD bytesWritten;

    HANDLE hFile = CreateFile(
        fileName,                // File name
        GENERIC_WRITE,           // dwDesiredAccess
        0,                       // dwShareMode
        NULL,                    // lpSecurityAttributes
        CREATE_ALWAYS,           // dwCreationDisposition
        FILE_ATTRIBUTE_NORMAL,   // dwFlagsAndAttributes
        NULL                     // hTemplateFile
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "Error creating file: " << GetLastError() << std::endl;
        return 1;
    }

    if (WriteFile(hFile, dataToWrite, strlen(dataToWrite), &bytesWritten, NULL)) {
        std::cout << "Successfully wrote " << bytesWritten << " bytes to " << fileName << std::endl;
    } else {
        std::cerr << "Error writing to file: " << GetLastError() << std::endl;
    }

    CloseHandle(hFile);
    return 0;
}
                    

Reading from a File

Using CreateFile and ReadFile to read data from a text file.


#include <windows.h>
#include <string>
#include <iostream>
#include <vector>

int main() {
    const char* fileName = "example.txt";
    DWORD bytesRead;
    const int bufferSize = 1024;
    std::vector<char> buffer(bufferSize);

    HANDLE hFile = CreateFile(
        fileName,              // File name
        GENERIC_READ,          // dwDesiredAccess
        FILE_SHARE_READ,       // dwShareMode
        NULL,                  // lpSecurityAttributes
        OPEN_EXISTING,         // dwCreationDisposition
        FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
        NULL                   // hTemplateFile
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "Error opening file: " << GetLastError() << std::endl;
        return 1;
    }

    if (ReadFile(hFile, buffer.data(), bufferSize - 1, &bytesRead, NULL)) {
        buffer[bytesRead] = '\\0'; // Null-terminate the buffer
        std::cout << "Successfully read " << bytesRead << " bytes from " << fileName << ":" << std::endl;
        std::cout << buffer.data() << std::endl;
    } else {
        std::cerr << "Error reading from file: " << GetLastError() << std::endl;
    }

    CloseHandle(hFile);
    return 0;
}
                    

Memory Management

Examples demonstrating dynamic memory allocation and manipulation.

Allocating and Freeing Memory

Using HeapAlloc and HeapFree for manual memory management.


#include <windows.h>
#include <iostream>
#include <string>

int main() {
    HANDLE hHeap = GetProcessHeap(); // Get the default heap of the current process
    if (hHeap == NULL) {
        std::cerr << "Failed to get process heap. Error: " << GetLastError() << std::endl;
        return 1;
    }

    SIZE_T sizeToAllocate = 100 * sizeof(char); // Allocate space for 100 characters
    LPVOID memoryBlock = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeToAllocate);

    if (memoryBlock == NULL) {
        std::cerr << "Failed to allocate memory. Error: " << GetLastError() << std::endl;
        return 1;
    }

    std::cout << "Memory allocated successfully at address: " << memoryBlock << std::endl;

    // Use the allocated memory
    strcpy_s((char*)memoryBlock, sizeToAllocate, "Hello from allocated memory!");
    std::cout << "Content: " << (char*)memoryBlock << std::endl;

    // Free the allocated memory
    if (HeapFree(hHeap, 0, memoryBlock)) {
        std::cout << "Memory freed successfully." << std::endl;
    } else {
        std::cerr << "Failed to free memory. Error: " << GetLastError() << std::endl;
    }

    return 0;
}
                    

Inter-Process Communication

Basic examples of how different processes can communicate.

Using Pipes for IPC

A simplified example of using anonymous pipes to send data from a parent to a child process.


#include <windows.h>
#include <iostream>
#include <string>
#include <vector>

int main() {
    HANDLE hReadPipe, hWritePipe;
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // Create the pipe
    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
        std::cerr << "CreatePipe failed (" << GetLastError() << ")." << std::endl;
        return 1;
    }

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.hStdError = GetStdHandle(STD_ERROR_HANDLE); // Inherit error handle
    si.hStdOutput = hWritePipe; // Redirect child's stdout to the write end of the pipe
    si.dwFlags |= STARTF_USESTDHANDLES; // Use std handles

    ZeroMemory(&pi, sizeof(pi));

    const char* childProgram = "cmd.exe"; // Example child process
    const char* cmdArgs = "/c echo Hello from child process!";

    // Create the child process
    if (!CreateProcess(
        childProgram,
        (LPSTR)cmdArgs,
        NULL, NULL,
        TRUE, // Inherit handles
        0, NULL, NULL,
        &si, &pi))
    {
        std::cerr << "CreateProcess failed (" << GetLastError() << ")." << std::endl;
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        return 1;
    }

    // Close the write end of the pipe in the parent, as the child has it
    CloseHandle(hWritePipe);

    // Read from the pipe in the parent process
    const int bufferSize = 1024;
    std::vector<char> buffer(bufferSize);
    DWORD dwRead;

    std::cout << "Reading from child process..." << std::endl;
    while (ReadFile(hReadPipe, buffer.data(), bufferSize - 1, &dwRead, NULL) && dwRead > 0) {
        buffer[dwRead] = '\0'; // Null-terminate
        std::cout << buffer.data(); // Print output from child
    }
    std::cout << std::endl << "Finished reading." << std::endl;

    // Wait for the child process to exit
    WaitForSingleObject(pi.hProcess, INFINITE);

    // Close handles
    CloseHandle(hReadPipe);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}