|
If I add printers (just available drivers of printers in Windows XP), it allows to many of the queries even if printer is not available physically. So I will surely try if I can find something to identify printer type for sure.
Ana
|
|
|
|
|
I know when you have a external refrence to a C program in a C++ program you can decalre the function as extern "C"
however if in the same build in which you are building a C++ app you have a header that has inline C function('s) is there a way to let the compiler know that this is a "C" function and not C++
thankx
|
|
|
|
|
You can also use extern "C" like this in a header file
#ifdef __cplusplus
extern "C" {
#endif
lots of C style defines etc
#ifdef __cplusplus
}
#endif
Which enables you to use a header describing defines for a C DLL in either a C or C++ project.
It is the method Microsoft uses and also the method I use.
|
|
|
|
|
can I do
#ifdef __cplusplus
#include "cheader.h"
#endif
|
|
|
|
|
alberthyc wrote: No_of_Slider
Do you ever initialize No_of_Slider?
Which pointer is NULL?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
hi, that was solved....
in the OutputData, i accidentally put me->pbydata[i]=me->MySliders.Getpos();
after I change to pbydata[i]=me->MySliders.Getpos();
solved.
but now i got assertion errors after i start the thread...
"Original post":
hi, desperately need some help with my code....
I have mfc dialog that reads slider positions and store into a data array, then this data is passed to on signal output board onboard memory and output.
This output process should be continuous so i'm using a worker thread.
Also, by changing the slider position, the output from the board should be changed accordingly.
the code compiles and build succesfully. After I start using the program, i got problems.
Here's some of my code:
in CMyTestDlg.h:
class CMyTestDlg : public CDialog{
char* pbyData[2];
long lBufSize;
int No_of_Slider;
CWinThread* pThread;//worker thread
Static UINT __cdecl Start(LPVOID pParam);//thread function
CSliderCtrl m_Myslider[2];//create 2 slider variable
afx_msg void OnBnClickedButtonInitialize();//this is the initialize button
afx_msg void OnBnClickedButtonStart();//this is the start button
afx_msg void OnBnClickedButtonStop();//this is the stop button
void MemAlloc();
void FillBuffer(LPVOID pParam);//fill the data buffer
void OutputData(char* pbyData, long lBufsize,CMyTestDlg* me);
//....and some other variable and functions
in my CMyTestDlg.cpp
....//some initialization
void CMyTestDlg::MemAlloc(){
// ----- allocate memory for data -----
for (i=0; i<2; i++)
pbyData[i] = (char*) GlobalAlloc (GMEM_FIXED, No_of_Slider);
}
void CMyTestDlg::FillBuffer(){
// ----- fill the data buffers with data -----
for (i=0; i<2; i++){
OutputData (pbyData[i], No_of_Slider,this);
void CMyTestDlg::OutputData(char* pbyData, long lBufsize,CMyTestDlg* me)
{//store the slider position into the two data arrays
int i;
for (i=0; i< me->No_of_Slider; i ++){
pbyData[i]=(char*)me->MySliders.GetPos();
}
UINT __cdecl CMy61xxTestDlg::Start(LPVOID pParam){//Thread Function
int i;
CMyTestDlg* me=(CMyTestDlg*)pParam;
do{
me->OutputData (me->pbyData[i], me->No_of_Slider,me);
SpcSetPararm(....)//a library function provided, don't worry about this
i++;
if (i == No_of_Sliders)
i = 0;
}while(!ERROR)
//this function should be fine
void CMy61xxTestDlg::onBnClickedButtonInitialize(){
//after Inialization button being clicked, do some initialization.
...
MemAlloc();
FillBuffer();
}
CMy61xxTestDlg::onBnClickedButtonStart(){
//After Start button being clicked, worker thread starts and data ouputed
pThread=AfxBeginThread(Start,this,-1);
}
void CMy61xxTestDlg::onBnClickedButtonStop(){
Error=False;//cause the thread function loop to break
for (i=0; i<2; i++)
GlobalFree ((HANDLE) pbyData[i] );
}
After I press the initialize button, something went wrong and i have to break,
on the output window, i got bunch of:
First-chance exception at 0x00000000 in Test_Multithreading.exe: 0xC0000005: Access violation reading location 0x00000000.
AND STACK OVERFLOW!
and on the call stack:
the yellow arrow points at 00000000();
what could cause the stack overflow????
i think there's a memory problem, probably either is the Fillbuffer or the OutputData function, but i can't find out where the problem is.
I don't think there's a thread problem because the thread was not even started.
|
|
|
|
|
alberthyc wrote: but now i got assertion errors after i start the thread...
The nice thing about assertion errors is they break on the line of code they occur at
I don't have a clue what assertion errors you're seeing or where they are occurring.
Why does your posted code show different class names for the dialog class?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
hi, the error asserts at wincore.cpp line 1007:
ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
some of my code here, i wrote them and some of them i just copyied from my file and forget to change the classname
|
|
|
|
|
I'm only guessing, but I'd say you have memory corruption problems.
To start with, it looks like 'i' is uninitialized (at least) the first time you use it in your thread proc (Start()).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
i don't think so, the code in my file is a little different, i'm posting a simpfied version, but i'm pretty sure they are initialized
the code below is the original code, and all variables are initialized.
the "SpcSetParam...." function comes from the external library, don't worry about it.
UINT __cdecl CMy61xxTestDlg::Start(LPVOID pParam){
// ----- start the board -----
CMy61xxTestDlg* me=(CMy61xxTestDlg*)pParam;
me->nBufIdx = 0;
me->lCommand = SPC_FIFOSTART;
me->lBufCount = 0;
do
{
me->nErr = SpcSetParam (me->hDrv, SPC_COMMAND, me->lCommand);
me->lCommand = SPC_FIFOWAIT;
// ----- driver requests next buffer: calculate it or load if from disk -----
me->OutputData (me->pbyData[me->nBufIdx], me->BUFSIZE,me);
// ----- buffer is ready -----
SpcSetParam (me->hDrv, SPC_FIFO_BUFREADY, me->nBufIdx);
// ----- next Buffer -----
me->lBufCount++;
me->nBufIdx++;
if (me->nBufIdx == MAX_BUF)
me->nBufIdx = 0;
}
while (me->nErr == ERR_OK);
delete me;
return 0;// assertion occurs here
}
by using the break points, i found out that the assertion at return 0
|
|
|
|
|
alberthyc wrote: by using the break points, i found out that the assertion at return 0
Which is a bad sign, since the assertion is related to DestroyWindow) - if you're not destroying any
windows then something is corrupt somewhere.
I hope you understand, it's next to impossible to debug this by proxy
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
lol, i'm having a headache.....
i'm wondering is my functions looks appropriate? is there any better way to do this?
|
|
|
|
|
Take some [insert your favorite headache medicine here] and run it in the debugger.
When you get an exception, look at your stack trace.
If you work your way back through the trace to the first line you find in YOUR code then go there.
Examine all variables, pointers, etc.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
alberthyc wrote: i'm wondering is my functions looks appropriate? is there any better way to do this?
Just some thoughts...
Accessing a CWnd from another thread is usually best avoided unless you know exactly what
you're doing (or what MFC is doing). Accessing the underlying HWND is ok but you have to
use thread synchronization just like for any other type of object accessed by multiple
threads.
I'm wondering if you really need a thread for this. Maybe a timer would be more appropriate,
maybe not.
Your thread sits and spins in a loop - does it consume all your CPU time?
Make sure your memory accesses all stay within bounds.
Make sure you use thread synchronization objects if you need them.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hello everyone, just wanted to say that this is my first post ever, so here goes...
I have sucessfully created and compiled a program that is supposed to calculate your age in either dog or cat years (based on your choice). Unfortunately, whenever I try and execute or debug it, nothing happens. On debugg, the command window flashes for a second and then is gone, and when running it from the command line, nothing happens at all.
I am just staring out with programming, but I think that my functions are not being called properly somehow, perhaps in the main module? I have attached the code at the bottom here, and any help given will be greatly appreciated. Thanks.
//************************//
//Animal Age Calculator //
//Phelan Vendeville //
//31 JUL 2007 //
//************************//
#include <iostream>
float age_module(float human_age); //function prototype
float animal_module(float dogyears, float catyears); //second function prototype
int main()
{
using namespace std ;
float age_module(float human_age); //call to function
float animal_module(float dogyears, float catyears); //call to second function
}
float age_module (float human_age) //custom function itself
{
using namespace std ;
cout << endl ;
cout << "Please enter your age (integer please)";
cin >> human_age ;
if (human_age <= 0)
{
cout << endl;
cout << "Please enter your real age (integer)";
cin >> human_age;
return (human_age);
}
else
{
(human_age > 0);
cout << "Your human age is: " << human_age <<endl;
return (human_age);
}
}
float dogfunction (float human_age, float dogyears); //subfunction prototypes
float catfunction (float human_age, float catyears);
float animal_module(float dogyears, float catyears) //second custom function (itself)
{
using namespace std ;
char type;
cout << endl ;
cout << "Would you like your age in Dog or Cat years? (D for Dog, C for Cat, capitalized)";
cin >> type ;
if (type == 'D')
{
float dogfunction (float human_age, float dogyears);//call to function
cout << endl;
cout << "Your age in dog years is:" <<dogyears <<endl;
return dogyears;
}
else if (type == 'C')
{
float catfunction (float human_age, float catyears);//call to function
cout << endl;
cout << "your age in cat years is:" <<catyears << endl;
return catyears;
}
else
{
cout <<endl ;
cout << "Please enter your choice, D or C" <<endl;
return 0;
}
}
float dogfunction (float human_age, float dogyears)
{
using namespace std;
if (human_age <= 2)
{
dogyears = human_age * 10.5f; //the reason that the f is there is to tell the comiler that the 10.5 is a float, not a double, which it thinks it is by default.
return (dogyears);
}
else
{
dogyears = (human_age * 4) - 21;
return (dogyears);
}
}
float catfunction (float human_age, float catyears)
{
using namespace std;
if (human_age == 1)
{
catyears = 15;
return (catyears);
}
else if (human_age == 2)
{
catyears = 24;
return (catyears);
}
else
{
catyears = (human_age * 4) - 24;
return (catyears);
}
}
|
|
|
|
|
Welcome to CP You are mixing up function prototypes and function calls. A prototype just tells the compiler about a function - its name, return type, and parameters. It doesn't actually call the function. Every place where you say "//call to function", you've actually written another prototype.
|
|
|
|
|
In addition to Michael Dunn's reply...
In your next version, I'd like to see the equivalant human years in alpaca years as well!
Welcome to The Code Project!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Ha! thanks for the welcome guys, and the tip. Alpaca it is then!
|
|
|
|
|
hello ,
I am try to write a C++ apllication using windows speech API 5.1, for a text-to-speech functionnality.
the application has as an input the text to translate, the format for wav output and the language to use. this application return a buffer containing the wave data.
I need to be able to change the wave format and to switch languages in real time.
Actually I am able to set the format and to return the wave data into a buffer.
The problem I have is that I can't change the language. I must be capable of using 5 languages (English, Italien, Spanish, German and French).
Does anybody have to di this and can help.
Thanks in advance
ps: I am not oblige to use SAPI5
|
|
|
|
|
hi,
when i like to link a table with an access report DB and i have an error -7748. we have an access 2000 on XP sp2. I can't find an anwser on msdn.
thanks.
|
|
|
|
|
For example *.dbb files of Skype.
It is possible to do this without killing the process
monopolizing the file, as shows the program
"Unlocker" by Cedrick Collomb. But is it possible
to do it without creating a driver like UnlockerDriver5.sys,
but using WinAPI only? CopyFile() fails to copy
an open file with forbidden sharing. But may be there
exists some tricky way?
|
|
|
|
|
Not without a driver to circumvent the OS'es sharing-mode check.
|
|
|
|
|
There is no 'friendly' way of doing it. With that being said, a hacked up way would be to use CreateRemoteThread() into a target process and force it to close the file handle. Which in turn would probably cause serious problems in the target process.
Partial pseudo-code looks something like this:
<br />
PID TargetProcess = P;<br />
HANDLE TargetHandle = H;<br />
HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE,TargetProcess);<br />
HMODULE hMod = LoadLibrary(_T("kernel32.dll"));<br />
DWORD rc;<br />
CreateRemoteThread(hProc,0,0,(__stdcall *)(void*)GetProcAddress(hMod,"CloseHandle"),TargetHandle,0,&rc );<br />
Best Wishes,
-Randor
|
|
|
|
|
Thank You for Your pseudocode!
Randor wrote: Which in turn would probably cause serious problems in the target process.
Well, if there exists a way to suspend the process during this operation,
and reopen the same handle after that it surely would do the job
without skrewing up the target process.
By the way, opening UnlockerDriver5.sys in Notepad
I noticed that it is a User Mode driver, importing
a dozen of routines from ntoskrnl.dll.
I've never wrote WinNT drivers up to now, so it seems
I have to learn the corresponding rituals
to produce a "smooth" solution to the problem
of stealing Skype's files without depressing Skype too much
|
|
|
|
|
OK, I've learned the rituals of writing kernel mode drivers --
these rituals turned out to be not that difficult.
What is difficult, however, is to determine what
this driver ought to do exactly (find a "handles table"
inside a Kernal memory space and change temporary
the sharing attributes of the corresponding handle?
Or to do somethinh else?). I have no time to read books
of Russinovich&Solomon or Dabak&Phadke&Borate,
so I decided to try first to find a way to do the job without
writing drivers of any kind, working entirely in User mode.
I've tried several ways to find a solution.
1) Injecting in the remote process blocking the access to the file
a remote thread, which uses the blocking handle
to copy the corresponding file rather than to close the handle.
For the purpose one is to inject Your own dll instead of
starting inside the remote thread any functon from Kernel32.dll
or some other "canonical" Windows library.
The reason is that any function like ReadFile(), etc.
uses more than 1 parameter. In Your own dll You can export a function
fn(void*p) which formaly has one pointer parameter, but this pointer
can point to a structure containing any number of parameters needed
e.g, for CreateFile(). The latter function can then be called from
inside of fn(). The structure with necessary parameters for fn()
is, of course, to be injected as well into the address space of the blocking
process, because the pointer to this structure in the calling process
has no sense in the remote process.
A sample implementation of the corresponding
algorithm (by Zoltan Csizmadia) can be found at
http://www.codeguru.com/cpp/w-p/dll/article.php/c105/ .
I've tried the demo exe from there: it is trying to attach a simple dll
to any process of Your choice. It succeeded for many of the processes
running on my PC, but failed to attach to Skype
2) Duplicating remote handle of an open file into Your process.
I've tried (different variations of) the next code:
bool CopyLockedFile(LPCTSTR lpFileName,int bytesToRead,char*buff)
{
HANDLE hProcess=NULL,//handle of the blocking process
hRemote=NULL;//blocking handle to the file lpFileName I wish to read
//Receive the handle hProcess of the blocking process
//as well as the blocking handle hRemote of the file You wish to read
....... //The code is omitted here
HANDLE hDup=NULL;
DuplicateHandle(hProcess,hRemote,GetCurrentProcess(),&hDup,0,FALSE,DUPLICATE_SAME_ACCESS);
DWORD err=GetLastError();
if(err!=0||hDup==NULL)return false;//Never happened!
CloseHandle(hProcess);
BOOL ok=LockFile(hDup,0,0,bytesToRead,0);//Does not help!
err=GetLastError();
if(!ok||err!=0)return false;//Never happened!
int bytesRead=0;
ok=ReadFile(hDup,(LPVOID)buff,bytesToRead,&bytesRead,NULL);
err=GetLastError();
CloseHandle(hDup);
if(!ok||err!=0)return false;//Never happened!
if(bytesRead==bytesToRead)return true;
return false;
}
Variations of the code consisted in changing different flags, using in ReadFile()
non-zero OVERLAPPED structure instead of last parameter=NULL, etc.
The result was always the same: the code produced no errors, but the number
of read bytes (i.e. bytesRead) were less than the file length bytesToRead.
More exactly, at the first run of my prog this number was slightly less
(about 5%) than the file length. All subsequent runs produced bytesRead==0.
Until the blocking app (Skype in this case) was restarted. Then my prog
was able again to partially read the file.
3) Googling in the internet I found that many other peoples
(especially those writing backup apps) were faced with this problem.
The solution proposed by them was to use somehow Windows Volume shadow copy service.
The only working application using this service I've found is ntbackup.exe by MS.
It succeedes in copying Skype's .dbb files only if Volume shadow service
is permitted as an option, otherwise it fails. Another application
(TeeBackuper written in Delphi -- source code 30K, exe -- 3.2M!) also failed.
It clearly did not use the Volume shadow service (which, by the way is
present on WinXP and higher only, so the solution using this service
would not work on Win2k).
4) I was prepairing already to learn more about Volume shadow service,
to include it somehow into my app. But yesterday googling again
I found the following remarkable link:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1089734&SiteId=1 .
The author (ismar) faced with the same problem. The only difference
is that he works with C# .NET. His first (buggy) solution
is the direct .NET counterpart of the "DuplicateHandle" way 2) above.
The bug of this .NET solution is roughly the same as the bug
of C++ solution: failure to read the locked file more than once.
Which indicates that using of CreateFile() together with the handle obtained
via DuplicateHandle() produces an (undocumented) bug of MS itself!
The good thing is that after about 2 weeks of playing around with
the buggy solution ismar found the working one! The
idea is to use, instead of ReadFile(),
the combination CreateFileMapping()+MapViewOfFile()
(in C# language this are NativeMethods.CreateFileMapping()+
NativeMethods.MapViewOfFile()).
I immediately have changed the buggy code 2) by the code:
bool CopyLockedFile(LPCTSTR lpFileName,int bytesToRead,char*buff)
{
HANDLE hProcess=NULL,//handle of the blocking process
hRemote=NULL;//blocking handle to the file lpFileName I wish to read
//Receive the handle hProcess of the blocking process
//as well as the blocking handle hRemote of the file You wish to read
....... //The code is omitted here
HANDLE hDup=NULL;
DuplicateHandle(hProcess,hRemote,GetCurrentProcess(),&hDup,0,FALSE,DUPLICATE_SAME_ACCESS);
DWORD err=GetLastError();
if(err!=0||hDup==NULL)return false;//Never happened!
CloseHandle(hProcess);
HANDLE hMap=CreateFileMapping(hDup,NULL,PAGE_WRITECOPY,0,bytesToRead,NULL);
err=GetLastError();
if(err!=0||hMap==NULL)return false;//Never happened!
char* pMap=(char*)MapViewOfFile(hMap,FILE_MAP_COPY,0,0,bytesToRead);
if(pMap==NULL){CloseHandle(hMap);return false;}
for(int i=0;i<bytesToRead;i++)buff[i]=pMap[i];
UnmapViewOfFile(pMap);
CloseHandle(hMap);
return true;
}
And this code works great! At last!
No matter how many times it is called.
It uses no drivers, no CreateRemoteThread()
(requiring, by the way, SeDebugPrivilege),
so that I suppose the prog using it can be run
under an ordinary user account without any administrative rights
(though I did not tested it yet under an ordinary user account).
-- modified at 14:01 Wednesday 22nd August, 2007
|
|
|
|
|