in windows 10, redirect port monitor (redmon), run as user doesn't work - pdf

I have a redirected printer port that use redmon (redirect port monitor) with a postscript printer driver to convert postscript to pdf and apply some other effects like watermarks, overlays, etc.
In win 7 all work fine but in windows 10 the process run under system user account.
In the configuration window of the printer port there is a flag called "Run as user" and in win7, checking this flag let the job running under the user account.
In Windows 10 it seems not working.
Any suggestion will be very appreciated.
Thank you.
Roy

I had a similar problem. I needed the user that printed the document to select the type of document and a patient ID. Then print the document to our EHR system as a PDF. Works in Windows 7 when "Run as User" is checked, but not on Windows 10. Redmon always runs the program as "SYSTEM". So I added a bit to the beginning of the program to check the user name. If it is "SYSTEM" the program looks for the an interactive user on the system by finding an instance of explorer.exe. If more than one interactive user is logged onto the system this will fail. Not a problem for my task. The program then starts another instance of itself running as the same user as explorer.exe, passing the same command line. A pipe is used so that stdin from the first instance can be piped to stdin on the second instance. Another limitation is that on a 64 bit OS, a 64 bit version of the program must be used. Otherwise explorer.exe may not be found.
The following code is what I placed at the beginning of my program. Don't be fooled by the program starting at main(). I am using a GUII toolkit that has WinMain() in it and then calls main(). I have only tested the code on ASCII programs. I tried to use the ASCII version of calls so that it would work with non-ASCII programs, but I am not sure I got all of them.
The LogInfoSys("Hello World"); function just writes to a log file.
Good luck.
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <direct.h>
#include <process.h>
#include <sqlext.h>
#include <Psapi.h>
#include <tlhelp32.h>
int main(int argc, char *argv[])
{
int error;
char msg[1024];
DWORD *processIDs;
int processCount;
HANDLE hProcess = NULL;
HANDLE hToken;
char userName[64];
char progName[1024];
int i, j;
char nameMe[256];
char domainMe[256];
PTOKEN_USER ptuMe = NULL;
PROCESS_INFORMATION procInfo;
STARTUPINFO startUpInfo;
HMODULE *hMod;
DWORD cbNeeded;
SECURITY_ATTRIBUTES saAttr;
HANDLE hChildStd_IN_Rd = NULL;
HANDLE hChildStd_IN_Wr = NULL;
i = 64; // Get user name, if it is "SYSTEM" redirect input to output to a new instance of the program
GetUserNameA(userName, &i);
if (_stricmp(userName, "system") == 0)
{
LogInfoSys("Running as SYSTEM");
processIDs = (DWORD *)calloc(16384, sizeof(DWORD)); // Look for explorer.exe running. If found that should be the user we want to run as.
EnumProcesses(processIDs, sizeof(DWORD) * 16384, &i); // If there is more than one that is OK as long as they are both being run by the same
processCount = i / sizeof(DWORD); // user. If more than one user is logged on, this will be a problem.
hMod = (HMODULE *)calloc(4096, sizeof(HMODULE));
hProcess = NULL;
for (i = 0; (i < processCount) && (hProcess == NULL); i++)
{
if (processIDs[i] == 11276)
Sleep(0);
if (processIDs[i] != 0)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);
if (hProcess != NULL)
{
cbNeeded = 0;
error = EnumProcessModules(hProcess, hMod, sizeof(HMODULE) * 4096, &cbNeeded);
if (error == 0)
{
error = GetLastError();
Sleep(0);
}
progName[0] = 0;
error = GetModuleBaseNameA(hProcess, hMod[0], progName, 1024);
if (error == 0)
{
error = GetLastError();
Sleep(0);
}
if (_stricmp(progName, "explorer.exe") != 0)
{
CloseHandle(hProcess);
hProcess = NULL;
}
else
{
LogInfoSys("Found explorer.exe");
}
}
}
}
LogInfoSys("After looking for processes.");
nameMe[0] = domainMe[0] = 0;
if (hProcess != NULL)
{
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0)) // Create a pipe for the child process's STDIN.
LogInfoSys("Stdin CreatePipe error");
if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) // Ensure the write handle to the pipe for STDIN is not inherited.
LogInfoSys("Stdin SetHandleInformation errir");
if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken) != 0)
{
GetStartupInfo(&startUpInfo);
startUpInfo.cb = sizeof(STARTUPINFO);
startUpInfo.lpReserved = NULL;
startUpInfo.lpDesktop = NULL;
startUpInfo.lpTitle = NULL;
startUpInfo.dwX = startUpInfo.dwY = 0;
startUpInfo.dwXSize = 0;
startUpInfo.dwYSize = 0;
startUpInfo.dwXCountChars = 0;
startUpInfo.dwYCountChars = 0;
startUpInfo.dwFillAttribute = 0;
startUpInfo.dwFlags |= STARTF_USESTDHANDLES;
startUpInfo.wShowWindow = 0;
startUpInfo.cbReserved2 = 0;
startUpInfo.lpReserved = NULL;
startUpInfo.hStdInput = hChildStd_IN_Rd;
startUpInfo.hStdOutput = NULL;
startUpInfo.hStdError = NULL;
GetModuleFileName(NULL, progName, 1024);
i = CreateProcessAsUserA(hToken, progName, GetCommandLine(), NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo, &procInfo);
if (i == 0)
{
i = GetLastError();
}
do
{
i = (int)fread(msg, 1, 1024, stdin);
if (i > 0)
WriteFile(hChildStd_IN_Wr, msg, i, &j, NULL);
} while (i > 0);
}
}
LogInfoSys("End of running as SYSTEM.");
exit(0);
}
/**********************************************************************************************************
*
* End of running as SYSTEM and start of running as the user that printed the document (I hope).
*
**********************************************************************************************************/
exit(0);
}

Related

How to get selected adapter's MAC address in WinPcap?

For example, when program runs, I entered 1 as input and wanted to get MAC address of that interface in here. How can I do that?
I did a lot of work trying to figure out how to both get the mac address for an arbitrary interface under Windows, and matching that to the device info you get back from WinPCap.
A lot of posts say you should use GetAdaptersInfo or similar functions to get the mac address, but unfortunately, those functions only work with an interface that has ipv4 or ipv6 bound to it. I had a network card that purposely wasn't bound to anything, so that Windows wouldn't send any data over it.
GetIfTable(), however, seems to actually get you every interface on the system (there were 40 some odd on mine). It has the hardware mac address for each interface, so you just need to match it to the corresponding WinPCap device. The device name in WinPCap has a long GUID, which is also present in the name field of the interface table entries you get from GetIfTable. The names don't match exactly, though, so you have to extract the GUID from each name and match that. An additional complication is that the name field in the WinPCap device is a regular character string, but the name in the data you get from GetIfTable is a wide character string. The code below worked for me on two different systems, one Windows 7 and another Windows 10. I used the Microsoft GetIfTable example code as a starting point:
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#include <pcap.h>
// Compare the guid parts of both names and see if they match
int compare_guid(wchar_t *wszPcapName, wchar_t *wszIfName)
{
wchar_t *pc, *ic;
// Find first { char in device name from pcap
for (pc = wszPcapName; ; ++pc)
{
if (!*pc)
return -1;
if (*pc == L'{'){
pc++;
break;
}
}
// Find first { char in interface name from windows
for (ic = wszIfName; ; ++ic)
{
if (!*ic)
return 1;
if (*ic == L'{'){
ic++;
break;
}
}
// See if the rest of the GUID string matches
for (;; ++pc,++ic)
{
if (!pc)
return -1;
if (!ic)
return 1;
if ((*pc == L'}') && (*ic == L'}'))
return 0;
if (*pc != *ic)
return *ic - *pc;
}
}
// Find mac address using GetIFTable, since the GetAdaptersAddresses etc functions
// ony work with adapters that have an IP address
int get_mac_address(pcap_if_t *d, u_char mac_addr[6])
{
// Declare and initialize variables.
wchar_t* wszWideName = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int nRVal = 0;
unsigned int i;
/* variables used for GetIfTable and GetIfEntry */
MIB_IFTABLE *pIfTable;
MIB_IFROW *pIfRow;
// Allocate memory for our pointers.
pIfTable = (MIB_IFTABLE *)malloc(sizeof(MIB_IFTABLE));
if (pIfTable == NULL) {
return 0;
}
// Make an initial call to GetIfTable to get the
// necessary size into dwSize
dwSize = sizeof(MIB_IFTABLE);
dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE);
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
free(pIfTable);
pIfTable = (MIB_IFTABLE *)malloc(dwSize);
if (pIfTable == NULL) {
return 0;
}
dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE);
}
if (dwRetVal != NO_ERROR)
goto done;
// Convert input pcap device name to a wide string for compare
{
size_t stISize,stOSize;
stISize = strlen(d->name) + 1;
wszWideName = malloc(stISize * sizeof(wchar_t));
if (!wszWideName)
goto done;
mbstowcs_s(&stOSize,wszWideName,stISize, d->name, stISize);
}
for (i = 0; i < pIfTable->dwNumEntries; i++) {
pIfRow = (MIB_IFROW *)& pIfTable->table[i];
if (!compare_guid(wszWideName, pIfRow->wszName)){
if (pIfRow->dwPhysAddrLen != 6)
continue;
memcpy(mac_addr, pIfRow->bPhysAddr, 6);
nRVal = 1;
break;
}
}
done:
if (pIfTable != NULL)
free(pIfTable);
pIfTable = NULL;
if (wszWideName != NULL)
free(wszWideName);
wszWideName = NULL;
return nRVal;
}

Webm (VP8 / Opus) file read and write back

I am trying to develop a webrtc simulator in C/C++. For media handling, I plan to use libav. I am thinking of below steps to realize media exchange between two webrtc simulator. Say I have two webrtc simulators A and B.
Read media at A from a input webm file using av_read_frame api.
I assume I will get the encoded media (audio / video) data, am I correct here?
Send the encoded media data to simulator B over a UDP socket.
Simulator B receives the media data in UDP socket as RTP packets.
Simulator B extracts audio/video data from just received RTP packet.
I assume the extracted media data at simulator B are the encoded data only (am I correct here). I do not want to decode it. I want to write it to a file. Later I will play the file to check if I have done everything right.
To simplify this problem lets take out UDP socket part. Then my question reduces to read data from a webm input file, get the encoded media, prepare the packet and write to a output file using av_interleaved_write_frame or any other appropriate api. All these things I want to do using libav.
Is there any example code I can refer.
Or can somebody please guide me to develop it.
I am trying with a test program. As a first step, my aim is to read from a file and write to an output file. I have below code, but it is not working properly.
//#define _AUDIO_WRITE_ENABLED_
#include "libavutil/imgutils.h"
#include "libavutil/samplefmt.h"
#include "libavformat/avformat.h"
static AVPacket pkt;
static AVFormatContext *fmt_ctx = NULL;
static AVFormatContext *av_format_context = NULL;
static AVOutputFormat *av_output_format = NULL;
static AVCodec *video_codec = NULL;
static AVStream *video_stream = NULL;
static AVCodec *audio_codec = NULL;
static AVStream *audio_stream = NULL;
static const char *src_filename = NULL;
static const char *dst_filename = NULL;
int main (int argc, char **argv)
{
int ret = 0;
int index = 0;
if (argc != 3)
{
printf("Usage: ./webm input_video_file output_video_file \n");
exit(0);
}
src_filename = argv[1];
dst_filename = argv[2];
printf("Source file = %s , Destination file = %s\n", src_filename, dst_filename);
av_register_all();
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0)
{
fprintf(stderr, "Could not open source file %s\n", src_filename);
exit(1);
}
/* retrieve stream information */
if (avformat_find_stream_info(fmt_ctx, NULL) < 0)
{
fprintf(stderr, "Could not find stream information\n");
exit(2);
}
av_output_format = av_guess_format(NULL, dst_filename, NULL);
if(!av_output_format)
{
fprintf(stderr, "Could not guess output file format\n");
exit(3);
}
av_output_format->audio_codec = AV_CODEC_ID_VORBIS;
av_output_format->video_codec = AV_CODEC_ID_VP8;
av_format_context = avformat_alloc_context();
if(!av_format_context)
{
fprintf(stderr, "Could not allocation av format context\n");
exit(4);
}
av_format_context->oformat = av_output_format;
strcpy(av_format_context->filename, dst_filename);
video_codec = avcodec_find_encoder(av_output_format->video_codec);
if (!video_codec)
{
fprintf(stderr, "Codec not found\n");
exit(5);
}
video_stream = avformat_new_stream(av_format_context, video_codec);
if (!video_stream)
{
fprintf(stderr, "Could not alloc stream\n");
exit(6);
}
avcodec_get_context_defaults3(video_stream->codec, video_codec);
video_stream->codec->codec_id = AV_CODEC_ID_VP8;
video_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
video_stream->time_base = (AVRational) {1, 30};
video_stream->codec->width = 640;
video_stream->codec->height = 480;
video_stream->codec->pix_fmt = PIX_FMT_YUV420P;
video_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
video_stream->codec->bit_rate = 400000;
video_stream->codec->gop_size = 10;
video_stream->codec->max_b_frames=1;
#ifdef _AUDIO_WRITE_ENABLED_
audio_codec = avcodec_find_encoder(av_output_format->audio_codec);
if (!audio_codec)
{
fprintf(stderr, "Codec not found audio codec\n");
exit(5);
}
audio_stream = avformat_new_stream(av_format_context, audio_codec);
if (!audio_stream)
{
fprintf(stderr, "Could not alloc stream for audio\n");
exit(6);
}
avcodec_get_context_defaults3(audio_stream->codec, audio_codec);
audio_stream->codec->codec_id = AV_CODEC_ID_VORBIS;
audio_stream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
audio_stream->time_base = (AVRational) {1, 30};
audio_stream->codec->sample_rate = 8000;
audio_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
#endif
if(!(av_output_format->flags & AVFMT_NOFILE))
{
if (avio_open(&av_format_context->pb, dst_filename, AVIO_FLAG_WRITE) < 0)
{
fprintf(stderr, "Could not open '%s'\n", dst_filename);
}
}
/* Before avformat_write_header set the stream */
avformat_write_header(av_format_context, NULL);
/* initialize packet, set data to NULL, let the demuxer fill it */
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
pkt.stream_index = video_stream->index;
ret = av_read_frame(fmt_ctx, &pkt);
while (ret >= 0)
{
index++;
//pkt.stream_index = video_avstream->index;
if(pkt.stream_index == video_stream->index)
{
printf("Video: Read cycle %d, bytes read = %d, pkt stream index=%d\n", index, pkt.size, pkt.stream_index);
av_write_frame(av_format_context, &pkt);
}
#ifdef _AUDIO_WRITE_ENABLED_
else if(pkt.stream_index == audio_stream->index)
{
printf("Audio: Read cycle %d, bytes read = %d, pkt stream index=%d\n", index, pkt.size, pkt.stream_index);
av_write_frame(av_format_context, &pkt);
}
#endif
av_free_packet(&pkt);
ret = av_read_frame(fmt_ctx, &pkt);
}
av_write_trailer(av_format_context);
/** Exit procedure starts */
avformat_close_input(&fmt_ctx);
avformat_free_context(av_format_context);
return 0;
}
When I execute this program, it outputs "codec not found". Now sure whats going wrong, Can somebody help please.
Codec not found issue is resolved by separately building libvpx1.4 version. Still struggling to read from source file, and writing to a destination file.
EDIT 1: After code modification, only video stuff I am able to write to a file, though some more errors are still present.
EDIT 2: With modified code (2nd round), I see video frames are written properly. For audio frames I added the code under a macro _AUDIO_WRITE_ENABLED_ , but if I enable this macro program crashing. Can somebody guide whats wrong in audio write part (code under macro _AUDIO_WRITE_ENABLED_).
I am not fully answering your question, but I hope we will get to the final solution eventually. When I tried to run your code, I got this error "time base not set".
Time base and other header specs are part of codec. This is, how I have this thing specified for writing into file (vStream is of AVStream):
#if LIBAVCODEC_VER_AT_LEAST(53, 21)
avcodec_get_context_defaults3(rc->vStream->codec, AVMEDIA_TYPE_VIDEO);
#else
avcodec_get_context_defaults2(rc->vStream->codec, AVMEDIA_TYPE_VIDEO);
#endif
#if LIBAVCODEC_VER_AT_LEAST(54, 25)
vStream->codec->codec_id = AV_CODEC_ID_VP8;
#else
vStream->codec->codec_id = CODEC_ID_VP8;
#endif
vStream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vStream->codec->time_base = (AVRational) {1, 30};
vStream->codec->width = 640;
vStream->codec->height = 480;
vStream->codec->pix_fmt = PIX_FMT_YUV420P;
EDIT: I ran your program in Valgrind and it segfaults on av_write_frame. Looks like its time_base and other specs for output are not set properly.
Add the specs before avformat_write_header(), before it is too late.

libusb_open returns 'LIBUSB_ERROR_NOT_SUPPORTED' on Windows 7

I have been developing USB drivers using LibUSB on Linux, but now I want to have one of my drivers compiled for Windows (this is the first time I am doing it).
My environment
I am working on Windows 7 using the MinGW compiler (also using Dev-cpp IDE), and I am using a pre-compiled libusb library downloaded from this link.
My device: It's a HID touch device. So no drivers are required for Windows. I have an additional endpoint to get certain debug data.
My code:
I have compiled code to list all the devices and USB devices connected to my machine, and the code works. Now I add code to open the device so that I get a device handle and start communication. But the function returns -12 That is, LIBUSB_ERROR_NOT_SUPPORTED.
How can I fix this problem?
I searched through the Internet and did not find a definite solution for this problem. While it's code which works beautifully on Linux.
P.S.: I have added the whole code below. The DoList(); function works fine, but the GetTRSDevice(); function fails at libusb_open(dev, &handle);.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb.h>
libusb_device_handle* deviceHandle = NULL;
int DoList();
libusb_device_handle* GetTRSDevice(void);
int main()
{
int ret = libusb_init(NULL);
if (ret < 0) {
printf("Failed to init libusb");
return ret;
}
DoList();
deviceHandle = GetTRSDevice();
if(!deviceHandle) {
printf("Failed to locate device");
goto fail_dev_open;
}
printf("Device opened");
libusb_close(deviceHandle);
fail_dev_open:
libusb_exit(NULL);
return(ret);
}
int DoList()
{
libusb_device **devs;
ssize_t cnt;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
return (int) cnt;
libusb_device *dev;
int i = 0;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return(-1);
}
printf("%04x:%04x (bus %d, device %d)\n",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
}
libusb_free_device_list(devs, 1);
return 0;
}
libusb_device_handle* GetTRSDevice(void)
{
int i = 0;
ssize_t cnt;
libusb_device *dev;
libusb_device **devs;
libusb_device_handle* handle = NULL;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0) {
printf("Failed libusb_get_device_list");
return(0);
}
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int ret = libusb_get_device_descriptor(dev, &desc);
if (ret < 0) {
printf("Failed libusb_get_device_descriptor");
continue;
}
if(desc.idVendor == 0X238f && desc.idProduct == 1) {
int ret = libusb_open(dev, &handle);
if (ret < 0) {
printf("Failed libusb_open: %d\n\r",ret);
break;
}
#ifndef WIN32
libusb_detach_kernel_driver(handle, 0);
#endif
ret = libusb_claim_interface(handle,0);
if (ret < 0) {
libusb_close(handle);
handle=NULL;
break;
}
break;
}
}
libusb_free_device_list(devs, 1);
return(handle);
}
You can easily install the WinUSB driver or the other drivers which libusb supports (libusb-win32 and libusbK) through the use of Zadig, an application that was developed just to solve this problem.
See https://zadig.akeo.ie.
One thing to keep in mind, though, is that if you replace a Mass Storage driver or HID driver (which Windows installs automatically) with WinUSB, you will only be able to access your device through libusb and won't be able to access your device as Mass Storage or HID until you uninstall the WinUSB driver.
Finally, if you have control of the firmware for your device, it is also possible to create devices that will automatically install the WinUSB driver on Vista or later, so that users don't have to go through a manual driver installation (this may require a connection to Windows Update for Windows 7 or earlier, but should work even without an internet connection for Windows 8 or later). See https://github.com/pbatard/libwdi/wiki/WCID-Devices.
[DISCLAIMER] I am the author of Zadig/libwi, the WCID wiki pages as well as a contributor to the libusb Windows backend.
It seems you need to install the winusb driver - libusb can get information about devices without this driver, but it cannot open them.
http://libusb.6.n5.nabble.com/LIBUSB-ERROR-NOT-SUPPORTED-td5617169.html:
On Wed, Apr 4, 2012 at 11:52 PM, Quân Phạm Minh <[hidden email]>
wrote:
although I never install winusb driver but I use libusb to get
information of my usb (kingston usb, and already
recognize by system)
Yes that is possible. But you can not open the device and do further
things. That is the confusing part for new users with regard to
libusb Windows backend, and similarly for Mac OS X as well. libusb
can get some basic information for device with a non-proper driver
(e.g.: USB mass storage device), but will not be able to open the
device without changing the driver to a supported one.
-- Xiaofan
I had this same issue and it was not solved by installing WinUSB drivers with Zadig.
Consistently I found that libusb_open() returns LIBUSB_ERROR_NOT_SUPPORTED if and only if I have a Logitech Unifying Receiver plugged into another USB port. This causes the pyusb libusb1 backend to raise an exception like "NotImplementedError: Operation not supported or unimplemented on this platform".
I have removed the Logitech receiver (so I am using a wired keyboard) and the problem is solved for me. I would love to know why or how the Logitech receiver can cause this error on another USB port, but I don't.
I had the same issue with Zadig not working. I fixed it my connection the device directly to my laptop not through a USB-C hub
I had the same issue. But to my surprize, ignoring the error and continuing the execution of the rest of the code, send the data as normal. So the device was supported and could communicate as normal. And for some reason, libUSB-1.0 thought it could not support the device.
My code example:
#include <libusb.h>
#include <stdio.h>
#include <unistd.h>
libusb_context* context = NULL;
int main(void)
{
int kernelDriverDetached = 0; /* Set to 1 if kernel driver detached*/
uint8_t buffer[64]; /* 64 byte transfer buffer */
int numBytes = 0; /* Actual bytes transferred. */
libusb_device_handle* handle = NULL;
int res = libusb_init(&context); //initialize the library using libusb_init
if (res != 0)
{
fprintf(stderr, "Error initialising libusb.\n");
}
/* Get the first device with the matching Vendor ID and Product ID.If
* intending to allow multiple demo boards to be connected at once,you
* will need to use libusb_get_device_list() instead. Refer to the libusb
* documentation for details. */
handle = libusb_open_device_with_vid_pid(0, 0x1cbe, 0x0003);
if (!handle)
{
fprintf(stderr, "Unable to open device.\n");
}
/* Check whether a kernel driver is attached to interface #0. If so, we'll
* need to detach it.*/
if (libusb_kernel_driver_active(handle, 0))
{
res = libusb_detach_kernel_driver(handle, 0);
if (res == 0)
{
kernelDriverDetached = 1;
}
else
{
fprintf(stderr, "Error detaching kernel driver. %s\n", libusb_error_name(res));
}
}
/* Claim interface #0. */
res = libusb_claim_interface(handle, 0);
if (res != 0)
{
fprintf(stderr, "Error claiming interface.\n");
}
memset(buffer, 0, 12);
buffer[0] = 0x55;
buffer[1] = 0xAA;
buffer[2] = 0x01;
buffer[3] = 0x00;
buffer[4] = 0x00;
buffer[5] = 0x00;
buffer[6] = 0x00;
buffer[7] = 0x00;
buffer[8] = 0x01;
buffer[9] = 0x00;
buffer[10] = 0x01;
buffer[11] = 0x01;
res = libusb_bulk_transfer(handle, 0x01, buffer, 12, &numBytes, 100);
if (res == 0)
{
printf("%d bytes transmitted successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error during send message: %s\n",libusb_error_name(res));
}
memset(buffer, 0, 12);
res = libusb_bulk_transfer(handle, 0x81, buffer, 12, &numBytes, 100);
if (res == 0)
{
printf("%d bytes receibed successfully.\n", numBytes);
}
else
{
fprintf(stderr, "Error during receibe response:%s\n",libusb_error_name(res));
}
/* Release interface #0. */
res = libusb_release_interface(handle, 0);
if (0 != res)
{
fprintf(stderr, "Error releasing interface.\n");
}
/* If we detached a kernel driver from interface #0 earlier, we'll now
* need to attach it again. */
if (kernelDriverDetached)
{
libusb_attach_kernel_driver(handle, 0);
}
/* Shutdown libusb. */
libusb_exit(0);
system("pause");
return 0;
}

Pthreads not working in Embedded ARM

Hello i am using AM1808 ARM9 microprocessor.
I have an interfacing of GSM dongle.I want to make the GSM dongle connection as well all data transmission as well reception in the background using pthreads.
When i am trying to connect the dongle in background it is continuously blinking green light and i could not get connect to the server.
I can not find the problem.
Here is my code for the datacard initialisation as well as communication routine.
I am initialising the Thread in the Main thread.
int InitializeDataCard(void)
{
static int connect_ret = 0;
pthread_t processing_th;
pthread_create(&processing_th, NULL, Datacard_Connection_Thread, &db_mc_object);
pthread_detach(processing_th);
ShowMessageBox(msgbox_text[136], MB_TASKMODAL);
if(connect_ret)
{
ShowMessageBox(msgbox_text[163], MB_ICONERROR);
return -1;`enter code here`
}
else
{
return 0;
}
}
int ConnectToServer(void)
{
int connect_ret = 0;
Dprintf(__func__,"Trying to connect ....");
DPUUtilsLib_RetrieveParameter(PID_DATACARD_INFO,(UCHAR *)&datacard_info,sizeof(datacard_info));
connect_ret = DataCardConnect(datacard_info);
sleep(3);
//g_do_process = 0;
Dprintf(__func__,"DataCardConnect ret=%d",connect_ret);
return connect_ret;
}
void * Datacard_Connection_Thread(void *tempdata)
{
int ret=0,response = -1,enc_ret=0;
static int g_gsm_response = 0;
dpu_csv_file_param_t fileparam;
dpu_db_export_search_params_t tempparams;
dpu_db_milk_collection_t *livedata,*updatedata;
dpu_db_user_master_t CreatedBy,UpdatedBy;
dpu_db_society_master_t soc_info;
char filename[50]={0};
livedata = (dpu_db_milk_collection_t *)tempdata;
//Connect to the Network
create_connection :
ret = ConnectToServer();
//connected successfully
if(!ret)
{
//Get the SocietyCode from the Database
if(g_data_available)
{
g_data_available=0;
soc_info.SocietyId = g_society_list[g_selected_society].SocietyId;
DPUDBLib_search_society_master(&soc_info);
strncpy(livedata->SocietyCode,soc_info.SocietyCode,5);
Dprintf(__func__,"%04d\n %5.2f\n %5.2f\n %5.2f\n %5.2f\n %5.2f\n %5.2f\n %7.2f\n %7.2f\n %03d\n %c\n %d\n %5.2d\n %s\n %d",
livedata->MemberCode,livedata->Fat,livedata->LRCLR,livedata->SNF,livedata->Solid,
livedata->FatKG,livedata->SNFKG,livedata->Rate,livedata->Amount,
livedata->CanNumber,livedata->EntryMode,livedata->MC_RateChartId,livedata->Water,livedata->SocietyCode,__LINE__);
sprintf(tempparams.FileName,"%s/%s",DATA_TEMP,MT_MILKLIVEFILE);
memcpy(fileparam.FilePath,tempparams.FileName,sizeof(tempparams.FileName));
fileparam.Type = DPU_CSV_EXPORT;
fileparam.FileType = DPU_CSV_MILK_LIVE_DATA_FILE;
//open a csv file
DPUCSVLib_open_csv_file(&fileparam);
memset(&CreatedBy,0,sizeof(dpu_db_user_master_t));
memset(&UpdatedBy,0,sizeof(dpu_db_user_master_t));
strncpy(CreatedBy.Username,TempUser,5);
//write the live data into the file
DPUCSVLib_write_csv_file(&fileparam,livedata,&CreatedBy,&UpdatedBy);
//encrypt the file
enc_ret = DPUEncryptFile(tempparams.FileName,filename);
if(!enc_ret)
{
//send file request to server for the accepting the data
response = SendFileRequest(g_gsm_response,filename,9);
if(!response)
{
//receive the response of the server
response = GetResponceFromServer(g_gsm_response,&response,9);
if(response || g_gsm_response) response = -1;
else
{
//If record is successfully sent to the server then update the FlagGSM flag of the record as well as
//Update the database
g_update_record = 1;
livedata->FlagGSM = 1;
updatedata->MilkCollectionId = livedata->MilkCollectionId;
DPUDBLib_search_milk_collection_entry_by_record(&updatedata);
DPUDBLib_edit_milk_collection_entry(&updatedata,&livedata);
g_update_record = 0;
}
}
//remove the temp file generated
remove(filename);
}
}
}
else
{
//if connection is not successfully done then try to reconnect the server
ShowMessageBox(msgbox_text[156], MB_ICONERROR);
goto create_connection;
}
}
I think there is basic mistake here. By declaring the static variable connect_ret in InitializeDataCard, it does not mean in any way that it is going to be the same variable declared in ConnectToServer. Therefore, the first function will always have the same behaviour...
I think you'll need a global variable (i.e. not defined in a function) and possibily some kind of synchronization, because when you create the thread, then probably it won't be executed immediately, so even if you have a global variable, you can't check against it until you know that it has been correctly set.

Getting ARP table on iPhone/iPad

I am trying to get the ARP entries on my iPad like here.
When compiling the code to run on my iPad (so not the simulator) I am getting missing header error messages. You can resolve them by copying the header files into you project locally as mentioned in this post.
The problem lies in the line
sdl = (struct sockaddr_dl *)(sin + 1);
in this piece of code:
-(NSString*) ip2mac: (char*) ip
{
int expire_time, flags, export_only, doing_proxy, found_entry;
NSString *mAddr = nil;
u_long addr = inet_addr(ip);
int mib[6];
size_t needed;
char *host, *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
extern int h_errno;
struct hostent *hp;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "actual retrieval of routing table");
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr) {
if (addr != sin->sin_addr.s_addr)
continue;
found_entry = 1;
}
if (nflag == 0)
hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
sizeof sin->sin_addr, AF_INET);
else
hp = 0;
if (hp)
host = hp->h_name;
else {
host = "?";
if (h_errno == TRY_AGAIN)
nflag = 1;
}
if (sdl->sdl_alen) {
u_char *cp = LLADDR(sdl);
mAddr = [NSString stringWithFormat:#"%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
// ether_print((u_char *)LLADDR(sdl));
}
else
mAddr = nil;
}
if (found_entry == 0) {
return nil;
} else {
return mAddr;
}
}
It gives the following error message:
Arithmetic on pointer to incomplete type 'struct sockaddr_inarp*'
When you compile the code for the iPad simulator everything runs fine.
Does anyone have an idea how to solve this?
A similar question (but not solved) is asked here.
After importing <netinet/if_ether.h>, you should edit it and change the line
#include <net/if_arp.h>
to
#include "if_arp.h"
and then import <net/if_arp.h> in your project as well. This should fix that error.
Anyway the headers you need to import to compile the code you posted are:
#include "if_ether.h"
#include "route.h"
#include "if_arp.h"
#include "if_dl.h"
Hope this helps =)
EDIT:
You need to "Add files to project", not simply importing it with #import or #include.
You can find above files from following links:
Files under "netinet"
Files under "net"
#include <net/ethernet.h>
instead of messing with the original headers. More info here: Implicit declaration of function 'ether_ntoa' is invalid in C99