|
I have successed in redirecting console to my program.All commands are executed well except some special characters.
My system is Windows XP Professional Chinese Edition.
Example in cmd.exe:
C:\Documents and Settings\Administrator>|
此时不应有 |。
C:\Documents and Settings\Administrator>
But in my program,it goes:
C:\Documents and Settings\Administrator>|
C:\Documents and Settings\Administrator>
In the debugging,I find that ReadFile() which reads feedback from the console only get '|',but no more characters,which should be a string as "此时不应有 |。"
What's wrong with it?
|
|
|
|
|
|
I think it's not about Chinese characters.My program can work well as follow:
C:\Documents and Settings\Administrator>xxxx
'xxxx' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
C:\Documents and Settings\Administrator>
|
|
|
|
|
I have a windows client application that connects to a Linux daemon, both written in C++. One of the functions simply sends files from a particular directory on the Linux server back to the windows client app. The client app then unpacks the buffer and writes the files. This all works perfectly as long as none of the files on the server are larger than around 1mb. If files larger than this are packed the daemon crashes in the call to send the data. I've done a binary dump into a file prior to attempting to send the data (ie. prior to a crash) and all the files are packed in there perfectly
The code to pack the files on the Linux server is (with all error checking removed for clarity):
bool ClassName::PackSoftwareUpdateBuffer(char* baseDirectory, unsigned char* pBuffer)
{
int return_code;
char buf[1024];
dirent entry;
dirent *result;
struct stat st;
DIR* dir;
Directory *pDir = NULL;
Directory *pCurr = NULL;
Directory *pd = NULL;
Directory *pCurrDir = NULL;
int fd = 0;
size_t bytesread;
do
{
if(pCurrDir)
{
sprintf(buf, "%s/%s", baseDirectory, pCurrDir->DirectoryName);
dir = opendir(buf);
*pBuffer++ = '$';
strcpy((char*)pBuffer, pCurrDir->DirectoryName);
pBuffer += 199;
}
else
{
dir = opendir(baseDirectory);
}
for(return_code = readdir_r(dir, &entry, &result); result != NULL && return_code == 0; return_code = readdir_r(dir, &entry, &result))
{
if(pCurrDir)
sprintf(buf, "%s/%s/%s", baseDirectory, pCurrDir->DirectoryName, entry.d_name);
else
sprintf(buf, "%s/%s", baseDirectory, entry.d_name);
stat(buf, &st))
if(S_ISDIR(st.st_mode))
{
if(pCurrDir)
{
sprintf(buf, "%s/%s", pCurrDir->DirectoryName, entry.d_name);
pd = new Directory(buf);
}
else
pd = new Directory(entry.d_name);
if(pCurr)
pCurr = pCurr->pNext = pd;
else
pDir = pCurr = pd;
}
else
{
strcpy((char*)pBuffer, entry.d_name);
SET_BUFFER_UINT32(pBuffer, 50, st.st_size);
fd = open(buf, O_RDONLY);
pBuffer += 54;
read(fd, (void*)pBuffer, st.st_size);
close(fd);
pBuffer += st.st_size;
}
}
closedir(dir);
if(pCurrDir)
pCurrDir = pCurrDir->pNext;
else
pCurrDir = pDir;
if(!pCurrDir)
break;
}while(true);
DeleteDirectoryStructs(pDir);
return true;
}
Where a Directory is a struct declared/defined as:
struct Directory
{
char DirectoryName[1024];
Directory *pNext;
Directory(char* dirName)
:pNext(NULL)
{
strcpy(DirectoryName, dirName);
}
};
The SET_BUFFER_UINT32 macro simply packs a numeric value into the buffer in network byte order. The pBuffer value passed into the function is a pointer to dynamically allocated memory. This is allocated in 1 mb chunks and always well and truly exceeds the amount of file data packed into the buffer (I have checked and re-checked this as it seemed the obvious reason for the issue). The crash occurs in the following function in the first call to send:
int ClassName::Write(unsigned char *buffer, unsigned int size)
{
int num = 0;
char *bufP = (char *)buffer;
unsigned int total = 0;
do
{
if((num = send(m_socket, (bufP + total), (size - total), 0)) <= 0)
{
return num;
}
total += (unsigned int)num;
}
while (total < size);
return total;
}
The buffer is the same buffer passed into the function to pack the data. If I comment out the call to read in the PackSoftwareUpdateBuffer function no crash occurs. Likewise if I set it so that only files less then one mb are read no crash occurs. In both cases the pBuffer pointer had the file size added to it, the same amount of data was sent if all the files were read, and the files were all successfully recreated on the client (albeit, filled with zeroes for the large files).
Bizarrely if I move the line: pBuffer += st.st_size; to above the call to read no crash occurs?!? This suggests to me there is something elementary I am completely missing. Any pointers much appreciated.
modified on Thursday, June 11, 2009 12:18 AM
|
|
|
|
|
- Where is the pBuffer allocated?
- How is the SET_BUFFER_UINT32 macro implemented?
With those obscurity.
How much memory is allocated for pBuffer? Its pointer value is increasing eternally within the loops. Never decreasing!
|
|
|
|
|
The pBuffer is allocated in a buffer wrapper class. Memory is allocated in 1mb chunks. I call another function to calculate the amount of buffer space required prior to calling PackSoftwareUpdateBuffer. The code for this function is similar to PackSoftwareUpdateBuffer except it never actually opens a file. Just uses the stat call to add up the total number of bytes required. I've checked to make sure it does this accurately using tracing. The buffer class allocates memory as follows (error checking removed):
bool CBuffer::InternalAlloc(unsigned int nBytes)
{
unsigned int nBytesToAllocate = (m_nBytesAllocated ? m_nBytesAllocated : 1048576);
while(nBytesToAllocate < nBytes)
nBytesToAllocate *= 2;
if(m_pMemory)
free(m_pMemory);
m_pMemory = (unsigned char *)malloc(nBytesToAllocate);
m_nBytesAllocated = nBytesToAllocate;
return true;
}
The SET_BUFFER_UINT32 macro is #define'd as follows:
#define SET_BUFFER_UINT32(buf, offset, value) \
buf[offset] = (value >> 24) & 0xff; \
buf[offset + 1] = (value >> 16) & 0xff; \
buf[offset + 2] = (value >> 8) & 0xff; \
buf[offset + 3] = value & 0xff;
Any ideas appreciated.
|
|
|
|
|
Well. The macro is using to store 32-bits size value in proper order, it's clear. But, I can't say that I understood the memory allocation exactly. Lets consider a fictive situation. m_nBytesAllocated is 10485760 bytes (10 MB) before the call to InternalAlloc member. if the requested nBytes is 10485761 bytes, 20 MB of space will be allocated. Sure?
Considering that you are sure, there isn't any buffer overflow problem. And I think that your linux daemon runs on a different CPU architecture, is it possible that there would be a page boundary problem in reading from a device?
The buffer will be passed to read function is starting with offset 54. Try to handle that value aligned in a page boundary consulting your CPU manuals. Or give it a try with a higher fabricated value for a page (e.g. 64K).
|
|
|
|
|
Your are correct about the memory allocation routine being, well, a little over generous. I need to tweak the allocation routine. The Linux daemon runs on x86 (for testing - x64 for production). You may have a point with the page alignment, I'll look into that.
|
|
|
|
|
I'm now using posix_memalign to allocate the memory on a 64 byte boundary. However the issue was much more simple. I removed the code to turn the server side app into a daemon and then ran it under GDB. It turns out the SIGPIPE signal was been sent to the daemon in the call to send. ie. my client was simply timing out and disconnecting. As I didn't have a SIGPIPE handler installed for my daemon I didn't realise this and was looking in the wrong place for the error. Not my smartest day(!).
modified on Thursday, June 11, 2009 9:10 PM
|
|
|
|
|
Would like to implement Office 2007 like interface using VS2008. There is a template of Office type 2007 interface. There is a calendar bar on the left. What I need is select date on the calendar and do something based on the date selected. I don't know which window message I should use in order get response of picking a date. Anyone kow any ideas? Thanks
|
|
|
|
|
In C, it is said that printf is in the header file stdio.h
But when I opened the header file, I couldn't see the definition of printf but there is only a funcion prototype like
"int _Cdecl printf(....;"
Where is the definition of printf actually written?
Plz reply
|
|
|
|
|
I don't think you should look at the definition unless you are a very experienced professional.
It could confuse you otherwise. Or you wouldn't make head or tail of it.
And, most of the function definitions are shipped in binary form inside DLLs.
The source of printf is available in printf.c in the crt\src folder of your VC installation.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
How to find the definition of printf in a Turbo C++ compiler. I am not using VC
|
|
|
|
|
Did you look for the aforementioned C file?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
printf is library function, possibly deployed without the source code.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Could someone tell me where (in MFC "make" files ) to find the path for this help file?
After several VC++ (6.0) reloads my older application won't compile due to wrong path for afxhelp.hm and I need to change this path. New projects ( with help file option) compile and work fine.
Thanks for your help.
Vaclav
modified on Thursday, June 11, 2009 1:26 PM
|
|
|
|
|
According to this MSDN the path is located in the MAP section of the help project file[^].
Best Wishes,
-David Delaune
|
|
|
|
|
Thank you very much for your help.
Vaclav
|
|
|
|
|
Hi all,
I have recently run into a problem I was not expecting that stands to jeopardize quite a bit of work. Within my application I have a singleton system logging object that reads from and writes to an XML file. This application also loads several DLLs which in turn also need to be able to contribute to the system log. The problem is when the DLLs try to get a pointer to the singleton they are actually creating a new instance of the object rather than referencing the one that has already been created. This creates an obvious problem with concurrent file I/O.
My question is, is there any way around this? The design of this object is such that the only interface anyone has to this object is through global macros(i.e. LOG_ERROR("error happened")), which handle accessing the singleton, meaning simply passing a pointer into the DLL at creation time is not feasible.
Any help is greatly appreciated.
Thanks,
Dustin Henry
|
|
|
|
|
Dustin Henry wrote: My question is, is there any way around this?
There must be - I've done it in apps (strangely enough, it was a logging class in my app as well!).
I also had the same issue you had (getting multiple instances) - I seem to remember the following making a difference:
- Making sure that all code implementing the singleton is implemented in .cpp files, not headers
- Using the DLL version of the C run-time
I also implemented the thing as a monostate object - all methods were static, something like:
class Logger
{
public:
static void Log(std::string const& msg);
private:
Logger();
static Logger* instance_;
std::ostream& output;
};
You could then access the logger using
Logger::Log("Hello World");
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hey Stuart, thanks for your help. I still couldn't get it to work so I just ended up passing in a pointer to the already created object and setting it via a macro. Not as clean as I would like but functional.
Dustin
|
|
|
|
|
I went back and had a look at the reporting implementation I wrote - I think the main difference is that I put my logger in a DLL, not the EXE. That way it's a lot easier for everything to link against it and be able to call it at run-time.
However, the implementation boiled down to what I described - there's a class with a single static function allowing reporting, and purely static (i.e. single instance for the whole class) data members:
Header file:
class Reporter
{
public:
Reporter();
static void Report(TMessageLevel level, const std::string& message);
static bool Reporting(TMessageLevel level);
private:
static TMessageLevel level_;
static implementation-defined message_;
enum { ReportLevelCount = sizeof(Reporter::level_) * 8 };
};
C++ file:
Reporter::Reporter()
{
}
void Reporter::Report(TMessageLevel level, const std::string& message)
{
if (Reporting(level)) {
message_(message);
}
}
bool Reporter::Reporting(TMessageLevel level)
{
int levelMask = (level < ReportLevelCount)?(1<<level):0;
return (level_ & levelMask) && !message_.empty();
}
message_ is effectively a function object that allows me to hook up the output mechanism at runtime.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I created a form application
File->New->Project->VC++->Windows Form Application.
I created couple of .Cpp files and .h files.
I have structure defined in .h file
typedef struct _PHB_ENTRY
{
unsigned char name[30];
unsigned char add[50];
int checksum;
int lenght;
int reserverd1;
int reserved2;
} PHB_ENTRY;
I have declared a variable in .cpp file, which is nothing but a 'C' code.
PHB_ENTRY myEntry[50];
First i have init function, thought to initialize the struc with null, so i used memset
memset(myEntry,NULL,50);
Problem no #1: I cant see index 0 is intialized to NULL !
then i started initializing the struct
strcpy((char*)myEntry[1].name,"STEFY");
Probmelem no #2: I can see STEFY being copied from myEntry[1].name[4], first for bytes are empty , that is myEntry[1].name[0]...myEntry[1].name[3] are empty!!
i assigned other values.
myEntry[1].checksum = 13;
myEntry[2].length = 4;
Problem no: #3: I see 13 is getting updated in myEntry[1].resevered1 variable and i cant see myEntry[2].length getting updated!
can some one help me out on this strange problem?!
Just a simple C code though!!!
|
|
|
|
|
The memset is has to be done as memset(myEntry, 0, sizeof(PHB_ENTRY) * 50);
Rest of your code looks ok.
Probably something wrong in how you are validating it.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
sakthii wrote: Problem no #1: I cant see index 0 is intialized to NULL !
memset 's third parameter is a byte count. Your array is 50 elements long, not 50 bytes. Try something like this:
memset(myEntry, 0, sizeof(myEntry));
Steve
|
|
|
|