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;
}