DDE connection failing for unknown reasons - qt

I'm trying to create and implement a DDE dll with Qt but as for now I'm being unable to properly connect to a service which I know to be working after testing it with Excel.
The dll connection function is as following:
UINT respTemp;
respTemp = DdeInitializeA(&pidInst, NULL, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0L);
//handle error messages here
//...
//![]
hszService = DdeCreateStringHandleA(pidInst, (LPCSTR)service.utf16(), CP_WINANSI); //service.toLatin1().toStdString().c_str()
hszTopic = DdeCreateStringHandleA(pidInst, (LPCSTR)topic.utf16(), CP_WINANSI); //topic.toLatin1().toStdString().c_str()
hConv = DdeConnect(pidInst, hszService, hszTopic, NULL);
DdeFreeStringHandle(pidInst, hszService);
DdeFreeStringHandle(pidInst, hszTopic);
if (!hConv)
{
UINT ddeLastError = DdeGetLastError(pidInst);
switch (ddeLastError)
{
case DMLERR_DLL_NOT_INITIALIZED: return DDEConn_DLLNotInitialized;
case DMLERR_INVALIDPARAMETER: return DDEConn_InvalidParameter;
case DMLERR_NO_CONV_ESTABLISHED: return DDEConn_NoConvEstablished;
default: return DDEConn_NoConnectionStablished;
}
}
connStatus = true;
return DDEConn_NoError;
The test function is as follows:
void MainWindow::on_start_clicked()
{
const QString application = "profitchart"; //=profitchart|COT!VALE5.ult
const QString topic = "COT";
const QString item = "VALE5.ult";
test = CommDDE::instance();
CommDDE::DDEConnectionErrorList resp = test->connect(application,topic);
if (resp == CommDDE::DDEConn_NoError)
{
qDebug() << "request RESULT: " << test->request(item);
}
else
qDebug() << "Can't connect to application" << resp;
}
Always when I try to connect I get error DMLERR_NO_CONV_ESTABLISHED after the call to DdeConnect. I couldn't find guidence on what to do when such error occurs. I don't know too much about the details of configuring such functions so I used the default configuration used by a working dll from which I got part of the raw material for this dll. Should I try a different configuration I'm not aware of? Remembering that the call is working on Excel.

It would seem I found the answer: the commented way of writting the service and topic names were the right ways of passing the parameters to DdeCreateStringHandleA and DdeCreateStringHandleA.

Related

I'm using QT MSVC to use google speech recognition for speech to text of a audio file, return result.size 0

I'm using google speech recognition for speech to text,I use the exampe of cpp-samples-main,but when I use transcribe interface , and use the sound file "audio.raw is from the example ,I found response.results_size() = 0 , I don't know why, my program is as follows:
RecognizeRequest request;// ParseArguments((char *)"en-US", request.mutable_config());
request.mutable_config()->set_language_code("en-US");
request.mutable_config()->set_sample_rate_hertz(16000);
request.mutable_config()->set_encoding(RecognitionConfig::LINEAR16);
request.mutable_config()->set_enable_automatic_punctuation(true);
char* file_path =( char *)"E:/cpp-samples-main/speech/api/resources/audio.raw";
if (nullptr == file_path) {
qDebug() << kUsage;
return -1;
}
// [START speech_sync_recognize]// Load the audio file from disk into the request.
request.mutable_audio()->mutable_content()->assign(
std::istreambuf_iterator<cha(std::ifstream(file_path).rdbuf()),
std::istreambuf_iterator<char>());
grpc::ClientContext context;
RecognizeResponse response;
grpc::Status rpc_status = speech->Recognize(&context, request, &response);
if (!rpc_status.ok())
{ // Report the RPC failure.
return -1;
}

decrypt function at run time and use it QT c++

I'm new to QT and I'm trying to create an encrypted function.
Overall what you do in C / C ++ is:
Take pointer to function
make the function page rwx
Encrypt it (for the example I encrypt and decrypt in the same program)
Decrypt it and run it
A simple code in C will happen roughly like this:
void TestFunction()
{
printf("\nmsgbox test encrypted func\n");
}
// use this as a end label
void FunctionStub() { return; }
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
char * addr = (char *)dwStartAddress;
for (int i = 0; i< dwSize; i++)
{
addr[i] ^= 0xff;
}
}
DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
DWORD dwFunctionSize = 0, dwOldProtect;
DWORD *fnA = NULL, *fnB = NULL;
fnA = (DWORD *)Function;
fnB = (DWORD *)StubFunction;
dwFunctionSize = (fnB - fnA);
VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // make function page read write execute permission
return dwFunctionSize;
}
int main()
{
DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
printf("use func");
TestFunction();
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function
printf("after enc");
//TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
printf("after\n");
TestFunction(); // Fine here
getchar();
}
When I try to run such an example in QT I get a run time error.
Here is the code in QT:
void TestFunction()
{
QMessageBox::information(0, "Test", "msgbox test encrypted func");
}
void FunctionStub() { return; }
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
char * addr = (char *)dwStartAddress;
for (int i = 0; i< dwSize; i++)
{
addr[i] ^= 0xff; // here i get seg. fault
}
}
DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
DWORD dwFunctionSize = 0, dwOldProtect;
DWORD *fnA = NULL, *fnB = NULL;
fnA = (DWORD *)Function;
fnB = (DWORD *)StubFunction;
dwFunctionSize = (fnB - fnA);
VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // Need to modify our privileges to the memory
QMessageBox::information(0, "Test", "change func to read write execute ");
return dwFunctionSize;
}
void check_enc_function()
{
DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
QMessageBox::information(0, "Test", "use func");
TestFunction();
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function -> ### i get seg fault in here ###
QMessageBox::information(0, "Test", "after enc");
TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
QMessageBox::information(0, "Test", "after dec");
TestFunction(); // Fine here
getchar();
}
Why should this happen?
QT is supposed to behave like precision as standard C ++ ...
post Scriptum.
Interestingly in the same matter, what is the most legitimate way to keep an important function encrypted (the reason it is encrypted is DRM)?
Legitimately I mean that anti-viruses will not mistakenly mark me as a virus because I defend myself.
PS2
If I pass an encrypted function over the network (say, I will build a server client schema that the client asks for the function it needs to run from the server and the server sends it to it if it is approved) How can I arrange the symbols so that the function does not collapse?
PS3
How in QT can I turn off the DEP and ASLR defenses? (In my opinion so that I can execute PS 2. I have to cancel them)
Thanks
yoko
The example is undefined behaviour on my system.
The first and main issue in your code is:
void TestFunction() { /* ... */ }
void FunctionStub() { return; }
You assume that the compiler will put FunctionStub after TestFunction without any padding. I compiled your example and FunctionStub in my case was above TestFunction which resulted in a negative dwFunctionSize.
dwFunctionSize = (fnB - fnA);
TestFunction located at # 0xa11d90
FunctionStub located at # 0xa11b50
dwFunctionSize = -0x240
Also in XorBlock
addr[i] ^= 0xff;
Is doing nothing.
I assume you want to write in XorBlock to the memory location to XOR the entire TestFunction.
You could do something like this:
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
DWORD dwEndAddress = dwStartAddress + dwSize;
for(DWORD i = dwStartAddress; i < dwEndAddress; i++) {
// ...
}
}
I can't see any Qt-specific in your example. Even if it's Qt function call it's just a call. So I guess you have undefined behaviour in both examples but only second one crashes.
I can't see any reason for compiler and linker to keep function order. For example GCC let you specify the code section for each function. So you can reorder it in executable without reordering in cpp.
I think you need some compiler specific things to make it work.

why this code works well in windows but not in linux?

i am faced with a problem , i write this code in windows which reads each line of the file. and it works well in windows 7 but not in liunx. i really can't figure it out. anyone can help me?
list< list<string> > getTransRecordsFormFile(const char* fileName)
{
list< list<string> > res;
FILE* f = fopen(fileName,"r");
if(f == NULL) {
cout << "load input file failed!" << endl;
exit(0);
}
else {
char *buffer;
while(fgets(buffer,MAX_LENTH,f) != NULL) {
list<string> v = splitStr(buffer, SPLITCHAR);
res.push_back(v);
}
}
fclose(f);
return res;
}
i and my classmates find it out that the "fgets" in this code is wrong , but i don't know it works well in windows.
In your code, buffer is left unitialized. So, it may very well (and most likely to) points to some invalid memory location. Accessing invalid memory invokes undefined behavior. Once your program hits UB, absolutely nothing is guaranteed.
You need to make buffer point to some valid memory location before you can use that in fgets().

What is the necessary call to send data over COM port using OpenNETCF Port class?

I am trying to retrieve a value from a Zebra printer by interrogating it with this code:
public static string GetSettingFromPrinter(string cmd)
{
string setting = string.Empty;
try
{
BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = BaudRates.CBR_19200;
bps.Parity = OpenNETCF.IO.Serial.Parity.none;
bps.StopBits = OpenNETCF.IO.Serial.StopBits.one;
Port serialPort = new Port("COM1:", bps);
serialPort.Open();
byte[] sendBytes = Encoding.ASCII.GetBytes(cmd);
MessageBox.Show(Encoding.ASCII.GetString(sendBytes, 0, sendBytes.Length));
serialPort.Output = sendBytes;
serialPort.Query(); // <= this is new
byte[] responseBytes = serialPort.Input;
setting = GetString(responseBytes);
serialPort.Close();
return setting;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return setting;
}
}
However, I don't see where the Output is actually sent, or how to do that. My best guess was calling the Port.Query() method, but that doesn't work, either - at least there is nothing in setting / the Port.Input value after doing so.
I have successfully passed commands to the printer using the older SerialPort class:
public static bool SendCommandToPrinter(string cmd)
{
bool success; // init'd to false by default
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
success = true;
}
catch // may not need a try/catch block, as success defaults to false
{
success = false;
}
return success;
}
...but was advised not to use that due to its longness of tooth.
I would revert back to this snaggletooth if I knew how to read from the old SerialPort class. Does anybody know what I need to do to send sendBytes (and receive responseBytes)?
UPDATE
I tested "COM1" instead of "COM1:" (I used the latter because there is a post that says the colon is necessary (<= not medical advice, although that is doubtless true in that sense, too), but sans the ":" made no noticeable difference.
I then tried "string.Empty" in place of giving it a name, and got, "OpenNETCF.IO.Serial.CommPortException: CreateFileFailed 2 ..."
Onward...or is it Sideward...
FWIW, setting the Output property immediately sends the data on the wire. No additional call is necessary.

Setting default TWAIN data source without using API UI menu

Using the twaindotnet library in C#, I'm wondering if there's a way to set the default datasource using the library.
As a feeble attempt, I've tried adding a SetDefault method to the DataSource class of twaindonet, like this
public static void SetDefault(Identity applicationId, IWindowsMessageHook messageHook, DataSource newDataSource)
{
var defaultSourceId = newDataSource.SourceId;
// Attempt to get information about the system default source
var result = Twain32Native.DsmIdentity(
applicationId,
IntPtr.Zero,
DataGroup.Control,
DataArgumentType.Identity,
Message.Set,
defaultSourceId);
if (result != TwainResult.Success)
{
var status = DataSourceManager.GetConditionCode(applicationId, null);
throw new TwainException("Error getting information about the default source: " + result, result, status);
}
}
which is called from the DataSourceManage class like this
public void SelectSource(DataSource dataSource)
{
DataSource.Dispose();
DataSource.SetDefault(ApplicationId, _messageHook, dataSource);
}
But when I try to use SetDefault, Twain32Native.DsmIdentity always results in Failure being returned.
I basically copied from SetDefault the setDefaultDataSource method from TWAIN sample Data Source and Application
pTW_IDENTITY TwainApp::setDefaultDataSource(unsigned int _index)
{
if(m_DSMState < 3)
{
cout << "You need to open the DSM first." << endl;
return NULL;
}
else if(m_DSMState > 3)
{
PrintCMDMessage("A source has already been opened, please close it first\n");
return NULL;
}
if(_index >= 0 && _index < m_DataSources.size())
{
m_pDataSource = &(m_DataSources[_index]);
// set the specific data source
TW_UINT16 twrc;
twrc = _DSM_Entry(
&m_MyInfo,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_SET,
(TW_MEMREF) m_pDataSource);
switch (twrc)
{
case TWRC_SUCCESS:
break;
case TWRC_FAILURE:
printError(0, "Failed to get the data source info!");
break;
}
}
else
{
return NULL;
}
return m_pDataSource;
}
Any help would be greatly appreciated.
The possible cause is that the version of your TWAIN DSM is too low. Only DSM 2.0 or above supports setting default TWAIN data source.

Resources