Creating network device - c++

here is my code:
#include <windows.h>
#include <winerror.h>
#include <Winbase.h>
#include <Shlwapi.h>
#include <Setupapi.h>
#include <stdio.h>
typedef BOOL WINAPI (*InstallSelectedDriverProto)(HWND, HDEVINFO, LPCTSTR, BOOL, PDWORD);
int main()
{
InstallSelectedDriverProto InstallSelectedDriver;
static const int MAX_NAME = 256;
HDEVINFO devs = INVALID_HANDLE_VALUE;
char infPath[260] = {0};
char deviceId[260] = {0};
DWORD reboot = 0;
HMODULE newDll = NULL;
int devNameSize = 260;
GUID classGUID = {0};
char ClassName[MAX_NAME] = {0};
char hwIdList[LINE_LEN + 4] = {0};
SP_DEVINFO_DATA deviceData = {0};
SP_DRVINFO_DATA driverInfoData = {sizeof(SP_DRVINFO_DATA)};
const char *hwid;
char *devName = NULL;
hwid = "net";
char *inf;
inf = "C:\\Program Files (x86)\\Infs\\net.inf";
strncpy(infPath, inf, sizeof(infPath)-1);
infPath[sizeof(infPath)-1] = '\0';
memset(hwIdList, 0, sizeof(hwIdList));
strcpy(hwIdList, hwid);
if (SetupDiGetINFClass(infPath, &classGUID,
ClassName, MAX_NAME, 0) == FALSE)
{
printf("SetupDiGetINFClass failed. %d\n", GetLastError());
fflush(stdout);
}
devs = SetupDiCreateDeviceInfoList(&classGUID, 0);
if (devs == INVALID_HANDLE_VALUE)
{
printf("devs == INVALID_HANDLE_VALUE.\n");
fflush(stdout);
}
deviceData.cbSize = sizeof(SP_DEVINFO_DATA);
if (devName == NULL || devName[0] == 0)
{
if (SetupDiCreateDeviceInfo(devs, hwid, &classGUID, NULL, 0,
DICD_GENERATE_ID, &deviceData) == FALSE)
{
printf("SetupDiCreateDeviceInfo failed. %d\n", GetLastError());
fflush(stdout);
}
}
else
{
strcpy(deviceId, "Root\\");
strcat(deviceId, ClassName);
strcat(deviceId, "\\");
strcat(deviceId, devName);
if (SetupDiCreateDeviceInfo(devs, deviceId, &classGUID,
NULL, 0, 0, &deviceData) == FALSE)
{
printf("SetupDiCreateDeviceInfo failed. %d\n", GetLastError());
fflush(stdout);
}
}
if (SetupDiSetDeviceRegistryProperty(devs, &deviceData,
SPDRP_HARDWAREID, (BYTE *) hwIdList,
(strlen(hwIdList) + 2)) == FALSE)
{
printf("SetupDiSetDeviceRegistryProperty failed. %d\n", GetLastError());
fflush(stdout);
}
if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
devs, &deviceData) == FALSE)
{
printf("SetupDiCallClassInstaller failed. %d\n", GetLastError());
fflush(stdout);
}
newDll = LoadLibrary("newdesv.dll");
if (newDll == NULL)
{
printf("newDll == NULL.\n");
fflush(stdout);
}
InstallSelectedDriver = (InstallSelectedDriverProto) GetProcAddress(newDll, "InstallSelectedDriver");
if (InstallSelectedDriver == NULL)
{
printf("InstallSelectedDriver == NULL failed. %d\n", GetLastError());
fflush(stdout);
}
if (SetupDiSetSelectedDevice(devs, &deviceData) == FALSE)
{
printf("SetupDiSetSelectedDevice failed. %d\n", GetLastError());
fflush(stdout);
}
if (SetupDiBuildDriverInfoList(devs, &deviceData,
SPDIT_COMPATDRIVER) == FALSE)
{
printf("SetupDiBuildDriverInfoList failed. %d\n", GetLastError());
fflush(stdout);
}
if (SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV, devs,
&deviceData) == FALSE)
{
printf("SetupDiBuildDriverInfoList failed. %d\n", GetLastError());
fflush(stdout);
}
if (SetupDiGetSelectedDriver(devs, &deviceData,
&deviceData) == FALSE)
{
printf("SetupDiGetSelectedDriver failed. %d\n", GetLastError());
fflush(stdout);
}
if (InstallSelectedDriver(NULL, devs, NULL, TRUE, &reboot) == FALSE)
{
printf("InstallSelectedDriver failed. %d\n", GetLastError());
fflush(stdout);
}
if (devName && devNameSize > 0)
{
if (SetupDiGetDeviceInstanceId(devs, &deviceData,
devName, devNameSize, NULL) == FALSE)
{
printf("SetupDiGetDeviceInstanceId failed. %d\n", GetLastError());
fflush(stdout);
}
}
return 0;
}
What I'm trying to do is create a network device. I'm having Segmentation fault but don't know why. I can't paste the whole .inf file because it's University project but, it clearly has
[Version]
Signature = "$Windows NT$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
I tried different things and noticed that SetupDiCreateDeviceInfo may be the problem, because I tried to delete the command and everything below it, and in that case everything works fine. Sorry if question is silly, I'm new with winapi. Thanks.
P.S
About the problem with SetupDiGetDeviceInstanceId, As I meantion in comments it gives me Segmentation fault, I even tried this version:
char *devName1 = NULL;
if (SetupDiGetDeviceInstanceId(devs, &deviceData,
devName1, devNameSize, NULL) == FALSE)
{
printf("SetupDiGetDeviceInstanceId failed. %d\n", GetLastError());
fflush(stdout);
}
Created separated variable and initialized, but it gives me same error.

Related

Some files send on a HLS Server using Http Put request are partially uploaded

I have to upload audio chunks continuously on a HLS Server as a part of my project. I am able to upload chunks sucessfully using HTTP Put method with wininet API in C++ using following code.
bool CHTTP::HttpPut(char *szFile,int fileType)
{
bool bErrorFlag = false;
if(m_hInternet == NULL)
{
int retStatus = OpenHTTPSession();
if(retStatus < 1)
{
return true;
}
}
char szPostURL[256];
INTERNET_BUFFERS BufferIn = {0};
DWORD dwBytesRead;
DWORD dwBytesWritten;
BYTE pBuffer[350000];
BOOL bRead, bRet;
static int flag = 1;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
char szLocalFilePath[256];
if(fileType == AUDIO_CHUNK)
sprintf(szLocalFilePath,"%s/%s",m_strFilePath,szFile);
else
strcpy(szLocalFilePath,szFile);
int iFileSize = 0;
if(fileType == AUDIO_CHUNK)
{
strcpy(szPostURL,m_strPostPath);
strcat(szPostURL,"/");
strcat(szPostURL,szFile);
}
else if(fileType == M3U8)
strcpy(szPostURL,m_szM3U8FileToPost);
else if(fileType == AUTO_M3U8)
strcpy(szPostURL,m_szM3U8AutoPost);
DWORD dwFlags =
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_COOKIES |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_NO_UI |
INTERNET_FLAG_RELOAD |INTERNET_FLAG_SECURE;
m_hRequest = HttpOpenRequest(m_hHttpSession, (const char*)"PUT",szPostURL, "HTTP/1.1",NULL , (const char**)"*/*\0",dwFlags, 1);
if(m_hRequest==NULL)
{
bErrorFlag = true;
CloseHTTPSession();
return bErrorFlag;
}
else
{
bErrorFlag = false;
}
int num_of_try = 0;
while(num_of_try < 3)
{
char logDump[1000];
num_of_try++;
HANDLE hFile = CreateFile (szLocalFilePath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
bErrorFlag = true;
break;
}
else if(!m_bLogFlagCreateErr)
{
m_bLogFlagCreateErr = true;
sprintf(logDump,"CreateFile success %s",szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = false;
}
BufferIn.dwBufferTotal = GetFileSize (hFile, NULL);
iFileSize = BufferIn.dwBufferTotal;
if(!HttpSendRequestEx( m_hRequest, &BufferIn, NULL, HSR_INITIATE, 0))
{
bErrorFlag = true;
m_bLogFlagSend = false;
sprintf(logDump,"Error on HttpSendRequestEx %lu %s",GetLastError(),szFile);
WriteLog(mLogFile,logDump);
break;
}
else
{
bErrorFlag = false;
sprintf(logDump,"HttpSendRequest success %s",szFile);
WriteLog(mLogFile,logDump);
}
DWORD sum = 0;
int size = 0;
do
{
bRead = ReadFile (hFile, pBuffer,iFileSize,
&dwBytesRead, NULL);
if(dwBytesRead != iFileSize)
{
sprintf(logDump,"dwBytesRead %d iFileSize %d %s",dwBytesRead,iFileSize,szFile);
WriteLog(mLogFile,logDump);
}
if(dwBytesRead > 0)
{
bRet=InternetWriteFile( m_hRequest, pBuffer, dwBytesRead,
&dwBytesWritten);
while(dwBytesRead < dwBytesWritten && bRet)
{
sprintf(logDump,"dwBytesRead %d dwBytesWritten %d %s",dwBytesRead,dwBytesWritten,szFile);
WriteLog(mLogFile,logDump);
bRet=InternetWriteFile( m_hRequest, pBuffer+dwBytesWritten, dwBytesRead - dwBytesWritten ,&dwBytesWritten);
}
if(!bRet)
{
int error = GetLastError();
sprintf(logDump,"InternetWriteFile %lu %s",error,szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = true;
break;
}
else
{
sprintf(logDump,"InternetWriteFile buffer success %s",szFile);
WriteLog(mLogFile,logDump);
bErrorFlag = false;
}
}
}
while (dwBytesRead == iFileSize);
CloseHandle (hFile);
if(!HttpEndRequest(m_hRequest, NULL, 0, 0))
{
int error = GetLastError();
if(error != 12032)
{
sprintf(logDump,"HttpEndRequest %lu %s",error,szFile);
WriteLog(mLogFile,logDump)
bErrorFlag = true;
break;
}
else
{
bErrorFlag = true;
continue;
}
}
else
{
sprintf(logDump,"HttpEndRequest success %s",szFile);
WriteLog(mLogFile,logDump);
DWORD dwCode, dwCodeSize;
dwCodeSize = sizeof(DWORD);
if(!HttpQueryInfo(m_hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwCodeSize, NULL))
{
int error = GetLastError();
char tmp[256];
sprintf(tmp,"HttpQueryfails %d %s",error, szFile);
WriteLog(mLogFile,tmp);
}
else
{
if(dwCode != 201 && dwCode != 204)
{
char tmp[256];
sprintf(tmp,"dwcode %d is not 201 or 204 %s",dwCode,szFile);
WriteLog(mLogFile,tmp);
bErrorFlag = true;
break;
}
}
bErrorFlag = false;
break;
}
}
CloseHTTPSession();
return bErrorFlag;
}
Most of the times chunks uploaded are of full size. Randomly chunks uploaded on server are not of full size as shown in following image.
sample image
In such case I am not getting any error messages, even dwBytesWritten returned by InternetWriteFile function is also correct. I am unable to understand what should I do to solve it. Any help in this regard is appreciated.

Modify DACL to prevent everybody kill process without Debug Priveleges

I have some code which i have wrote. I need to modify DACL ( security descriptor) in Windows 10 to prevent kill process without Debug Privilege of user. How can i do this one? I learned at the internet algorithm, looked for some functions for that, but process still closes without any problems. I tried debug it a lot of time, code works without errors, but unsuccessfully.
How should i solve this problem? For my example below,i Add ACE for Denied PROCESS_TERMINATE. Is it right way?
Also advice me how can i check that. I know that i will get MessageBox of Permission Denied, yep?
My code (p.s. updated):
#include <iostream>
#include <Windows.h>
PSECURITY_DESCRIPTOR GetProcessSecurityDescriptor(HANDLE processHandle, DWORD &buffSizeNeeded);
void SecurityDescriptorModifier(HANDLE hProcess);
int main()
{
DWORD pID;
std::cin >> pID;
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
SecurityDescriptorModifier(processHandle);
HANDLE pHandle = OpenProcess(PROCESS_TERMINATE, false, pID);
return 0;
}
void SecurityDescriptorModifier(HANDLE hProcess)
{
DWORD SIDLength = 0;
PSID SID;
PACL pACL;
PACL pNewAcl;
BOOL bDaclExist;
BOOL bDaclPresent;
PSECURITY_DESCRIPTOR pSecurityDescriptor;
PSECURITY_DESCRIPTOR pSecurityDescriptorNew;
ACL_SIZE_INFORMATION aclSizeInfo;
DWORD dwNewAclSize;
ACCESS_ALLOWED_ACE* pACE;
PVOID pTempAce;
DWORD buffSizeNeeded = -1;
// "everyone" group
//CreateWellKnownSid(WinWorldSid, NULL, NULL, &SIDLength);
// Allocate enough memory for the largest possible SID.
SIDLength = SECURITY_MAX_SID_SIZE;
if (!(SID = LocalAlloc(LMEM_FIXED, SIDLength)))
{
fprintf(stderr, "Could not allocate memory.\n");
exit(1);
}
//SID = new byte[SECURITY_MAX_SID_SIZE];
if (!CreateWellKnownSid(WinWorldSid, NULL, SID, &SIDLength))
{
fprintf(stderr,
"CreateWellKnownSid Error %u",
GetLastError());
LocalFree(SID);
}
pSecurityDescriptor = GetProcessSecurityDescriptor(hProcess, buffSizeNeeded);
BOOL executionResult = GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pACL, &bDaclExist);
if(!executionResult)
{
fprintf(stderr, "GetSecurityDescriptorDacl() failed, error %d\n", GetLastError());
exit(1);
}
pSecurityDescriptorNew = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffSizeNeeded);
if (pSecurityDescriptorNew == NULL)
exit(1);
else
printf("Heap allocated for psdNew!\n");
// Create a new security descriptor
if (!InitializeSecurityDescriptor(pSecurityDescriptorNew, SECURITY_DESCRIPTOR_REVISION))
{
fprintf(stderr, "InitializeSecurityDescriptor() failed, error %d\n", GetLastError());
exit(1);
}
// Obtain the DACL from the security descriptor
if (!GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pACL, &bDaclExist))
{
fprintf(stderr, "GetSecurityDescriptorDacl() failed, error %d\n", GetLastError());
exit(1);
}
// Initialize
ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
aclSizeInfo.AclBytesInUse = sizeof(ACL);
// Call only if NULL DACL
if (pACL != NULL)
{
// Determine the size of the ACL information
if (!GetAclInformation(pACL, (LPVOID)& aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
{
fprintf(stderr, "GetAclInformation() failed, error %d\n", GetLastError());
exit(1);
}
}
// Compute the size of the new ACL
dwNewAclSize = aclSizeInfo.AclBytesInUse + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(SID) - sizeof(DWORD);
// Allocate buffer for the new ACL
pNewAcl = (PACL)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize);
if (pNewAcl == NULL)
exit(1);
// Initialize the new ACL
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
{
fprintf(stderr, "InitializeAcl() failed, error %d\n", GetLastError());
exit(1);
}
static const DWORD dwPoison = PROCESS_TERMINATE;
BOOL bResult = AddAccessDeniedAce(pNewAcl, ACL_REVISION, dwPoison, SID);
if (FALSE == bResult)
{
printf("AddAccessDenied Error %d\n", GetLastError());
}
// If DACL is present, copy it to a new DACL
if (!bDaclPresent)
{
// Copy the ACEs to the new ACL.
if (aclSizeInfo.AceCount)
{
for (int i = 0; i < aclSizeInfo.AceCount; i++)
{
// Get an ACE.
if (!GetAce(pACL, i, &pTempAce))
{
fprintf(stderr, "GetAce() failed, error %d\n", GetLastError());
exit(1);
}
else
fprintf(stderr, "GetAce working\n");
// Add the ACE to the new ACL.
if (!AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize))
{
fprintf(stderr, "AddAce() failed, error %d\n", GetLastError());
exit(1);
}
else
fprintf(stderr, "AddAce() is working!\n");
}
}
}
if (!SetSecurityDescriptorDacl(pSecurityDescriptorNew, TRUE, pNewAcl, FALSE))
{
printf("SetSecurityDescriptorDacl() failed, error %d\n", GetLastError());
exit(1);
}
else
printf("SetSecurityDescriptorDacl() is working!\n");
// Set the new security descriptor for the window station
if (!SetKernelObjectSecurity(hProcess, DACL_SECURITY_INFORMATION, pSecurityDescriptorNew))
{
printf("SetUserObjectSecurity() failed, error %d\n", GetLastError());
exit(1);
}
else
printf("SetUserObjectSecurity() is working!\n");
}
PSECURITY_DESCRIPTOR GetProcessSecurityDescriptor(HANDLE processHandle, DWORD &buffSizeNeeded)
{
PSECURITY_DESCRIPTOR pSD = new byte[0];
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
// To understand actual needed size for pSD
// GetKernelObject, what diff?
GetKernelObjectSecurity(processHandle, si, pSD, 0, &buffSizeNeeded);
if (buffSizeNeeded <= 0)
{
fprintf(stderr, ":GetKernelObjectSecurity ERROR: %u\n", GetLastError());
exit(1);
}
pSD = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffSizeNeeded);
if (pSD == NULL)
exit(1);
else
printf("Heap allocated for psdNew!\n");
//Allocate Memory & get DACL
if (!GetKernelObjectSecurity(processHandle, si, pSD, buffSizeNeeded, &buffSizeNeeded))
{
fprintf(stderr, ":GetKernelObjectSecurity(With Alloc) ERROR: %u\n", GetLastError());
exit(1);
}
return pSD;
}

Broken pipe when reading from a pipe of a child process launched as a different user

I'm trying to launch a child executable to run as the logged in user(written in golang) from a windows service running as SYSTEM. I am using the CreateProcessAsUser method to start the process. I've observed that the child process actually starts, but i'm unable to read the stdout of it. I've followed the steps described in https://learn.microsoft.com/en-us/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output to redirect the stdin and stdout of the child.
I have also set the permissions on the pipe to the Everyone SID, but still getting the same issue.
The parent process's code is as follows (after further edits based on suggestions in the comments)
#include "test.h"
#include <windows.h>
#include <winbase.h>
#include <userenv.h>
#include <tchar.h>
#include <wtsapi32.h>
#include <strsafe.h>
#include <processthreadsapi.h>
#define BUFSIZE 4096
#define PROC_THREAD_ATTRIBUTE_HANDLE_LIST ( 2 | 0x00020000)
typedef struct _STARTUPINFOEXA {
STARTUPINFOA StartupInfo;
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;
void ReadAndHandleOutput(HANDLE hPipeRead, FILE* fp)
{
CHAR lpBuffer[BUFSIZE];
DWORD nBytesRead;
DWORD bytesAvailable;
DWORD bytesLeftInMsg;
do
{
if (!PeekNamedPipe(hPipeRead, lpBuffer, sizeof(lpBuffer), &nBytesRead, &bytesAvailable, &bytesLeftInMsg))
{
if (GetLastError() == ERROR_BROKEN_PIPE) {
fprintf(fp, "Broken Pipe \n");
fflush(fp);
break; // pipe done - normal exit path.
}
else {
fprintf(fp, "ReadFileError %d\n", GetLastError()); // Something bad happened.
fflush(fp);
}
}
} while(bytesLeftInMsg > 0);
fprintf(fp, "GOT OUTPUT, %s -- %d -- %d -- %d\n", lpBuffer, nBytesRead, bytesAvailable, bytesLeftInMsg);
fflush(fp);
}
bool LaunchProcess(char *process_path)
{
FILE *fp = fopen("C:\\test.log", "a");
DWORD SessionId = WTSGetActiveConsoleSessionId();
if (SessionId == -1) { // no-one logged in
fprintf(fp, "Session ID is -1\n");
fclose(fp);
return false;
}
HANDLE hToken;
BOOL ok = WTSQueryUserToken(SessionId, &hToken);
if (!ok) {
fprintf(fp, "Unable to get the token for session id %d\n", SessionId);
fclose(fp);
return false;
}
void *environment = NULL;
ok = CreateEnvironmentBlock(&environment, hToken, TRUE);
if (!ok)
{
fprintf(fp, "Unable to create environment with session ID %d\n", SessionId);
CloseHandle(hToken);
fclose(fp);
return false;
}
HANDLE hServerPipe = CreateNamedPipe("\\\\.\\Pipe\\test-pipe.em", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 1, 0, 0, 0, 0);
HANDLE hClientPipe;
if (hServerPipe != INVALID_HANDLE_VALUE)
{
static SECURITY_ATTRIBUTES sa = { sizeof(sa), 0, TRUE };
hClientPipe = CreateFile("\\\\.\\Pipe\\test-pipe.em", FILE_GENERIC_READ|FILE_GENERIC_WRITE, 0, &sa, OPEN_EXISTING, 0, 0);
if (hClientPipe == INVALID_HANDLE_VALUE)
{
fprintf(fp, "Error creating client handle %d", GetLastError());
CloseHandle(hServerPipe);
return false;
}
} else {
fprintf(fp, "Error creating server handle %d", GetLastError());
return false;
}
STARTUPINFOEXA si = { { sizeof(si) } };
PROCESS_INFORMATION pi;
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
si.StartupInfo.hStdInput = si.StartupInfo.hStdOutput = si.StartupInfo.hStdError = hClientPipe;
DWORD dwCreationFlags = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
BOOL fInit = FALSE;
SIZE_T Size;
if (!InitializeProcThreadAttributeList(0, 1, 0, &Size) && GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
InitializeProcThreadAttributeList(si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(Size), 1, 0, &Size))
{
fInit = TRUE;
if (UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &si.StartupInfo.hStdError, sizeof(HANDLE), 0, 0)) {
dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
}
}
fprintf(fp, "calling the process %s\n", process_path);
fflush(fp);
ok = CreateProcessAsUser(hToken, NULL, process_path, NULL, NULL, TRUE, dwCreationFlags, environment, NULL, &si.StartupInfo, &pi);
fprintf(fp, "Running process %s and %d with PID %d\n", process_path, ok, pi.dwProcessId);
fflush(fp);
if (!ok) {
wchar_t buf[BUFSIZE];
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buf, (sizeof(buf) / sizeof(wchar_t)), NULL);
fprintf(fp, "Failed to create processes as user - %d, %d, %S, %s\n", SessionId, GetLastError(), buf, process_path);
fclose(fp);
return false;
} else {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
// Close pipe handles (do not continue to modify the parent).
// You need to make sure that no handles to the write end of the
// output pipe are maintained in this process or else the pipe will
// not close when the child process exits and the ReadFile will hang.
if (!CloseHandle(si.StartupInfo.hStdError)) {
fprintf(fp, "CloseHandle - outputwrite Error %d\n", GetLastError());
fclose(fp);
return false;
}
ReadAndHandleOutput(hServerPipe, fp);
CloseHandle(hServerPipe);
fclose(fp);
return true;
Cleanup:
fprintf(fp, "Something went wrong");
fclose(fp);
return false;
}
The child process's code is as follows
package main
import (
"fmt"
"os"
"time"
)
func main() {
os.Stdout.Write([]byte("Hello from the GO side..."))
f, err := os.OpenFile("C:\\log.text", os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
panic(err)
}
defer f.Close()
var output = fmt.Sprintf("I'm running as %d launched by %d", os.Getpid(), os.Getppid())
if _, err = f.WriteString(output); err != nil {
panic(err)
}
os.Stdout.Close()
}
I'm able to see the current PID and the parent's PID(the service) in the log.text file, However I keep getting a pipe broken error on the parent side.
Any pointers are appreciated

Wow64GetThreadContext returning same values for WOW64_CONTEXT structure members

I am compiling to 64-bit and calling the functions on a 32-bit(Wow64) processes thread. No errors are being returned for any functions.
But for some reason the CPU register members in the WOW64_CONTEXTstruct passed to Wow64GetThreadContext are always the same values each and every time the function is called. Even though I initialize every member in the struct to 0, WOW64_CONTEXT wow64ctxt = {0}.
As far as I know I am doing everything correctly but I always get the same values for each member in WOW64_CONTEXT.
Here's my code:
#define _WIN32_WINNT _WIN32_IE_WIN8
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
int main()
{
DWORD dwPid = 0;
BOOL found = FALSE;
BOOL wow64 = FALSE;
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
HANDLE hSnapshot = INVALID_HANDLE_VALUE;
THREADENTRY32 th32;
WOW64_CONTEXT wow64ctxt = {0};
printf("PID: ");
scanf("%lu", &dwPid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if(hProcess == NULL)
{
printf("Error getting handle to process: %lu\n", GetLastError());
return 1;
}
if(!IsWow64Process(hProcess, &wow64))
{
printf("Error determining bitness of process: %lu\n", GetLastError());
return 1;
}
if(!wow64)
{
printf("Error, not a 32-bit process... closing program\n");
return 1;
}
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPid);
if(hSnapshot == INVALID_HANDLE_VALUE)
{
printf("Error getting thread snapshot: %lu\n", GetLastError());
return 1;
}
th32.dwSize = sizeof(THREADENTRY32);
if(!Thread32First(hSnapshot, &th32))
{
printf("Error Thread32First: %lu\n", GetLastError());
return 1;
}
while(Thread32Next(hSnapshot, &th32))
{
if(th32.th32OwnerProcessID == dwPid)
{
found = TRUE;
break;
}
}
if(!found)
{
printf("Thread could not be found\n");
return 1;
}
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
if(hThread == NULL)
{
printf("Error getting a handle to thread %lu: %lu\n", th32.th32ThreadID, GetLastError());
return 1;
}
if(Wow64SuspendThread(hThread) == -1)
{
printf("Error suspending thread: %lu\n", GetLastError());
return 1;
}
wow64ctxt.ContextFlags = WOW64_CONTEXT_FULL;
if(!Wow64GetThreadContext(hThread, &wow64ctxt))
{
printf("Error getting thread context: %lu\n", GetLastError());
}
ResumeThread(hThread);
printf("EAX: %lu\n", wow64ctxt.Eax);
printf("EBP: %lu\n", wow64ctxt.Ebp);
printf("EIP: %lu\n", wow64ctxt.Eip);
return 0;
}

Why a ZeroMQ PGM multicast is not receiving a Multicast message? ( C++, Windows )

Environment setup:
- Both a multicast send & receive applications are running in the same machine
I am integrating ZeroMQ multicast with OpenPGM support, but facing problem in below my sample code.
i.e. "Multicast message is not received" in receiver application. Kindly correct me if I am doing wrong. Also not able to find proper examples on ZeroMQ PGM multicast requirement.
// ZMQ_pgm_receive.cpp :
//
//Headers
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_SUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_bind(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_bind: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_recvmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_recvmsg: %s\n", zmq_strerror (errno));
return -1;
}
printf("message received\n");
if (zmq_msg_size (&msg) != message_size) {
printf ("message of incorrect size received\n");
return -1;
}
Sleep(1000);
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
// ZMQ_pgm_send.cpp :
//
#include "stdafx.h"
#include "zmq.h"
#include <iostream>
#include <windows.h>
std::string fullurl = "pgm://eth0;239.255.0.1:30001";
static int roundtrip_count = 50;
static size_t message_size = 4;
int _tmain(int argc, _TCHAR* argv[])
{
void *ctx = NULL,
*s = NULL;
int con;
int i;
ctx = zmq_init (1);
if (!ctx) {
printf ("error in zmq_init: %s\n", zmq_strerror (errno));
return -1;
}
s = zmq_socket (ctx, ZMQ_PUB);
if (!s) {
printf ("error in zmq_socket: %s\n", zmq_strerror (errno));
return -1;
}
con = zmq_connect(socket, fullurl.c_str());
if (con == 0) {
printf ("error in zmq_connect: %s\n", zmq_strerror (errno));
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init_size (&msg,message_size);
if (rc != 0) {
printf ("error in zmq_msg_init: %s\n", zmq_strerror (errno));
return -1;
}
memset(zmq_msg_data (&msg),'A', message_size );
for (i = 0; i != roundtrip_count; i++) {
rc = zmq_sendmsg (s, &msg, 0);
if (rc < 0) {
printf ("error in zmq_sendmsg: %s\n", zmq_strerror (errno));
return -1;
}
}
rc = zmq_msg_close (&msg);
if (rc != 0) {
printf ("error in zmq_msg_close: %s\n", zmq_strerror (errno));
return -1;
}
rc = zmq_close (s);
if (rc != 0) {
printf ("error in zmq_close: %s\n", zmq_strerror (errno));
return -1;
}
/*rc = zmq_ctx_term (ctx);
if (rc != 0) {
printf ("error in zmq_ctx_term: %s\n", zmq_strerror (errno));
return -1;
}
ctx = NULL;
*/
return 0;
}
Please correct me if I am doing wrong.
Having solved the [Step 0], proposed above in the comment,
one ought
detect
a Missing ZMQ_SUBSCRIBE setup, thus SUB-side filters all traffic
ZMQ_SUBSCRIBE: Establish message filter
The ZMQ_SUBSCRIBE option shall establish a new message filter on a ZMQ_SUB socket. Newly created ZMQ_SUB sockets shall filter out all incoming messages, therefore you should call this option to establish an initial message filter.
An empty option_value of length zero shall subscribe to all incoming messages. A non-empty option_value shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.
Anyway, welcome & enjoy these smart tools for distributed systems computing!