Modify DACL to prevent everybody kill process without Debug Priveleges - c++

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

Related

WindowsIdentity.GetCurrent().IsSystem in C++

I need to know if the current process is running as system. In C# I use WindowsIdentity.GetCurrent().IsSystem to do that, what is the equivalent in C++?
I'm trying to avoid comparing usernames, because different OS has different usernames for SYSTEM account.
I have created an example based on Eryk's idea, and it works:
BOOL IsSystem()
{
HANDLE hToken = NULL;
BOOL result = false;
TOKEN_USER *tokenUser = NULL;
DWORD dwLength = 0;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == 0)
{
DbgPrint("OpenProcessToken(): %d", GetLastError());
goto cleanup;
}
if (GetTokenInformation(hToken, TokenUser, (LPVOID) tokenUser, 0, &dwLength) == 0)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
DbgPrint("GetTokenInformation(): %d", GetLastError());
goto cleanup;
}
tokenUser = (TOKEN_USER *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (tokenUser == NULL)
{
goto cleanup;
}
if (GetTokenInformation(hToken, TokenUser, (LPVOID) tokenUser, dwLength, &dwLength) == 0)
{
DbgPrint("GetTokenInformation(): %d", GetLastError());
goto cleanup;
}
result = IsWellKnownSid(tokenUser->User.Sid, WinLocalSystemSid);
}
cleanup:
if (tokenUser != NULL)
{
HeapFree(GetProcessHeap(), NULL, tokenUser);
}
return result;
}

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

Creating network device

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.

how to run following mailslots program in VC++

//writing to mailslot
#include <windows.h>
#include <stdio.h>
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
BOOL WriteSlot(HANDLE hSlot, LPTSTR lpszMessage)
{
BOOL fResult;
DWORD cbWritten;
fResult = WriteFile(hSlot,
lpszMessage,
(DWORD) (lstrlen(lpszMessage)+1)*sizeof(TCHAR),
&cbWritten,
(LPOVERLAPPED) NULL);
if (!fResult)
{
printf("WriteFile failed with %d.\n", GetLastError());
return FALSE;
}
printf("Slot written to successfully.\n");
return TRUE;
}
int main()
{
HANDLE hFile;
hFile = CreateFile(SlotName,
GENERIC_WRITE,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed with %d.\n", GetLastError());
return FALSE;
}
WriteSlot(hFile, TEXT("Message one for mailslot."));
WriteSlot(hFile, TEXT("Message two for mailslot."));
Sleep(5000);
WriteSlot(hFile, TEXT("Message three for mailslot."));
CloseHandle(hFile);
return TRUE;
}
//reading from mailslot
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
HANDLE hSlot;
LPTSTR SlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
BOOL ReadSlot()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPTSTR lpszBuffer;
TCHAR achID[80];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
if( NULL == hEvent )
return FALSE;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = hEvent;
fResult = GetMailslotInfo( hSlot, // mailslot handle
(LPDWORD) NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD) NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed with %d.\n", GetLastError());
return FALSE;
}
if (cbMessage == MAILSLOT_NO_MESSAGE)
{
printf("Waiting for a message...\n");
return TRUE;
}
cAllMessages = cMessage;
while (cMessage != 0) // retrieve all messages
{
// Create a message-number string.
StringCchPrintf((LPTSTR) achID,
80,
TEXT("\nMessage #%d of %d\n"),
cAllMessages - cMessage + 1,
cAllMessages);
// Allocate memory for the message.
lpszBuffer = (LPTSTR) GlobalAlloc(GPTR,
lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage);
if( NULL == lpszBuffer )
return FALSE;
lpszBuffer[0] = '\0';
fResult = ReadFile(hSlot,
lpszBuffer,
cbMessage,
&cbRead,
&ov);
if (!fResult)
{
printf("ReadFile failed with %d.\n", GetLastError());
GlobalFree((HGLOBAL) lpszBuffer);
return FALSE;
}
// Concatenate the message and the message-number string.
StringCbCat(lpszBuffer,
lstrlen((LPTSTR) achID)*sizeof(TCHAR)+cbMessage,
(LPTSTR) achID);
// Display the message.
_tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);
GlobalFree((HGLOBAL) lpszBuffer);
fResult = GetMailslotInfo(hSlot, // mailslot handle
(LPDWORD) NULL, // no maximum message size
&cbMessage, // size of next message
&cMessage, // number of messages
(LPDWORD) NULL); // no read time-out
if (!fResult)
{
printf("GetMailslotInfo failed (%d)\n", GetLastError());
return FALSE;
}
}
CloseHandle(hEvent);
return TRUE;
}
BOOL WINAPI MakeSlot(LPTSTR lpszSlotName)
{
hSlot = CreateMailslot(lpszSlotName,
0, // no maximum message size
MAILSLOT_WAIT_FOREVER, // no time-out for operations
(LPSECURITY_ATTRIBUTES) NULL); // default security
if (hSlot == INVALID_HANDLE_VALUE)
{
printf("CreateMailslot failed with %d\n", GetLastError());
return FALSE;
}
return TRUE;
}
void main()
{
MakeSlot(SlotName);
while(TRUE)
{
ReadSlot();
Sleep(3000);
}
}
Go through the Visual Studio C++ Guided Tour on MSDN or watch this introductory video explaining how to create a basic Win32 application in C++. They should be enough of a starting point. From there on just browse the MSDN library to advance your knowledge or search for issues you encounter.