Related
I have a C program (win32 api) which communicates to my Arduino Mega via serial (USB).
I can communicate to the Arduino fine via the IDE's serial monitor.
If I plug in my Arduino and run the C program, the port does not seem to be opened properly and there is no communication.
In this case, if I open the serial monitor from Arduino's IDE (or another serial program) and then close it again, the C program then works perfectly.
Here is my port code from the C program (in this example it is passed 5 as this is the port the Arduino is using):
CSerialPort.h:
#pragma once
#include <Windows.h>
#define CP_BAUD_RATE_1200 CBR_1200
#define CP_BAUD_RATE_9600 CBR_9600
#define CP_BAUD_RATE_1155 CBR_1155
#define CP_BAUD_RATE_4800 CBR_4800
#define CP_BAUD_RATE_19200 CBR_19200
#define CP_DATA_BITS_5 5
#define CP_DATA_BITS_6 6
#define CP_DATA_BITS_7 7
#define CP_DATA_BITS_8 8
#define CP_STOP_BITS_ONE ONESTOPBIT
#define CP_STOP_BITS_TWO TWOSTOPBITS
#define CP_STOP_BITS_ONE_AND_HALF ONE5STOPBITS
#define CP_PARITY_NOPARITY NOPARITY
#define CP_PARITY_ODD ODDPARITY
#define CP_PARITY_EVEN EVENPARITY
#define CP_PARITY_MARK MARKPARITY
#define CP_PARITY_SPACE SPACEPARITY
typedef HANDLE PORT;
PORT OpenPort(int idx);
void ClosePort(PORT com_port);
int SetPortBaudRate(PORT com_port, int rate);
int SetPortDataBits(PORT com_port, int databits);
int SetPortStopBits(PORT com_port, int stopbits);
int SetPortParity(PORT com_port, int parity);
int GetPortBaudRate(PORT com_port);
int GetPortDataBits(PORT com_port);
int GetPortStopBits(PORT com_port);
int GetPortParity(PORT com_port);
int SendData(PORT com_port,const char * data);
int ReciveData(PORT com_port, char * databuffer,int bufferlen);
CSerialPort.c
#include "CSerialPort.h"
#include <time.h>
PORT OpenPort(int idx)
{
HANDLE hComm;
TCHAR comname[100];
wsprintf(comname, TEXT("\\\\.\\COM%d"), idx);
hComm = CreateFile(comname, //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING,// Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
return NULL;
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE)
return NULL;
if (SetCommMask(hComm, EV_RXCHAR) == FALSE)
return NULL;
return hComm;
}
void ClosePort(PORT com_port)
{
CloseHandle(com_port);
}
int SetPortBaudRate(PORT com_port, int rate)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE BAUD STATE");
return FALSE;
dcbSerialParams.BaudRate = rate;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortDataBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE DATABITS STATE");
return FALSE;
dcbSerialParams.ByteSize = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortStopBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE STOP STATE");
return FALSE;
dcbSerialParams.StopBits = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortParity(PORT com_port, int parity)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE PARITY STATE");
return FALSE;
dcbSerialParams.Parity = parity;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int GetPortBaudRate(PORT com_port)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.BaudRate;
}
int GetPortDataBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.ByteSize;
}
int GetPortStopBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.StopBits;
}
int GetPortParity(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.Parity;
}
int SendData(PORT com_port, const char * data)
{
DWORD dNoOFBytestoWrite = strlen(data);
DWORD dNoOfBytesWritten;
BOOL Status = WriteFile(com_port,
data,
dNoOFBytestoWrite,
&dNoOfBytesWritten,
NULL);
if (Status == FALSE)
return -1;
return dNoOfBytesWritten;
}
int ReciveData(PORT com_port, char * data, int len)
{
DWORD dwEventMask;
DWORD NoBytesRead;
BOOL Status = WaitCommEvent(com_port, &dwEventMask, NULL);
if (Status == FALSE) {
return FALSE;
}
Status = ReadFile(com_port, data, len, &NoBytesRead, NULL);
data[NoBytesRead] = 0;
if (Status == FALSE) {
return FALSE;
}
return TRUE;
}
Test Code:
#include "CSerialPort.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
bool sendComms(char * msgSndPtr, int portNum)
{
auto p1 = OpenPort(portNum);
SetPortBaudRate(p1, CP_BAUD_RATE_9600);
SetPortDataBits(p1, CP_DATA_BITS_8);
SetPortStopBits(p1, CP_STOP_BITS_ONE);
SetPortParity(p1, CP_PARITY_NOPARITY);
SendData(p1, msgSndPtr);
ClosePort(p1);
printf("%s sent.\n", msgSndPtr); //debug
//strcpy(msgSndPtr,"");
return 1;
}
bool receiveComms(char * msgRecPtr, int portNum)
{
bool status = 0;
strcpy(msgRecPtr,"");
SetPortBaudRate(portNum, CP_BAUD_RATE_9600);
SetPortDataBits(portNum, CP_DATA_BITS_8);
SetPortStopBits(portNum, CP_STOP_BITS_ONE);
SetPortParity(portNum, CP_PARITY_NOPARITY);
auto p1 = OpenPort(portNum);
status = ReciveData(p1, msgRecPtr, 50);
ClosePort(p1);
if (!status) //if nothing is received, cancel out and show error
{
return 0;
}
else
{
printf("%s received.\n", msgRecPtr); //debug
return 1;
}
}
void main()
{
char msgRec[50];
char * msgRecPtr = msgRec;
char msgSnd[50];
char * msgSndPtr = msgSnd;
while (!(strcmp("end",msgRecPtr)))
{
sendComms(msgSndPtr, 5);
receiveComms(msgRecPtr, 5);
printf("sent: %s\n, msgSndPtr);
printf("received: %s\n, msgRecPtr);
}
}
The arduino code:
int i = 0;
void setup()
{
// Initiate Serial
Serial.begin(9600);
while (!Serial) ; // wait for serial port to connect. Needed for native USB
Serial.println("serial ready");
}
void loop()
{
Serial.println("testing comms");
i++
delay (150);
if (i == 10) {
Serial.println("end");
}
}
If anyone has had this problem using win32 or knows how the Serial Monitor opens it's port, that would be very helpful.
Edit: just to clarify, once the port has been opened once successfully (by any program apart from my C program), my C program then works fine and can open/close the port successfully until the next power cycle.
Thanks
I have fixed your code!
The major errors were:
Incorrect use of COM port number where a handle was required
Closing the port after sending data and before receiving response which flush input buffer
Almost no error check which prohibed to know what was wrong
In the test code, the main loop was incorrect. No data was sent and breaking the loop when "end" was received was wrong.
I moved COM port parametrization once after opening the port (could be inside OpenPort as well).
The way you handle receive is related to the communication protocol you define. I have not touched that part. If it would be my software, I would design the protocol as a line oriented protocol that is each message sent and received would be in the form of lines terminated by a CRLF pair. Receiving can then be in a loop, cumulating all characters until the end of line is found.
Here after the fixed source code. There are still plenty of romm for enhancement.
Test code:
#include "CSerialPort.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
bool SetComParameters(PORT comPort, int rate, int dataBits, int stopBits, int parity)
{
if (!SetPortBaudRate(comPort, CP_BAUD_RATE_9600)) {
fprintf(stderr, "Unable to set baudrate\n");
return 0;
}
if (!SetPortDataBits(comPort, CP_DATA_BITS_8)) {
fprintf(stderr, "Unable to set data bits\n");
return 0;
}
if (!SetPortStopBits(comPort, CP_STOP_BITS_ONE)) {
fprintf(stderr, "Unable to set stop bits\n");
return 0;
}
if (!SetPortParity(comPort, CP_PARITY_NOPARITY)) {
fprintf(stderr, "Unable to set parity\n");
return 0;
}
return 1;
}
bool sendComms(char* msgSndPtr, PORT comPort)
{
SendData(comPort, msgSndPtr);
return 1;
}
bool receiveComms(char* msgRecPtr, PORT comPort)
{
bool status = 0;
strcpy(msgRecPtr, "");
status = ReceiveData(comPort, msgRecPtr, 50);
return status;
}
void main()
{
char msgRec[50];
char* msgRecPtr = msgRec;
char msgSnd[50];
char* msgSndPtr = msgSnd;
int portNum = 1;
PORT com_port = OpenPort(portNum);
if (com_port == NULL) {
fprintf(stderr, "Unable to open COM%d\n", portNum);
return;
}
if (!SetComParameters(com_port, CP_BAUD_RATE_9600, CP_DATA_BITS_8, CP_STOP_BITS_ONE, CP_PARITY_NOPARITY)) {
fprintf(stderr, "Error setting parameters\n");
return;
}
do { // FPiette use of do/while instead of while loop
strcpy(msgSnd, "Hello\r\n");
if (!sendComms(msgSndPtr, com_port)) {
fprintf(stderr, "sendComs failed\n");
break;
}
printf("sent: %s\n", msgSndPtr);
if (!receiveComms(msgRecPtr, com_port)) {
fprintf(stderr, "receiveComms failed\n");
break;
}
printf("received: %s\n", msgRecPtr);
} while (strcmp("end", msgRecPtr));
ClosePort(&com_port);
printf("Done.\n");
}
CSerialPort.c:
#include <stdio.h>
#include "CSerialPort.h"
#include <time.h>
PORT OpenPort(int idx)
{
HANDLE hComm;
TCHAR comname[100];
wsprintf(comname, TEXT("\\\\.\\COM%d"), idx);
hComm = CreateFile(comname, //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING,// Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
return NULL;
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE)
return NULL;
if (SetCommMask(hComm, EV_RXCHAR) == FALSE)
return NULL;
return hComm;
}
void ClosePort(PORT* com_port)
{
if (com_port && *com_port) {
CloseHandle(*com_port);
*com_port = NULL;
}
}
int SetPortBaudRate(PORT com_port, int rate)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.BaudRate = rate;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortDataBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.ByteSize = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortStopBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.StopBits = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortParity(PORT com_port, int parity)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.Parity = parity;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int GetPortBaudRate(PORT com_port)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.BaudRate;
}
int GetPortDataBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.ByteSize;
}
int GetPortStopBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.StopBits;
}
int GetPortParity(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.Parity;
}
int SendData(PORT com_port, const char* data)
{
DWORD dNoOFBytestoWrite = strlen(data);
DWORD dNoOfBytesWritten;
BOOL Status = WriteFile(com_port,
data,
dNoOFBytestoWrite,
&dNoOfBytesWritten,
NULL);
if (Status == FALSE)
return -1;
return dNoOfBytesWritten;
}
int ReceiveData(PORT com_port, char* data, int len)
{
DWORD dwEventMask = 0;
DWORD NoBytesRead = 0;
BOOL Status = WaitCommEvent(com_port, &dwEventMask, NULL);
if (Status == FALSE)
return FALSE;
Status = ReadFile(com_port, data, len, &NoBytesRead, NULL);
if (Status == FALSE)
return FALSE;
data[NoBytesRead] = 0;
return TRUE;
}
CSerialPort.h:
#pragma once
#include <Windows.h>
#define CP_BAUD_RATE_1200 CBR_1200
#define CP_BAUD_RATE_9600 CBR_9600
#define CP_BAUD_RATE_1155 CBR_1155
#define CP_BAUD_RATE_4800 CBR_4800
#define CP_BAUD_RATE_19200 CBR_19200
#define CP_DATA_BITS_5 5
#define CP_DATA_BITS_6 6
#define CP_DATA_BITS_7 7
#define CP_DATA_BITS_8 8
#define CP_STOP_BITS_ONE ONESTOPBIT
#define CP_STOP_BITS_TWO TWOSTOPBITS
#define CP_STOP_BITS_ONE_AND_HALF ONE5STOPBITS
#define CP_PARITY_NOPARITY NOPARITY
#define CP_PARITY_ODD ODDPARITY
#define CP_PARITY_EVEN EVENPARITY
#define CP_PARITY_MARK MARKPARITY
#define CP_PARITY_SPACE SPACEPARITY
#define bool BOOL
typedef HANDLE PORT;
PORT OpenPort(int idx);
void ClosePort(PORT* com_port);
int SetPortBaudRate(PORT com_port, int rate);
int SetPortDataBits(PORT com_port, int databits);
int SetPortStopBits(PORT com_port, int stopbits);
int SetPortParity(PORT com_port, int parity);
int GetPortBaudRate(PORT com_port);
int GetPortDataBits(PORT com_port);
int GetPortStopBits(PORT com_port);
int GetPortParity(PORT com_port);
int SendData(PORT com_port, const char* data);
int ReceiveData(PORT com_port, char* databuffer, int bufferlen);
I'm Trying to test this Sagaan AntiCheat but i got bluescreen i use OSRLoader to load the driver and its load perfectly but when i open the .exe it's give me Blue Screen of Death https://prnt.sc/m9zl6o
the Source code of the FullProject https://github.com/SagaanTheEpic/Sagaan-AntiCheat-V2.0 I cant see where is the error can someone help me analyze this project that im trying to build. i want to recode it to add more features and make it better more.
#include <ntdef.h>
#include <ntifs.h>
#include <ntddk.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
#include <stdio.h>
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include <wdf.h>
#include <ntdef.h>
#include "BlackBone\VadRoutines.h"
#include "BlackBone\Routines.h"
#include "DriverIO.h"
#include "Formula.h"
DRIVER_INITIALIZE DriverEntry;
#pragma alloc_text(INIT, DriverEntry)
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
#define SYSTEM_PROCESS_ID (HANDLE)4
PVOID ObHandle = NULL;
ULONG ProtectedProcess = 0;
ULONG UsermodeAntiCheat = 0;
ULONG ProtectionThreads[7];
VOID CreateThreadNotifyRoutine(
IN HANDLE ProcessId,
IN HANDLE ThreadId,
IN BOOLEAN Create
);
// Terminating a process of your choice using the PID, usefull if the cheat is also using a driver to strip it's handles and therefore you can forcefully close it using the driver
NTSTATUS TerminateProcess(ULONG targetPid)
{
if (targetPid == ProtectedProcess)
{
ProtectedProcess = 0;
}
if (targetPid == UsermodeAntiCheat)
{
UsermodeAntiCheat = 0;
}
NTSTATUS NtRet = ((NTSTATUS)0x00000000L);
PEPROCESS PeProc = { 0 };
NtRet = PsLookupProcessByProcessId(targetPid, &PeProc);
if (NtRet != ((NTSTATUS)0x00000000L))
{
return NtRet;
}
HANDLE ProcessHandle;
NtRet = ObOpenObjectByPointer(PeProc, NULL, NULL, 25, *PsProcessType, KernelMode, &ProcessHandle);
if (NtRet != ((NTSTATUS)0x00000000L))
{
return NtRet;
}
ZwTerminateProcess(ProcessHandle, 0);
ZwClose(ProcessHandle);
return NtRet;
}
NTSTATUS DriverDispatchRoutine(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PVOID buffer;
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIo;
pIo = IoGetCurrentIrpStackLocation(pIrp);
pIrp->IoStatus.Information = 0;
switch (pIo->MajorFunction)
{
case IRP_MJ_CREATE:
NtStatus = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
NtStatus = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
break;
case IRP_MJ_CLOSE:
NtStatus = STATUS_SUCCESS;
break;
default:
NtStatus = STATUS_INVALID_DEVICE_REQUEST;
break;
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return NtStatus;
}
// This will be called, if the driver is unloaded or just returns something
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrintEx(0, 0, "UNLOADED \n");
UNICODE_STRING SACSymbolName;
RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
if (ObHandle)
{
ObUnRegisterCallbacks(ObHandle);
ObHandle = NULL;
}
PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
IoDeleteSymbolicLink(&SACSymbolName);
IoDeleteDevice(pDriverObject->DeviceObject);
}
NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
extern NTSTATUS PsLookupProcessByProcessId(
HANDLE ProcessId,
PEPROCESS *Process
);
typedef struct _OB_REG_CONTEXT {
USHORT Version;
UNICODE_STRING Altitude;
USHORT ulIndex;
OB_OPERATION_REGISTRATION *OperationRegistration;
} REG_CONTEXT, *PREG_CONTEXT;
OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;
if ((ULONG)PsGetCurrentProcessId() == UsermodeAntiCheat)
{
return OB_PREOP_SUCCESS;
}
if ((ULONG)PsGetCurrentProcessId() == ProtectedProcess)
{
return OB_PREOP_SUCCESS;
}
if (PsGetThreadProcessId(OperationInformation->Object) == UsermodeAntiCheat)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
else
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
}
else if (PsGetThreadProcessId(OperationInformation->Object) == ProtectedProcess)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
else
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
}
return OB_PREOP_SUCCESS;
}
OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (UsermodeAntiCheat == 0)
return OB_PREOP_SUCCESS;
if (ProtectedProcess == 0)
return OB_PREOP_SUCCESS;
PEPROCESS ProtectedProcessPEPROCESS;
PEPROCESS ProtectedUserModeACPEPROCESS;
PEPROCESS OpenedProcess = (PEPROCESS)OperationInformation->Object,
CurrentProcess = PsGetCurrentProcess();
ULONG ulProcessId = PsGetProcessId(OpenedProcess);
PsLookupProcessByProcessId(ProtectedProcess, &ProtectedProcessPEPROCESS);
PsLookupProcessByProcessId(ProtectedProcess, &ProtectedUserModeACPEPROCESS);
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;
if (ProtectedProcess != 0)
{
if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == ProtectedProcess)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
else
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
return OB_PREOP_SUCCESS;
}
}
if (UsermodeAntiCheat != 0)
{
if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == UsermodeAntiCheat)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
else
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
return OB_PREOP_SUCCESS;
}
}
return OB_PREOP_SUCCESS;
}
VOID CreateThreadNotifyRoutine(
IN HANDLE ProcessId,
IN HANDLE ThreadId,
IN BOOLEAN Create
)
{
if (!Create)
{
if (UsermodeAntiCheat == ProcessId)
{
for (int x = 0; x > 8; x++)
{
if ((ULONG)ThreadId == ProtectionThreads[x])
{
TerminateProcess(ProtectedProcess);
TerminateProcess(UsermodeAntiCheat);
}
}
}
if (ProtectedProcess == ProcessId)
{
}
}
}
VOID EnableCallBack()
{
NTSTATUS NtHandleCallback = STATUS_UNSUCCESSFUL;
NTSTATUS NtThreadCallback = STATUS_UNSUCCESSFUL;
OB_OPERATION_REGISTRATION OBOperationRegistration[2];
OB_CALLBACK_REGISTRATION OBOCallbackRegistration;
REG_CONTEXT regContext;
UNICODE_STRING usAltitude;
memset(&OBOperationRegistration, 0, sizeof(OB_OPERATION_REGISTRATION));
memset(&OBOCallbackRegistration, 0, sizeof(OB_CALLBACK_REGISTRATION));
memset(®Context, 0, sizeof(REG_CONTEXT));
regContext.ulIndex = 1;
regContext.Version = 120;
RtlInitUnicodeString(&usAltitude, L"1000");
if ((USHORT)ObGetFilterVersion() == OB_FLT_REGISTRATION_VERSION)
{
//OBOperationRegistration.ObjectType = PsProcessType; // Use To Strip Handle Permissions For Threads PsThreadType
//OBOperationRegistration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
//OBOperationRegistration.PostOperation = PostCallBack; // Giving the function which happens after creating
//OBOperationRegistration.PreOperation = PreCallback; // Giving the function which happens before creating
OBOperationRegistration[1].ObjectType = PsProcessType;
OBOperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OBOperationRegistration[1].PreOperation = ProcessPreCallback;
OBOperationRegistration[1].PostOperation = NULL;
OBOperationRegistration[0].ObjectType = PsThreadType;
OBOperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OBOperationRegistration[0].PreOperation = ThreadPreCallback;
OBOperationRegistration[0].PostOperation = NULL;
OBOCallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
OBOCallbackRegistration.OperationRegistrationCount = 2;
OBOCallbackRegistration.RegistrationContext = NULL;
OBOCallbackRegistration.OperationRegistration = &OBOperationRegistration;
NtHandleCallback = ObRegisterCallbacks(&OBOCallbackRegistration, &ObHandle); // Register The CallBack
PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
if (!NT_SUCCESS(NtHandleCallback))
{
if (ObHandle)
{
ObUnRegisterCallbacks(ObHandle);
ObHandle = NULL;
}
DbgPrintEx(0, 0, "Error: ObRegisterCallbacks Has Failed\n");
}
else
{
}
}
}
static ULONG KsecRandomSeed = 0x62b409a1;
NTSTATUS
NTAPI
KsecGenRandom(
PVOID Buffer,
SIZE_T Length)
{
LARGE_INTEGER TickCount;
ULONG i, RandomValue;
PULONG P;
/* Try to generate a more random seed */
KeQueryTickCount(&TickCount);
KsecRandomSeed ^= _rotl(TickCount.LowPart, (KsecRandomSeed % 23));
P = Buffer;
for (i = 0; i < Length / sizeof(ULONG); i++)
{
P[i] = RtlRandomEx(&KsecRandomSeed);
}
Length &= (sizeof(ULONG) - 1);
if (Length > 0)
{
RandomValue = RtlRandomEx(&KsecRandomSeed);
RtlCopyMemory(&P[i], &RandomValue, Length);
}
return STATUS_SUCCESS;
}
ULONG FOR1 = 100, FOR2 = 200, FOR3 = 300, FOR4 = 400, FOR5 = 500;
ULONG Encryption_Forward1 = 1, Encryption_Forward2 = 1, Encryption_Forward3 = 1, Encryption_Forward4 = 1, Encryption_Forward5 = 1;
BOOL Request_1 = FALSE;
BOOLEAN ProtectedGameRecieved = FALSE;
BOOLEAN UsermodeAntiCheatRecieved = FALSE;
NTSTATUS IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status;
ULONG BytesIO = 0;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
// Code received from user space
ULONG ControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
if (ControlCode == IO_SEND_CURRENTPROCESS && UsermodeAntiCheat < 1)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
UsermodeAntiCheat = ReadInput->UsermodeProgram;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
if ((ULONG)UsermodeAntiCheat == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
{
if (ControlCode == IO_SEND_PROCESSID && ProtectedGameRecieved == FALSE)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ProtectedProcess = ReadInput->GameProcess;
if (ProtectedProcess > 0)
{
ProtectedGameRecieved = TRUE;
}
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
else if (ControlCode == IO_PROTECTIONT_THREADS)
{
PKERNEL_THREAD_REQUEST ReadInput = (PKERNEL_THREAD_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ProtectionThreads[0] = ReadInput->ThreadID;
ProtectionThreads[1] = ReadInput->ThreadID2;
ProtectionThreads[2] = ReadInput->ThreadID3;
ProtectionThreads[3] = ReadInput->ThreadID4;
ProtectionThreads[4] = ReadInput->ThreadID5;
ProtectionThreads[5] = ReadInput->ThreadID6;
ProtectionThreads[6] = ReadInput->ThreadID7;
ProtectionThreads[7] = ReadInput->ThreadID8;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_THREAD_REQUEST);
}
else if (ControlCode == IO_TerminateProcess)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
TerminateProcess(ReadInput->UsermodeProgram);
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
else if (ControlCode == HEARTBEATMAINSTART_FORWARD)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
Encryption_Forward1 = ReadInput->Encrypt1;
Encryption_Forward2 = ReadInput->Encrypt2;
Encryption_Forward3 = ReadInput->Encrypt3;
Encryption_Forward4 = ReadInput->Encrypt4;
Encryption_Forward5 = ReadInput->Encrypt5;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == HEARTBEATMAINSTART_RETURN)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ReadInput->Encrypt1 = Formula1(Encryption_Forward1);
ReadInput->Encrypt2 = Formula2(Encryption_Forward2);
ReadInput->Encrypt3 = Formula3(Encryption_Forward3);
ReadInput->Encrypt4 = Formula4(Encryption_Forward4);
ReadInput->Encrypt5 = Formula5(Encryption_Forward5);
//DbgPrintEx(0, 0, "HEARTBEATMAINSTART_RETURN Called: Formula1(Encryption_Forward1) %d", Formula1(Encryption_Forward1));
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == HEARTBEATCREATEPROCESS_RETURN)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
KsecGenRandom(FOR1, sizeof(FOR1));
KsecGenRandom(FOR2, sizeof(FOR2));
KsecGenRandom(FOR3, sizeof(FOR3));
KsecGenRandom(FOR4, sizeof(FOR4));
KsecGenRandom(FOR5, sizeof(FOR5));
ReadInput->Encrypt1 = FOR1;
ReadInput->Encrypt2 = FOR2;
ReadInput->Encrypt3 = FOR3;
ReadInput->Encrypt4 = FOR4;
ReadInput->Encrypt5 = FOR5;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == IO_VADPROTECTION)
{
PHIDE_VAD ReadInput = (PHIDE_VAD)Irp->AssociatedIrp.SystemBuffer;
if (ReadInput->pid == ProtectedProcess || ReadInput == UsermodeAntiCheat)
{
// Enable it if you like. I dont need it so eh
//BBHideVAD(ReadInput);
}
Status = STATUS_SUCCESS;
BytesIO = sizeof(HIDE_VAD);
}
else if (ControlCode == HEARTBEATCREATEPROCESS_FORWARD)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
if (ReadInput->Encrypt1 == Formula1(FOR1))
{
if (ReadInput->Encrypt2 == Formula2(FOR2))
{
if (ReadInput->Encrypt3 == Formula3(FOR3))
{
if (ReadInput->Encrypt4 == Formula4(FOR4))
{
if (ReadInput->Encrypt5 == Formula5(FOR5))
{
//DbgPrintEx(0, 0, "Process Id ( IOCONTROL )%s\n", (ULONG)PsGetProcessId(IoGetCurrentProcess()));
Status = STATUS_SUCCESS;
// GOOD
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt5 == Formula5(FOR5) Encrypt: %s Formula: %s \n", ReadInput->Encrypt5, Formula5(FOR5));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt4 == Formula4(FOR4) Encrypt: %s Formula: %s \n", ReadInput->Encrypt4, Formula4(FOR4));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt3 == Formula3(FOR3) Encrypt: %s Formula: %s \n", ReadInput->Encrypt3, Formula3(FOR3));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt2 == Formula2(FOR2) Encrypt: %s Formula: %s \n", ReadInput->Encrypt2, Formula2(FOR2));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt1 == Formula1(FOR1) Encrypt: %s Formula: %s \n", ReadInput->Encrypt1, Formula1(FOR1));
}
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
}
else if ((ULONG)ProtectedProcess == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
{
if (ControlCode == IO_RETURNANTICHEATUSERMODE_PROCESSID_GMAE)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ReadInput->UsermodeProgram = UsermodeAntiCheat;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
}
// Complete the request
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesIO;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
// Driver's Main function. This will be called and looped through till returned, or unloaded.
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pUniStr)
{
DbgPrintEx(0, 0, "LOADED \n");
UNICODE_STRING SACDriverName, SACSymbolName;
NTSTATUS NtRet = STATUS_SUCCESS;
PDEVICE_OBJECT pDeviceObj;
RtlInitUnicodeString(&SACDriverName, L"\\Device\\SACDriver"); // Giving the driver a name
RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
UNICODE_STRING deviceNameUnicodeString, deviceSymLinkUnicodeString;
NTSTATUS NtRet2 = IoCreateDevice(pDriverObject, 0, &SACDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
IoCreateSymbolicLink(&SACSymbolName, &SACDriverName);
pDriverObject->MajorFunction[IRP_MJ_CREATE] = Create;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Close;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;
pDeviceObj->Flags |= DO_DIRECT_IO;
pDeviceObj->Flags &= (~DO_DEVICE_INITIALIZING);
pDriverObject->DriverUnload = DriverUnload;
EnableCallBack();
return NtRet;
}
Im not sure why i got bluescreen of death because of this rand() function.
#include "DLLInjectorDector.h"
#include "AbortFailureDetects.h"
#include "DriverLoader\\driver.h"
#include "DriverIO.h"
#include "openssl\\md5.h"
#include "DriverIORequests.h"
#include "Formulas.h"
#include "Anti Debug.h"
#include "DLLInjectionDetector\Utils.h"
#include "Utlis.h"
#include "NamePipe.h"
#include "DigitalSignatureChecker.h"
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <sys/types.h>
#include <signal.h>
#include <vector>
// Link with the Wintrust.lib file.
#pragma comment (lib, "wintrust")
// Varibles
HANDLE hDriver; // Driver
ULONG NamePipe1, NamePipe2, NamePipe3, NamePipe4, NamePipe5;
ULONG FOR1, FOR2, FOR3, FOR4, FOR5;
ULONG CHECK1, CHECK2, CHECK3, CHECK4, CHECK5;
ULONG CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5;
int GameProcessID = 0;
// Functions
bool CheckTestMode();
int randNum(int min, int max);
DWORD TidHeartBeat = 0;
DWORD TidGameValidChech = 0;
DWORD TidAntiDebug = 0;
DWORD tidDriverScanner = 0;
DWORD TidCommonCheatScanner = 0;
DWORD TidOverlayScanner = 0;
DWORD TidAntiKill = 0;
DWORD TidMainThread = 0;
BOOL HeartBeatThreadAntiKill = FALSE;
HANDLE hHeartBeatThread = NULL;
DWORD WINAPI HeartBeatThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
srand(time(0));
FOR1 = randNum(2, 63);
FOR2 = randNum(3, 34);
FOR3 = randNum(8, 45);
FOR4 = randNum(5, 67);
FOR5 = randNum(2, 12);
if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();
CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt1);
CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt2);
CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt3);
CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt4);
CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt5);
if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
{
if ( CUtils::IsSuspendedThread(TidMainThread))
{
ErrorHandler::ErrorMessage("63452 ( Thread Mismatched )", 6);
}
HeartBeatThreadAntiKill = TRUE;
Sleep(400);
}
else
{
ErrorHandler::ErrorMessage("601 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("602 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("603 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("604 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("605 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("606 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("607 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
return 0;
}
BOOL GameCheckerAntiKill = FALSE;
HANDLE hGameChecker = NULL;
DWORD WINAPI GameValidCheckThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (GameProcessID == 0)
{
Sleep(200);
}
else
{
if (!ErrorHandler::isProcessRunning(GameProcessID))
{
ErrorHandler::ErrorMessage("901 ( Game Stopped Running )", 3);
}
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("32156 ( Thread Mismatched )", 6);
}
GameCheckerAntiKill = TRUE;
}
}
BOOL AntiDebugAntiKill = FALSE;
HANDLE hAntiDebug = NULL;
DWORD WINAPI AntiDebugThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (AntiDebug::CheckRemoteDebuggerPresentAPI())
{
ErrorHandler::ErrorMessage("701", 6);
}
Sleep(200);
if (AntiDebug::IsDebuggerPresentAPI())
{
ErrorHandler::ErrorMessage("702", 6);
}
Sleep(200);
if (AntiDebug::HardwareBreakpoints())
{
ErrorHandler::ErrorMessage("703", 6);
}
Sleep(200);
if (AntiDebug::MemoryBreakpoints_PageGuard())
{
ErrorHandler::ErrorMessage("704", 6);
}
Sleep(200);
if (AntiDebug::UnhandledExcepFilterTest())
{
ErrorHandler::ErrorMessage("706", 6);
}
Sleep(200);
if (AntiDebug::SharedUserData_KernelDebugger())
{
ErrorHandler::ErrorMessage("707", 6);
}
Sleep(200);
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("34524 ( Thread Mismatched )", 6);
}
AntiDebugAntiKill = TRUE;
}
}
BOOL DriversScanAntiKill = FALSE;
HANDLE hDriversScan = NULL;
DWORD WINAPI DriversScanThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
LPVOID drivers[1024];
DWORD cbNeeded;
int cDrivers, i;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
{
/*
TCHAR szDriver[1024];
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++)
{
if (GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0])))
{
TCHAR szName[MAX_PATH] = { 0 };
GetDeviceDriverFileName(drivers[i], szName, MAX_PATH);
//_tprintf(TEXT("%d: %s\n"), i + 1, szName);
Sleep(10);
}
}*/
Sleep(100);
}
else
{
ErrorHandler::ErrorMessage("9753 ( Please Restart Your PC )", 5);
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("565435 ( Thread Mismatched )", 6);
}
DriversScanAntiKill = TRUE;
}
}
BOOL CommonCheatsScannerAntiKill = FALSE;
HANDLE hCommonCheatsScanner = NULL;
DWORD WINAPI CommonCheatsScannerThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
const char DebuggingDrivers[9][20] = {
"\\\\.\\EXTREM", "\\\\.\\ICEEXT",
"\\\\.\\NDBGMSG.VXD", "\\\\.\\RING0",
"\\\\.\\SIWVID", "\\\\.\\SYSER",
"\\\\.\\TRW", "\\\\.\\SYSERBOOT",
"\0"
};
for (int i = 0; DebuggingDrivers[i][0] != '\0'; i++) {
HANDLE h = CreateFileA(DebuggingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
if (h != INVALID_HANDLE_VALUE)
{
CloseHandle(h);
ErrorHandler::ErrorMessage("2001 ( Debugging Drivers Found )", 6);
}
CloseHandle(h);
Sleep(200);
}
const char CheatingDrivers[5][20] = {
"\\\\.\\kernelhop", "\\\\.\\BlackBone",
"\\\\.\\VBoxDrv", "\\\\.\\Htsysm72FB",
"\0"
};
for (int i = 0; CheatingDrivers[i][0] != '\0'; i++) {
HANDLE hCheats = CreateFileA(CheatingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
if (hCheats != INVALID_HANDLE_VALUE)
{
CloseHandle(hCheats);
ErrorHandler::ErrorMessage("3001 ( Cheating Drivers Found )", 2);
}
CloseHandle(hCheats);
Sleep(200);
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
}
CommonCheatsScannerAntiKill = TRUE;
Sleep(200);
}
}
BOOL OverlayScannerAntiKill = FALSE;
HANDLE hOverlayScanner = NULL;
DWORD WINAPI OverlayScannerThread()
{
// https://www.unknowncheats.me/forum/anti-cheat-bypass/263403-window-hijacking-dont-overlay-betray.html
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
OverlayFinderParams params;
params.style = WS_VISIBLE;
params.styleEx = WS_EX_LAYERED | WS_EX_TRANSPARENT;
params.percentMainScreen = 90.0f;
params.satisfyAllCriteria = true;
std::vector<HWND> hwnds = Utlis::OverlayFinder(params);
for (int i(0); i < hwnds.size(); ++i) {
DWORD ProcessIDForOverlay = 0;
DWORD tid = GetWindowThreadProcessId(hwnds[i], &ProcessIDForOverlay);
if (ErrorHandler::isProcessRunning(ProcessIDForOverlay))
{
DriverRequest::TerminatePrcoess(ProcessIDForOverlay);
Sleep(200);
}
Sleep(200);
}
OverlayScannerAntiKill = TRUE;
Sleep(200);
}
}
BOOL AntiKillBool = FALSE;
HANDLE hAntiKill = NULL;
DWORD WINAPI AntiKillThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (CUtils::IsSuspendedThread(TidHeartBeat)
|| CUtils::IsSuspendedThread(tidDriverScanner)
|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
|| CUtils::IsSuspendedThread(TidOverlayScanner)
|| CUtils::IsSuspendedThread(TidGameValidChech)
|| CUtils::IsSuspendedThread(TidMainThread)
|| CUtils::IsSuspendedThread(TidAntiDebug))
{
ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
}
else
{
Sleep(200);
}
}
}
bool IsSystemCodeIntegrityEnabled()
{
//https://stackoverflow.com/questions/40084077/can-i-have-any-way-to-detect-the-driver-signing-policy-status/50944791
typedef NTSTATUS(__stdcall* td_NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
struct SYSTEM_CODEINTEGRITY_INFORMATION {
ULONG Length;
ULONG CodeIntegrityOptions;
};
static td_NtQuerySystemInformation NtQuerySystemInformation = (td_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");
SYSTEM_CODEINTEGRITY_INFORMATION Integrity = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION), 0 };
NTSTATUS status = NtQuerySystemInformation(103, &Integrity, sizeof(Integrity), NULL);
return (status && (Integrity.CodeIntegrityOptions & 1));
}
void OnExit()
{
if (GameProcessID != 0)
{
if (ErrorHandler::isProcessRunning(GameProcessID))
{
DriverRequest::TerminatePrcoess(GameProcessID);
}
}
ErrorHandler::UnloadDriver();
}
int main()
{
using namespace std;
//FreeConsole();
InitializeDLLCheck();
InitializeThreadCheck();
TidMainThread = GetCurrentThreadId();
if (IsSystemCodeIntegrityEnabled())
{
ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
}
if (Utlis::IsRunAsAdministrator)
{
HANDLE CheckHandle = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (CheckHandle != INVALID_HANDLE_VALUE)
{
ErrorHandler::UnloadDriver();
CloseHandle(CheckHandle);
}
ErrorHandler::LoadDriver();
Sleep(100);
hDriver = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
//printf("File Size: %d \n", WhiteListedDLLs::GetFileSize("SAC-V2-DLL.dll"));
if (hDriver)
{
if (DriverRequest::SendCurrentProcessID())
{
hAntiDebug = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiDebugThread, NULL, 0, &TidAntiDebug);
srand(time(0));
FOR1 = randNum(1, 35);
FOR2 = randNum(1, 23);
FOR3 = randNum(1, 23);
FOR4 = randNum(1, 23);
FOR5 = randNum(1, 34);
if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();
ULONG TEST1 = HeartbeatFormula::Formula1(FOR1);
ULONG TEST2 = RETURNED_HEARTBEAT.Encrypt1;
if (RETURNED_HEARTBEAT.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
{
if (RETURNED_HEARTBEAT.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
{
if (RETURNED_HEARTBEAT.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
{
if (RETURNED_HEARTBEAT.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
{
if (RETURNED_HEARTBEAT.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();
CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1);
CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2);
CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3);
CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4);
CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5);
if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
{
hHeartBeatThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HeartBeatThread, NULL, 0, &TidHeartBeat);
hDriversScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DriversScanThread, NULL, 0, &tidDriverScanner);
hCommonCheatsScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommonCheatsScannerThread, NULL, 0, &TidCommonCheatScanner);
hOverlayScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OverlayScannerThread, NULL, 0, &TidOverlayScanner);
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PROCESS_INFORMATION ProcessInfo;
if (CreateProcess("D:\\SteamLibrary\\steamapps\\common\\Kingdom New Lands\\Kingdom.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
{
BlockInput(TRUE);
Utlis::Injection(L"SAC-V2-DLL.dll", ProcessInfo.dwProcessId);
GameProcessID = ProcessInfo.dwProcessId;
if (DriverRequest::SendProcessIDs(GameProcessID))
{
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
BlockInput(FALSE);
hGameChecker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GameValidCheckThread, NULL, 0, &TidGameValidChech);
hAntiKill = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiKillThread, NULL, 0, &TidAntiKill);
KERNEL_THREAD_REQUEST Threads;
Threads.ThreadID = TidAntiDebug;
Threads.ThreadID2 = TidHeartBeat;
Threads.ThreadID3 = tidDriverScanner;
Threads.ThreadID4 = TidCommonCheatScanner;
Threads.ThreadID5 = TidOverlayScanner;
Threads.ThreadID6 = TidGameValidChech;
Threads.ThreadID7 = TidAntiKill;
Threads.ThreadID8 = TidMainThread;
if (DriverRequest::SendProtectedThreadID(Threads))
{
while (1)
{
atexit(OnExit);
Sleep(4000);
if (CUtils::IsSuspendedThread(TidHeartBeat)
|| CUtils::IsSuspendedThread(tidDriverScanner)
|| CUtils::IsSuspendedThread(TidGameValidChech)
|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
|| CUtils::IsSuspendedThread(TidOverlayScanner)
|| CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("32947 ( Thread Mismatched )", 6);
}
if (IsSystemCodeIntegrityEnabled())
{
ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
}
if (OverlayScannerAntiKill && CommonCheatsScannerAntiKill && DriversScanAntiKill && AntiDebugAntiKill && HeartBeatThreadAntiKill)
{
OverlayScannerAntiKill = FALSE;
CommonCheatsScannerAntiKill = FALSE;
DriversScanAntiKill = FALSE;
AntiDebugAntiKill = FALSE;
HeartBeatThreadAntiKill = FALSE;
}
else
{
ErrorHandler::ErrorMessage("9452 ( Thread Mismatched )", 5);
}
}
}
else
{
BlockInput(FALSE);
ErrorHandler::ErrorMessage("43524 ( Thread Mismatched )", 5);
}
}
else
{
ErrorHandler::ErrorMessage("202 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("945 ( Failed To Start Game )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("207 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("206 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("205 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("204 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("203 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("249 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("201 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("301 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("67 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("1001 ( Run As Admin )", 1);
}
return 0;
}
int randNum(int min, int max)
{
return rand() % max + min;
}
I am using a generic write and read operations using the serial communication with R-232 connector to an external device.
For specific write operations, the readFile returns the data.
But for one command, it returns 0 bytes and GetLastError() returns 0.
I am using the application on a windows PDA.
Below is the code used:
long port = jport;
long baudrate = jbaudrate;
int cmd_length = env->GetStringLength(jcmd);
const jchar* cmd = env->GetStringChars(jcmd, 0);
zCommand = new char[cmd_length+1];
for (int j=0;j<cmd_length;j++)
zCommand[j] = (char)cmd[j];
zCommand[cmd_length]='\r';
env->ReleaseStringChars(jcmd,cmd);
WCHAR comPort[6];
wsprintf(comPort, L"COM%d:", port);
LPCTSTR pcCommPort = LPCTSTR( comPort );
hCom = CreateFile( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive-access
NULL, // default security attributes
OPEN_EXISTING,
0, // not overlapped I/O
NULL
);
if (hCom == INVALID_HANDLE_VALUE)
{
throw_executeCommand(env,"java/lang/Exception","INVALID_HANDLE_VALUE");
return env->NewStringUTF("");
}
//Clear all input output buffer
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
//Configure DCB
DCB PortDCB;
// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (hCom, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = baudrate; // Zera specified baud
PortDCB.ByteSize = 8;
PortDCB.StopBits = TWOSTOPBITS;
PortDCB.Parity = PARITY_NONE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fRtsControl = RTS_CONTROL_ENABLE | (RTS_CONTROL_TOGGLE ^ RTS_CONTROL_HANDSHAKE );
PortDCB.fAbortOnError = FALSE;
//Set Com Timeouts
COMMTIMEOUTS commTimeouts;
if(!GetCommTimeouts(hCom, &commTimeouts))
{
throw_executeCommand(env,"java/lang/Exception","Exception GetCommTimeouts");
return env->NewStringUTF("");
}
commTimeouts.ReadIntervalTimeout = 50;
commTimeouts.ReadTotalTimeoutMultiplier = 10;
commTimeouts.ReadTotalTimeoutConstant = 50;
commTimeouts.WriteTotalTimeoutConstant = 50;
commTimeouts.WriteTotalTimeoutMultiplier = 10;
if(!SetCommTimeouts(hCom, &commTimeouts))
{
throw_executeCommand(env,"java/lang/Exception","Exception SetCommTimeouts");
return env->NewStringUTF("");
}
if (!SetCommState (hCom, &PortDCB))
{
throw_executeCommand(env,"java/lang/Exception","Exception SetCommState");
return env->NewStringUTF("");
}
unsigned long numBytesWritten;
unsigned long numBytesRead;
BOOL bWriteResult;
bWriteResult = WriteFile(hCom,zCommand, sizeof (zCommand),&numBytesWritten,NULL);
if (!bWriteResult)
{
throw_executeCommand(env,"java/lang/Exception","Exception WriteFile");
return env->NewStringUTF("");
}
//Time to read
string result="";
BOOL bReadResult; //AAV,ARC,AGR1
char sBuffer[128];
BOOL datafound;
numBytesRead = 0;
while(true)
{
bReadResult = ReadFile(hCom, &sBuffer, 128, &numBytesRead, NULL);
if (numBytesRead > 0)
{
for (int i=0;i<(int)numBytesRead;i++)
{
datafound = TRUE;
if (sBuffer[i]=='\r')
{
result += '\n';
}else
{
result += sBuffer[i];
}
}
}
else
{
break;
}
}
if (datafound)
{
if (hCom != INVALID_HANDLE_VALUE)
{
cleanup_executeCommand();
return env->NewStringUTF(result.c_str());
}
}
cleanup_executeCommand();
throw_executeCommand(env,"java/lang/Exception","err");
return env->NewStringUTF("");
I try to build a service that monitor user sessions activity. currently focusing on logon and lock of user.
i am using http://msdn.microsoft.com/en-us/library/bb540475(v=VS.85).aspx example
my code :
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#pragma comment(lib, "advapi32.lib")
#define SVCNAME TEXT("SvcName")
#define SVC_ERROR 4
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
HANDLE ghSvcStopEvent = NULL;
VOID SvcInstall(void);
DWORD WINAPI SvcCtrlHandler(DWORD , DWORD , LPVOID , LPVOID );
VOID WINAPI SvcMain(DWORD, LPTSTR *);
VOID ReportSvcStatus(DWORD, DWORD, DWORD);
VOID SvcInit(DWORD, LPTSTR *);
VOID SvcReportEvent(LPTSTR);
void __cdecl _tmain(int argc, TCHAR *argv[])
{
if (lstrcmpi(argv[1], TEXT("install")) == 0)
{
SvcInstall();
return;
}
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher(DispatchTable))
{
SvcReportEvent(TEXT("StartServiceCtrlDispatcher"));
}
}
VOID SvcInstall()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if (!GetModuleFileName(NULL, szPath, MAX_PATH))
{
printf("Cannot install service (%d)\n", GetLastError());
return;
}
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Create the service
schService = CreateService(
schSCManager, // SCM database
SVCNAME, // name of service
SVCNAME, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL)
{
printf("CreateService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else printf("Service installed successfully\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME,SvcCtrlHandler,NULL);
OutputDebugString(L"\n***SVCMAIN");
if (!gSvcStatusHandle)
{
SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
return;
}
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
SvcInit(dwArgc, lpszArgv);
}
VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv)
{
FILE *f = fopen("c:\\test\\file.txt", "a");
OutputDebugString(L"\n***SVCINIT");
fprintf(f, "init\n");
fclose(f);
ghSvcStopEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not signaled
NULL); // no name
if (ghSvcStopEvent == NULL)
{
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
while (WaitForSingleObject(ghSvcStopEvent, 3000) != WAIT_OBJECT_0){
OutputDebugString(L"\n***BEEP");
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "beep\n");
fclose(f);
Beep(1000, 100);
}
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
}
VOID ReportSvcStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
DWORD my_error = 0;
// Fill in the SERVICE_STATUS structure.
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_SESSIONCHANGE | SERVICE_ACCEPT_STOP;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED)){
gSvcStatus.dwCheckPoint = 0;
}
else gSvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
my_error = GetLastError();
FILE *f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "last error %d \n",my_error);
fprintf(f, "\n***controls accepted %d ***\n", gSvcStatus.dwControlsAccepted);
fclose(f);
}
DWORD WINAPI SvcCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
DWORD dwErrorCode = NO_ERROR;
FILE *f = fopen("c:\\test\\file.txt", "a");
// Handle the requested control code.
fprintf(f, "dwCtrl is = %d \n", dwControl);
fclose(f);
switch (dwControl)
{
case SERVICE_CONTROL_TIMECHANGE:
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "time\n");
fclose(f);
OutputDebugString(L"\n****GOT time!!!\n\n");
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
break;
case SERVICE_CONTROL_SESSIONCHANGE:
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "session\n");
fclose(f);
OutputDebugString(L"\n****GOT Session!\n\n");
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
break;
case SERVICE_CONTROL_STOP:
OutputDebugString(L"\n****GOT STOP!\n\n");
f = fopen("c:\\test\\file.txt", "a");
fprintf(f, "stop\n");
fclose(f);
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
return;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
VOID SvcReportEvent(LPTSTR szFunction)
{
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
TCHAR Buffer[80];
hEventSource = RegisterEventSource(NULL, SVCNAME);
if (NULL != hEventSource)
{
StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction, GetLastError());
lpszStrings[0] = SVCNAME;
lpszStrings[1] = Buffer;
ReportEvent(hEventSource, // event log handle
EVENTLOG_ERROR_TYPE, // event type
0, // event category
SVC_ERROR, // event identifier
NULL, // no security identifier
2, // size of lpszStrings array
0, // no binary data
lpszStrings, // array of strings
NULL); // no binary data
DeregisterEventSource(hEventSource);
}
}
any ideas why i am not getting any "case SERVICE_CONTROL_SESSIONCHANGE" and only stop?
in my log file i see the beep log and controls accepted - 129 (stop + session change)
this is my log file content :
last error 0
***controls accepted 129 ***
init
last error 0
***controls accepted 129 ***
beep
beep
beep
beep
beep
gSvcStatusHandle = RegisterServiceCtrlHandler(SVCNAME,SvcCtrlHandler,NULL);
should be :
gSvcStatusHandle = RegisterServiceCtrlHandlerEx(SVCNAME,SvcCtrlHandler,NULL);
I tried to write a small event-based application in C for serial port reading (sources below). My program is to use the WinApi functions. The comport.c has the functions written to handle COM-port (open, read, write), the utils.c has some helper functions.
My program produces always the following output:
COM1 is selected to be listened.
GetCommMask result: 0x00000029 (EV_RXCHAR: 0x0001, EV_CTS: 0x0008, EV_RLSD: 0x0020)
Press any key to proceed...
I/O is pending (WaitCommEvent)...
I/O is pending (WaitCommEvent)...
I/O is pending (WaitCommEvent)...
I/O is pending (WaitCommEvent)...
I/O is pending (WaitCommEvent)...
It seems, that the function WaitCommEvent fails, the GetLastError() gives back error 87 (I/O pending).
Please help me to find out what the problem is, which parameter is invalid? See below the code.
The main.c:
#include "stdafx.h"
#include "comport.h"
#include "utils.h"
#include <conio.h>
#define READ_BUFF_MAX_LENGTH 1024
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwEvtMask;
HANDLE hComPort;
OVERLAPPED oEventHandler;
int portNum;
DWORD readTotal;
BOOL bOverlappedPending = FALSE;
char readBuff[READ_BUFF_MAX_LENGTH];
if(2 > argc)
{
printf("Use the program: ZliFuerZlvbusInterface.exe XXX (where XXX is the number of com port), \r\ne.G. for COM1 -> ZliFuerZlvbusInterface.exe 1\r\n");
return 1;
}
else
{
portNum = atoi(argv[1]);
if(0 == IsValidComNumber(portNum))
{
printf("ERROR: COM port number %d is invalid (parsed from '%s').\r\n", portNum, argv[1]);
return 2;
}
else
{
printf("COM%d is selected to be listened.\r\n", portNum);
}
}
if(0 == CreateSerialConnection(&hComPort, &oEventHandler, portNum, 1200, 8, EVEN, STOP1))
{
return 3;
}
if(FALSE == GetCommMask(hComPort, &dwEvtMask))
{
printf("GetCommMask failed with error:\r\n");
PrintLastErrorText();
return 4;
}
else
{
printf("GetCommMask result: 0x%08X (EV_RXCHAR: 0x0001, EV_CTS: 0x0008, EV_RLSD: 0x0020)\r\n", dwEvtMask);
}
printf("Press any key to proceed...\r\n");
getch();
while(1)
{
if(0 != kbhit())
{
if(27 == getch()) // ESC pressed
{
printf("Key ESC pressed, exiting...\r\n");
break;
}
}
bOverlappedPending = FALSE;
readTotal = 0;
if(TRUE == WaitCommEvent(hComPort, &dwEvtMask, &oEventHandler))
{
if(dwEvtMask & EV_CTS) // Clear-to-send signal present
{
PrintCurrentDateTime();
printf("COM%d: Clear-to-send signal set\r\n", portNum);
}
if(dwEvtMask & EV_RLSD) // Data-carrier-detect signal present
{
PrintCurrentDateTime();
printf("COM%d: Data-carrier-detect signal set\r\n", portNum);
}
if(dwEvtMask & EV_RXCHAR) // Data received
{
ReadSerial(&hComPort, &oEventHandler, portNum, readBuff, READ_BUFF_MAX_LENGTH);
}
}
else
{
if(ERROR_IO_PENDING == GetLastError())
{
printf("I/O is pending (WaitCommEvent)...\r\n");
bOverlappedPending = TRUE;
}
else
{
printf("WaitCommEvent failed with error:\r\n");
PrintLastErrorText();
}
}
if(TRUE == bOverlappedPending)
{
if(FALSE == GetOverlappedResult(hComPort, &oEventHandler, &readTotal, TRUE))
{
printf("GetOverlappedResult failed with error:\r\n");
PrintLastErrorText();
}
}
}
CloseSerialConnection(&hComPort);
return 0;
}
The comport.c:
#include <stdio.h>
#include "comport.h"
#include "utils.h"
int IsValidComNumber(int com)
{
if ((com < 1) ||
(com > 256))
{
return 0;
}
return 1;
}
int IsValidBaud(int baud)
{
switch(baud)
{
case CBR_110:
case CBR_300:
case CBR_600:
case CBR_1200:
case CBR_2400:
case CBR_4800:
case CBR_9600:
case CBR_14400:
case CBR_19200:
case CBR_38400:
case CBR_56000:
case CBR_57600:
case CBR_115200:
case CBR_128000:
case CBR_256000:
{
return 1;
break;
}
default:
{
break;
}
}
return 0;
}
int IsValidBits(int bits)
{
if ((bits < 5) ||
(bits > 8))
{
return 0;
}
else
{
return 1;
}
}
int CreateSerialConnection(HANDLE* handle, OVERLAPPED* overlapped, int portNumber, int baud, int bits, enum ParType parity, enum StopType stopbits)
{
DCB dcb;
COMMTIMEOUTS timeouts;
TCHAR portVirtualFile[32];
// For serial port name this format must be used (as virtual file): "\\\\.\\COMx"
memset(portVirtualFile, 0, 32);
#ifdef _UNICODE
swprintf(portVirtualFile, 32, L"\\\\.\\COM%d", portNumber);
#else
sprintf_s(portVirtualFile, 32, "\\\\.\\COM%d", portNumber);
#endif
if(0 == IsValidBaud(baud))
{
printf("ERROR: Specified baud rate %d is invalid for serial connection to COM%d.\r\n", baud, portNumber);
return 0;
}
if(0 == IsValidBits(bits))
{
printf("ERROR: Specified number of data bits %d is invalid for serial connection to COM%d.\r\n", bits, portNumber);
return 0;
}
*handle = CreateFile(portVirtualFile, // Specify port device
GENERIC_READ | GENERIC_WRITE, // Specify mode that open device.
0, // the devide isn't shared.
NULL, // the object gets a default security.
OPEN_EXISTING, // Specify which action to take on file.
FILE_FLAG_OVERLAPPED, // Use overlapped I/O.
NULL); // default.
if(*handle == INVALID_HANDLE_VALUE)
{
printf("ERROR: Opening serial port COM%d failed\r\n", portNumber);
return 0;
}
if(FALSE == GetCommState(*handle, &dcb))
{
printf("ERROR: Getting current state of COM%d\r\n", portNumber);
PrintLastErrorText();
return 0;
}
memset(&dcb, 0, sizeof(dcb)); //zero initialize the structure
dcb.DCBlength = sizeof(dcb); //fill in length
dcb.BaudRate = baud; // baud rate
dcb.ByteSize = bits; // data size, xmit and rcv
dcb.Parity = parity; // parity bit
dcb.StopBits = stopbits; // stop bits
if(FALSE == SetCommState(*handle, &dcb))
{
printf("ERROR: Setting new state of COM%d failed.\r\n", portNumber);
PrintLastErrorText();
return 0;
}
if(FALSE == SetCommMask(*handle, EV_RXCHAR | EV_CTS | EV_RLSD))
{
printf("ERROR: Setting new COM MASK (events) for COM%d failed.\r\n", portNumber);
PrintLastErrorText();
return 0;
}
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if(FALSE == SetCommTimeouts(*handle, &timeouts))
{
printf("ERROR: Setting timeout parameters for COM%d failed.\r\n", portNumber);
PrintLastErrorText();
return 0;
}
(*overlapped).hEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // not signaled
NULL // no name
);
if(NULL == overlapped->hEvent)
{
printf("ERROR: CreateEvent for COM%d failed.\r\n", portNumber);
PrintLastErrorText();
return 0;
}
// Initialize the rest of the OVERLAPPED structure to zero.
overlapped->Internal = 0;
overlapped->InternalHigh = 0;
overlapped->Offset = 0;
overlapped->OffsetHigh = 0;
return 1;
}
int CloseSerialConnection(HANDLE* handle)
{
if(FALSE == CloseHandle(*handle))
{
printf("ERROR: Cannot close handle 0x8.8%X\r\n", *handle);
PrintLastErrorText();
return 0;
}
*handle = NULL;
return 1;
}
int ReadSerial(HANDLE* handle, LPOVERLAPPED ov, int num, char* buffer, int max_len)
{
DWORD readTotal = 0;
if(FALSE == ClearCommError(*handle, NULL, NULL))
{
printf("ClearCommError failed with error:\r\n");
PrintLastErrorText();
return 0;
}
else
{
memset(buffer, 0, max_len);
if(FALSE == ReadFile(*handle, buffer, max_len, &readTotal, ov))
{
printf("ERROR: Reading from port COM%d failed\r\n", num);
if(ERROR_IO_PENDING == GetLastError())
{
printf("I/O is pending (ReadFile)...\r\n");
if(FALSE == GetOverlappedResult(*handle, ov, &readTotal, TRUE))
{
printf("GetOverlappedResult failed with error:\r\n");
PrintLastErrorText();
return 0;
}
}
else
{
PrintLastErrorText();
return 0;
}
}
else
{
PrintCurrentDateTime();
printf("Received %d characters on port COM%d: ", readTotal, num);
PrintBufferContent(buffer, readTotal);
}
}
return 1;
}
The utils.c:
#include <Windows.h>
#include <stdio.h>
#include "utils.h"
void PrintLastErrorText(void)
{
DWORD retSize;
LPTSTR pTemp = NULL;
retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&pTemp, 0, NULL);
if ((retSize > 0) &&
(pTemp != NULL))
{
printf("Last error: %s (0x%08X)\r\n", pTemp, GetLastError());
LocalFree((HLOCAL)pTemp);
}
}
void PrintCurrentDateTime(void)
{
SYSTEMTIME systime;
GetLocalTime(&systime);
printf("%04d.%02d.%02d %02d:%02d:%02d:%03d ", systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
}
void PrintBufferContent(char* buff, int len)
{
int i;
for(i = 0; i<len; i++)
{
printf("%02X ", buff[i]);
}
}
You're using the same OVERLAPPED structure for WaitCommEvent and ReadFile. Try using separate/independent OVERLAPPED for each.
UPDATE: Ignore that previous answer.
If your call to WaitCommEvent returns ERROR_IO_PENDING, you're not waiting for it to complete. Rather than loop around and call WaitCommEvent again, you need to wait for the operation to complete (typically via GetOverlappedResult).
You cannot have multiple pending asynchronous requests share a single OVERLAPPED structure. By looping and calling WaitCommEvent again after ERROR_IO_PENDING, that's exactly what's happening.