Port availability check on remote system - port

How can I tell if a given port is available or not on a local or remote system, in an NSIS page?

Abuot COM ports:
They cannot be detected directly from NSIS so write simple plug-in in C which will detect port by it's number.
This is my basic idea:
void GetListOfLocalPorts(CList<CString, CString>& o_lstPorts)
{
for( int i = 1; i <= 99; i++ )
{
DCB dcb;
HANDLE hCom = NULL;
BYTE byPort = (BYTE)i;
CString strPort;
strPort.Format("COM%d", i);
CString strCom = (CString)"\\\\.\\" + strPort;
SetErrorMode(SEM_FAILCRITICALERRORS);
try
{
hCom = CreateFile(strCom, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hCom == INVALID_HANDLE_VALUE)
continue;
BOOL fSuccess = GetCommState(hCom, &dcb);
CloseHandle(hCom);
if (!fSuccess)
continue;
// Port exists on this machine
o_lstPorts.AddTail(strPort);
}
catch(...)
{
}
}
}

Related

How to set up a UNIX domain socket in iOS?

I am trying to set up a UNIX domain socket in iOS. According to https://iphonedevwiki.net/index.php/Unix_sockets, this is the code that I used to set up the socket on the server side:
const char *socket_path = "/var/run/myserver.socket";
// setup socket
struct sockaddr_un local;
strcpy(local.sun_path, socket_path);
unlink(local.sun_path);
local.sun_family = AF_UNIX;
int listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
printf("listenfd: %d\n", listenfd);
// start the server
int r = -1;
while(r != 0) {
r = bind(listenfd, (struct sockaddr*)&local, sizeof(local));
printf("bind: %d\n", r);
usleep(200 * 1000);
}
int one = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
// start listening for new connections
r = -1;
while(r != 0) {
r = listen(listenfd, 20);
printf("listen: %d\n", r);
usleep(200 * 1000);
}
// wait for new connection, and then process it
int connfd = -1;
while(true) {
if(connfd == -1) {
// wait for new connection
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
printf("new connfd: %d\n", connfd);
}
// process incoming data
char buffer[4096];
int len = recv(connfd, buffer, sizeof(buffer), 0);
if(len == 0) {
printf("connfd %d disconnected!\n", connfd);
connfd = -1;
continue;
} else {
printf("connfd %d recieved data: %s", connfd, buffer);
// send some data back (optional)
const char *response = "got it!\n";
send(connfd, response, strlen(response) + 1, 0);
}
}
However, when I run this code on my iPhone, I got this in the console:
listenfd: 3
bind: -1
bind: -1
bind: -1
bind: -1
bind: -1
...
It looks like there is a problem when we do bind() as it returns -1, I want to know what I am doing wrong in the code?
The errno is 1, which is OPERATION_NOT_PERMITTED
You are not allowed to create objects in /var/run on iOS. You need to put the socket in a directory where you are allowed to create objects, like FileManager.shared.temporaryDirectory.

wxWidgets serial Commuication

I have absolutely no experience in programming serial communication and since I'm stuck with my code I'd really appreciate your help! Thank you already!
So now to my problem:
I got a generator on which are several different sensors who communicate over CAN with a microcontroller. This mc itself communicates with a device from USBTin again over CAN. On the USBTin, a little board, is mainly a CAN controller and a microcontroller which are precoded from its developer.
So my task now is to open my COM Port, send the right messages to the USBTin (those are "S5" for the baudrate and 'O' for Open CAN) and then receive the data.
First of all the functions and my problem:
The problem is that in my output textfield stands something like "PPPPPPPPPP,Râö". There are always these 10 P's and some random characters. I have no idea where the P's or these additional "Râö" comes from. The actual output string shoud be something like "T1E18001F8". I tested that with hTerm, which is a terminal programm for serial communication.
OPEN:
long Serial::Open()
{
if (IsOpened()) return 0;
#ifdef UNICODE
wstring wtext(port.begin(),port.end());
#else
string wtext = port;
#endif
hComm = CreateFile(wtext.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE) {return 1;}
if (PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR |
PURGE_RXCLEAR) == 0) {return 2;}//purge
//get initial state
DCB dcbOri;
bool fSuccess;
fSuccess = GetCommState(hComm, &dcbOri);
if (!fSuccess) {return 3;}
DCB dcb1 = dcbOri;
dcb1.BaudRate = baud;
if (parity == 'E') dcb1.Parity = EVENPARITY;
else if (parity == 'O') dcb1.Parity = ODDPARITY;
else if (parity == 'M') dcb1.Parity = MARKPARITY;
else if (parity == 'S') dcb1.Parity = SPACEPARITY;
else if (parity == 'N') dcb1.Parity = NOPARITY;
dcb1.ByteSize = (BYTE)dsize;
if(stopbits==2) dcb1.StopBits = TWOSTOPBITS;
else if (stopbits == 1.5) dcb1.StopBits = ONE5STOPBITS;
else if (stopbits == 1) dcb1.StopBits = ONE5STOPBITS;
dcb1.fOutxCtsFlow = false;
dcb1.fOutxDsrFlow = false;
dcb1.fOutX = false;
dcb1.fDtrControl = DTR_CONTROL_DISABLE;
dcb1.fRtsControl = RTS_CONTROL_DISABLE;
fSuccess = SetCommState(hComm, &dcb1);
delay(60);
if (!fSuccess) {return 4;}
fSuccess = GetCommState(hComm, &dcb1);
if (!fSuccess) {return 5;}
osReader = { 0 };// Create the overlapped event. Must be closed before
exiting to avoid a handle leak.
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osReader.hEvent == NULL) {return 6;}// Error creating overlapped event;
abort.
fWaitingOnRead = FALSE;
osWrite = { 0 };
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL) {return 7;}
if (!GetCommTimeouts(hComm, &timeouts_ori)) { return 8; } // Error getting
time-outs.
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 20;
timeouts.ReadTotalTimeoutMultiplier = 15;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.WriteTotalTimeoutMultiplier = 15;
timeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hComm, &timeouts)) { return 9;} // Error setting time-
outs.
return 0;
}
WRITE:
bool Serial::Write(char *data)
{
if (!IsOpened()) {
return false;
}
BOOL fRes;
DWORD dwWritten;
long n = strlen(data);
if (n < 0) n = 0;
else if(n > 1024) n = 1024;
// Issue write.
if (!WriteFile(hComm, data, n, &dwWritten, &osWrite)) {
if (GetLastError() != ERROR_IO_PENDING) {fRes = FALSE;}// WriteFile
failed, but it isn't delayed. Report error and abort.
else {// Write is pending.
if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, TRUE))
fRes = FALSE;
else fRes = TRUE;// Write operation completed successfully.
}
}
else fRes = TRUE;// WriteFile completed immediately.
return fRes;
}
READCHAR:
char Serial::ReadChar(bool& success)
{
success = false;
if (!IsOpened()) {return 0;}
DWORD dwRead;
DWORD length=1;
BYTE* data = (BYTE*)(&rxchar);
//the creation of the overlapped read operation
if (!fWaitingOnRead) {
// Issue read operation.
if (!ReadFile(hComm, data, length, &dwRead, &osReader)) {
if (GetLastError() != ERROR_IO_PENDING) { /*Error*/}
else { fWaitingOnRead = TRUE; /*Waiting*/}
}
else {if(dwRead==length) success = true;}//success
}
//detection of the completion of an overlapped read operation
DWORD dwRes;
if (fWaitingOnRead) {
dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);
switch (dwRes)
{
// Read completed.
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hComm, &osReader, &dwRead, FALSE))
{/*Error*/ }
else {
if (dwRead == length) success = true;
fWaitingOnRead = FALSE;// Reset flag so that another
opertion
can be issued.
}// Read completed successfully.
break;
case WAIT_TIMEOUT:
// Operation isn't complete yet.
break;
default:
// Error in the WaitForSingleObject;
break;
}
}
return rxchar;
}
And Finally the excerpt of the main in wxWidgets to display the received data:
void GUI_1_2Frame::OnConnectButtonClick(wxCommandEvent& (event))
{
char tempString[10] = {0};
bool ReadChar_success = true;
char temp_Char;
/* Preset Serial Port setting */
Serial com(com_x, 115200, 8, NOPARITY, 1);
char* buffer;
if(connection_flag)
{
/* Port was connected, Disconnect Button unsed*/
com.Close();
wxMessageBox(_("Port closed"),_("Info!"),wxICON_INFORMATION);
connection_flag = 0;
ConnectButton->SetLabel("Connect");
TextCtrl1->SetValue("");
}
else
{
/* If open() == true -> INVALID HANDLE */
if(com.Open())
{
wxMessageBox(_("Port not available"),_("ERROR!"),wxICON_ERROR);
}
else /* Port Opened */
{
TextCtrl1->SetValue(com.GetPort());
ConnectButton->SetLabel("Disconnect");
connection_flag = 1;
}
if(com.Write("S5"))
{
TextCtrl1->SetValue("Baudrate sent!\n");
delay(100);
if(com.WriteChar('O'))
{
TextCtrl1->SetValue("Baudrate & Open Command sent!");
int i =0;
while(i<10)
{
temp_Char = com.ReadChar(ReadChar_success);
tempString[i] = temp_Char;
i++;
}
com.WriteChar('C');
com.Close();
//com.readSerialPort(data, MAX_DATA_LENGTH);
TextCtrl2->SetValue(tempString);
//wxMessageOutput::Get()->Printf("%s", tempString);
}
else
{
TextCtrl1->SetValue("Open Command Error!"); }
}
else
{
TextCtrl1->SetValue("Error!");
}
}
}
Since I am not native speaking englisch I say sorry for my language mistakes.
Thank everybody a lot and again I really appreciate every single hint!
Greetings,
MSol

Enumeration handle names issue

I found a way to enumerate other programs handles, but I have problem now. I can not see Process type threads. I need to check which programs open handles for my process.
When I check the output, it is "unnamed", I don't know how to fix it.
Should I do this via dirver? or any other way to do this without driver?
pid = _wtoi(argv[1]);
if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
{
printf("Could not open PID %d! (Don't try to open a system process.)\n", pid);
return 1;
}
handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
/* NtQuerySystemInformation won't give us the correct buffer size,
so we guess by doubling the buffer size. */
while ((status = NtQuerySystemInformation(
SystemHandleInformation,
handleInfo,
handleInfoSize,
NULL
)) == STATUS_INFO_LENGTH_MISMATCH)
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
if (!NT_SUCCESS(status))
{
printf("NtQuerySystemInformation failed!\n");
return 1;
}
for (i = 0; i < handleInfo->HandleCount; i++)
{
SYSTEM_HANDLE handle = handleInfo->Handles[i];
HANDLE dupHandle = NULL;
POBJECT_TYPE_INFORMATION objectTypeInfo;
PVOID objectNameInfo;
UNICODE_STRING objectName;
ULONG returnLength;
/* Check if this handle belongs to the PID the user specified. */
if (handle.ProcessId != pid)
continue;
/* Duplicate the handle so we can query it. */
if (!NT_SUCCESS(NtDuplicateObject(
processHandle,
handle.Handle,
GetCurrentProcess(),
&dupHandle,
0,
0,
0
)))
{
printf("[%#x] Error!\n", handle.Handle);
continue;
}
/* Query the object type. */
objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectTypeInformation,
objectTypeInfo,
0x1000,
NULL
)))
{
printf("[%#x] Error!\n", handle.Handle);
CloseHandle(dupHandle);
continue;
}
/* Query the object name (unless it has an access of
0x0012019f, on which NtQueryObject could hang. */
if (handle.GrantedAccess == 0x0012019f)
{
/* We have the type, so display that. */
printf(
"[%#x] %.*S: (did not get name)\n",
handle.Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
free(objectTypeInfo);
CloseHandle(dupHandle);
continue;
}
objectNameInfo = malloc(0x1000);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectNameInformation,
objectNameInfo,
0x1000,
&returnLength
)))
{
/* Reallocate the buffer and try again. */
objectNameInfo = realloc(objectNameInfo, returnLength);
if (!NT_SUCCESS(NtQueryObject(
dupHandle,
ObjectNameInformation,
objectNameInfo,
returnLength,
NULL
)))
{
/* We have the type name, so just display that. */
printf(
"[%#x] %.*S: (could not get name)\n",
handle.Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
free(objectTypeInfo);
free(objectNameInfo);
CloseHandle(dupHandle);
continue;
}
}
/* Cast our buffer into an UNICODE_STRING. */
objectName = *(PUNICODE_STRING)objectNameInfo;
/* Print the information! */
if (objectName.Length)
{
/* The object has a name. */
printf(
"[%#x] %.*S: %.*S\n",
handle.Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer,
objectName.Length / 2,
objectName.Buffer
);
}
else
{
/* Print something else. */
printf(
"[%#x] %.*S: (unnamed)\n",
handle.Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
}
free(objectTypeInfo);
free(objectNameInfo);
CloseHandle(dupHandle);
}
free(handleInfo);
CloseHandle(processHandle);
return 0;
void SearchMyProcessHandles()
{
ULONG UniqueProcessId = GetCurrentProcessId();
if (HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, UniqueProcessId))
{
NTSTATUS status;
union {
PSYSTEM_HANDLE_INFORMATION_EX pshi;
PVOID buf;
};
ULONG cb = 0x10000;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (buf = new UCHAR[cb += PAGE_SIZE])
{
if (0 <= (status = ZwQuerySystemInformation(SystemExtendedHandleInformation, buf, cb, &cb)))
{
if (ULONG_PTR NumberOfHandles = pshi->NumberOfHandles)
{
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX* Handles = pshi->Handles;
do
{
if (Handles->UniqueProcessId == UniqueProcessId &&
Handles->HandleValue == (ULONG_PTR)hProcess)
{
PVOID Object = Handles->Object;
Handles = pshi->Handles;
NumberOfHandles = pshi->NumberOfHandles;
do
{
if (Handles->Object == Object &&
Handles->UniqueProcessId != UniqueProcessId)
{
DbgPrint("%p %p %08x\n",
Handles->UniqueProcessId,
Handles->HandleValue,
Handles->GrantedAccess);
}
} while (Handles++, --NumberOfHandles);
break;
}
} while (Handles++, --NumberOfHandles);
}
}
delete [] buf;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
CloseHandle(hProcess);
}
}

How does my C application communicate with bluetoothctl?

In C language, I want to develop an application to run bluetoothctl, and then send command to it and receive the info, like we run bluetoothctl in console.
int main(void)
{
int fd, err = 0;
char* tty;
wait_pid = -1;
printf("BLEapp program start.......\r\n");
if (wait_pid == -1) {
printf("Start to run bluetoothctl......\r\n");
if ((pid = fork()) < 0) {
err = 1;
printf("Create new progress failed.\r\n");
}
else if (pid == 0) {
// Child progress, run as default when xid = 0x0 and mastAddr = 0x0
execl("/root/bluez-5.42/client/bluetoothctl", "bluetoothctl", NULL);
}
}
else {
printf("The child procress is still running.....\r\n");
err = 1;
}
//tty = ttyname(STDIN_FILENO);
//printf("stdin name is %s.\r\n", tty);
//fd = open(tty, O_WRONLY);
//if (fd < 0) {
// printf("Open stdin error..............\r\n");
//}
while (1) {
sleep(2);
fputs("devices\n", stdin);
//write(fd, "devices\n", 8);
}
return err;
}
I run bluetoothctl as child process, and want to send "devices\n" command to it, and read the listed devices. But it doesn't work.
Please help me to fix this problem.
Thanks.

How get trap with indy TidSNMP component

I'm using c++builderXE with Indy 10.5.7 and I'm trying to receive trap from another agent snmp.
I have no info describing how to do the program to receive trap.
Below you can find the snippet of code which I'm trying to use now.
The ReceiveTrap() method always return 0, which means non data received.
I tested the PC configuration with another program I made several years ago using spare API and the trap is received so I don't this it should be a configuration problem.
Have you some suggestions of hat I'm wrong in the routine below?
void __fastcall TForm1::LabelReceiveTrapClick(TObject * Sender)
{
static bool status = false;
int ists;
String Fun = "[SimpleReceiveTrap] ";
TSNMPInfo * infoSnmp = 0;
try
{
status = !status;
if (status)
{
std::auto_ptr< TIdSNMP >clientSnmp(new TIdSNMP(NULL));
clientSnmp->Community = "public";
clientSnmp->ReceiveTimeout = 1000;
clientSnmp->Binding->Port = 162;
while (status)
{
Application->ProcessMessages();
ists = clientSnmp->ReceiveTrap();
Mylog(L"%s ReceiveTrap status = [%d]", Fun.c_str(), ists);
if (ists > 0)
{
infoSnmp = clientSnmp->Trap;
}
}
}
}
catch (Exception & ex)
{
Mylog(L"%s ERROR", Fun.c_str(), ex.Message.c_str());
}
}
That is not the correct way to set the listening Port for receiving traps. Reading the Binding property allocates and binds a socket to a local IP/Port using the TIdSNMP::BoundIP and TIdSNMP::BoundPort properties. You can't change that socket's local Port after it has already been bound, so your assignment of the Binding->Port property is effectively a no-op.
For that matter, you are trying to manipulate the wrong socket anyway. The Binding socket is used for sending queries to the remote SNMP system. TIdSNMP uses a separate socket for receiving traps. TIdSNMP has a separate TrapPort property for specifying the listening Port of that socket. When the Binding is accessed, the trap socket is allocated and bound to Binding->IP and TIdSNMP::TrapPort. The TrapPort property defaults to 162.
std::auto_ptr< TIdSNMP >clientSnmp(new TIdSNMP(NULL));
clientSnmp->Community = "public";
clientSnmp->ReceiveTimeout = 1000;
clientSnmp->TrapPort = 162; // <--
...
ists = clientSnmp->ReceiveTrap();
Looking at Indy's changelog, there have been some trap-related changes to the listening socket since 10.5.7 was released, so you may need to upgrade to a newer Indy version to get bug fixes. Or you could download the latest version and then just add IdSNMP.pas to your project directly, at least.
Using only the Indi component I can't read the trap rev 2c
But I found a solution using TWSocket and TSNMPInfo which seems to works well
Belowe the code I used:
To get the data I use a TWSocket fro FPiette components suite:
void __fastcall TForm1::LabelStartServerTracSnmpClick(TObject * Sender)
{
String Fun = "[LabelStartServerTracSnmp] ";
try
{
if (WSocket1->State == wsClosed)
{
WSocket1->Proto = "udp";
WSocket1->Addr = "0.0.0.0";
WSocket1->Port = 162;
WSocket1->Listen();
}
else
{
WSocket1->Close();
}
}
catch (Exception & ex)
{
Mylog(L"%s ERROR: [%s]", Fun.c_str(), ex.Message.c_str());
}
}
To analyze the data received I use the Indy
void __fastcall TForm1::WSocket1DataAvailable(TObject * Sender, WORD ErrCode)
{
char buffer[1024];
int len, cnt, srcLen;
TSockAddrIn srcSocket;
String rcvmsg, remHost, s1, s2, Fun = "[WSocket1DataAvailable] ";
TIdSNMP * clientSnmp = NULL;
TSNMPInfo * infoSnmp = NULL;
try
{
srcLen = sizeof(srcSocket);
len = WSocket1->ReceiveFrom(buffer, sizeof(buffer), srcSocket, srcLen);
if (len >= 0)
{
buffer[len] = 0;
rcvmsg = String(buffer, len);
__try
{
clientSnmp = new TIdSNMP(NULL);
infoSnmp = new TSNMPInfo(clientSnmp);
infoSnmp->DecodeBuf(rcvmsg);
cnt = infoSnmp->ValueCount;
if (cnt > 0)
{
// ---------------------------------------------------
for (int idx = 0; idx < cnt; ++idx)
{
s1 = infoSnmp->ValueOID[idx];
s2 = infoSnmp->Value[idx];
Mylog(L"[%s] Trap : [%s] => [%s]", s1.c_str(), s2.c_str());
}
}
}
__finally
{
if (infoSnmp)
{
delete infoSnmp;
infoSnmp = 0;
}
if (clientSnmp)
{
delete clientSnmp;
clientSnmp = 0;
}
}
}
}
catch (Exception & ex)
{
Mylog(L"%s ERROR", Fun.c_str(), ex.Message.c_str());
}
}

Resources