Nope. It seems that as soon as the socket sees those nulls it stops sending. If i send the message like you suggest I get nothing. But if I take out the memset (nulls) and send the string....it sends it.
I'm thinking that the people that made up this custom packet, are missing something.
Could this have anything to do with me passing data from a PC to a main frame?
This packet is based on the DMPP-2020 Message Layout.
I get this: ))))))))))))))))))))))))))))))))))))))))))))))))))))) rest of message header here
Now I know that the )'s are supposed to be A's I think I put in the wrong number for A.
So I replaced 41 with 0 and I got nothing.
I'm thinking that I cannot send anything with leading nulls....which if you think about it, is right....how would the system know the end of one packet and the beginning of another is it did not reference nulls as the end or beginning of something.
That is never going to work because CString holds a C-style string. C-style strings, by definition, cannot contain embedded 0 characters because the first 0 marks the end of the string. CString is just the wrong class to use in this case.
Also consider what happens when Format() goes to insert the sHeader array in place of the %s. Again, %s means a C-style string, so it looks at sHeader1, sees that the first character is 0, and stops because that's the end of the string.
I'd just do two separate send calls, one for the block of 0s, then another for the text string. If you have to do it in one send call, you'll need to allocate a BYTE buffer of the right size and fill it in with the 0s and the string.
How are you inspecting the packet received? Could it be that your inspection mechanism gets fooled by leading nulls (like for instance if it dumps the packets to the console like they were C-style strings), but these are actually transmitted?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
As far as I can think, the closest solution should be replacing those null's with some other characters those otherwise will never be used in your application, for example, if your sure you'll never use the character '#', then:
// how long is your header gonna be, then how many #'s here#define THE_HEADER _T("###...##")
// To make your packet:
CString sPacket = CString(THE_HEADER) + _T("your real contents");
// Now send your packet
socket.Send((LPCVOID)(LPCTSTR)sPacket, sPacket.GetLength() * sizeof(TCHAR));
// And the receiver then replace the #'s with null's
TCHAR szReceived = _T("");
receiver.Receive((LPVOID)szReceived, 1023); // suppose 1023 is enoughfor (int i = 0; szReceived[i]; i++)
if (szReceived[i] == _T('#'))
szReceived[i] = _T('\0');
// Now you get what you want
Neither the Send function nor the corresponding Receive function strip out any characters from the buffer (nulls or otherwise). The Send function does not care what type of data you are sending. It takes a void pointer as a parameter. The data you send does not even have to be text. I send binary data over a socket all the time.
If it helps think of your final send and receive buffers as a block of miscellaneous bytes. It can be a string, a structure, random bytes, whatever. The length value is the number of bytes in the buffer to send. This is not necessarily the same as the number of characters in the string.
There is no need to replace the NULLs with another character unless that is more convenient for the receiving side.
A couple questions to ask:
What does the spec call for? 53 bytes of 0 followed by a variable length string? Is the string null terminated as well? Must the string be ASCII encoded? Can it be Unicode? This is important because the CString type will change depending on how the program is compiled. So, it's usually better to be more specific by using CStringA or a char array.
Another thing to consider is how much data you plan to send? If there are a lot of Send calls in a row, Send can fail as there is no more room in the internal buffer. Then you have to wait and resend the data. And that may not be all of the data either as Send can send part of your data (whatever fills up the buffer). It will always send bytes in the order passed to it, though.
Any way, yet another simple Send example (assumes ASCII bytes and variable null terminated string):
This version is done with two calls to send. In a low-load app, there won't be much of a performance difference between one call and two calls to send. You can replace the const char pointer with CStringA and lstrlen with GetLength if desired.
Tom Wright wrote: So is there a way to send leading nulls? Or is this a loosing battle?
NO! This is done all the time.
Tom Wright wrote: Sorry your right. After sending I only get 4 bytes...but still not the leading nulls.
This has really got me puzzled.
That is because you don't understand C/C++ strings. They are never going to have leading NULLs since all string library functions interpret the first NULL byte as the END OF THE STRING.
Tom Wright wrote: I'm thinking that I cannot send anything with leading nulls....which if you think about it, is right....how would the system know the end of one packet and the beginning of another is it did not reference nulls as the end or beginning of something.
Tom Wright wrote: and I got nothing. Tom Wright wrote: When I look at the packet on the other end,
How do you know what you got? I thought you sent it to a mainframe?
Tom Wright wrote: Here is my code snippet:
First we don't know what m_sConnectSocket is?
If we assume it's send() method is equivalent to the socket API send() then Tom you need to get this. send() only knows about the type byte. You give it the starting address of the memory block of bytes you want it to send and the number of bytes to send. It will either send all of them or none or some of them. The return value is the exact number of bytes sent or an error indicator. Are you checking the return value?
So to sum up if you call send( someAddress, 128) and the return value is 128 then the stack sent the 128 bytes of data starting at the address "someAddress" it does not care what freakin values are in those bytes, period. Please respond in the affermative if you understand this.
Tom Wright wrote: Do mainframes allow leading nulls?
Well if they don't then why would you have a specification to send it leading nulls?
Watch out! I'm a CPian on the edge!
I have a new Gold rating and I'm not afraid to use it!
You know what bud, it's 'A' holes like you that come on here late in the game and bitch people out instead of helping them understand what it is that they are trying to do. People like David Crow or Michael Dunn at least take the time to explain how things work instead of giving flaming responses and not explaining, or making someone feel like an idiot.
I do know some things about strings. There are times that I forget stuff (God i hope you never come on here and do that...I have no problem ripping you a new one). And beacause I program in both VC++ and COBOL there are times that I get the two languages confused.
I NOW know that leading nulls can not be passed. I DO understand that they mean the end of something. And I NEVER said that I was testing this between a mainframe and a PC. I'm at the stage where I'm just creating the string to send to the mainframe, but I am testing between two PC's. And while stepping thru my code I see that the nulls are not being sent. So while you roam around the forum like a meandering idiot bitching out people because they are not as smart as you, why don't you get down off your "I am a programming GOD" podium and take a few more seconds and find a better way of replying to people instead of being a jerk!!!
palbano wrote: Tom Wright wrote:
Here is my code snippet:
First we don't know what m_sConnectSocket is?
Well duh...it is some sort of socket method.....to be exact it's the CAsyncSocket method to send.
Thanks for nothing. So here is your affermative response....UP YOURS! by the way if it were up to me I would take that f-ing gold rating and stick it where the sun don't shine.
<humor>Wow, if you had spent as much time reading the documentation on strings and the send() API as you did typing that lovely romp of a post, you would have never started this thread. But then we would have never met. </humor>
And you did post a statement that I interpreted to mean you were sending the data to a mainframe.
Tom Wright wrote: So is there a way to send leading nulls? Or is this a loosing battle?
This mesage layout is based on the DMPP-2020 layout...which is a packet coming from a PC and going to a mainframe. Do mainframes allow leading nulls?
So you found some of my frivolous statements offensive rather than humorous. Ok my bad.
However there was a serious explanation of the send() API in there yes? You should have found that helpful right? It did not seem to be covered in the previous posts and it did seem like the main source of the problem. Also the explanation of NULL in strings should have been helpful as well right?
I did not just drop in to bash you or anyone. My coming late in the thread has nothing to do with anything other than the fabric of time. (again with the frivolity) Sorry being serious all the time is just not in my nature. Just like that signature. I feel the ratings are funny so I am poking some fun at it.
I have a Gold rating but it is currently unavailable due to being stuck up my arse.
Hi, I a making an MFC app that needs to save the user's password and username to the registry. How do I go about "encrypting" it before I save it to the registry so no sneaks will look in the registry to see the user's password (for example, a brother or sister or whoever..).
There are many articles on cryptography if you do a search. However I would advise against it. It would be all too easy for someone to reverse engineer your code to find out out to decrypt it (you must also want to decrypt it at a later stage, right?)
If you *must* save the username and password it needs to be at least as secure as windows encryption is. Try looking at the Crypto API. A search for such on google will give you quite a bit of information.
I'm hard, yet soft. I'm coloured, yet clear. I'm fruity and sweet. I'm jelly, what am I? Muse on it further, I shall return! - David Williams (Little Britain)
i face similar problem,
therw may be many solution to this problem,the solution is this.
i when ever i save the password in registry i Encrypt using RC4 encryption and when ever i need it i decrypt it and make use of it
----------------------------- "I Think It will Work"
Formerly Known As "Alok The Programmer" at CP
visit me at http://www.thisisalok.tk
I think it all depends on the level of protection you require on the password
You may or may not need the password to be decrypted which imposes 2 different ways of storing the data.
1) Need to decrypt
This is a weak way of storing a password because it can be decrypted but one might find this easier to handle since they can display the password after or send it by e-mail etc.
2) No need to decrypt
You store a non-decryptable version of the password or user/pass (if it applies) then when you need to validate the password, you encrypt the source data (password or user/pass) and compare versus what's found in your storage (registry). This also has the advantage that you will mostly never have the password unencrypted in process memory except for the source data which isnt guaranteed to match.
Once you decided on how you want to handle storage, you can better decide which encryption method you're going to use. Remember that each encryption system has its strengths and its weaknesses.
You should never save a password, even an encrypted one, especially in the registry. You should, instead, save a cryptographic hash value that results from the password, and user name if you want to be really secure.
The way this works is that different passwords and/or usernames will produce different consistant hash values and you can not reverse engineer a password and/or user name from the hash value. When a user enters a password you can compare the resulting hash value to the saved value and determine if the password is correct without ever storing the actual password in a data store. If the hash values match you can say with a high degree of certainty that the user entered the correct password.
A 160 bit hash value is currently considered to be the standard for a secure system.
MD5 produces a 128 bit hash value, which is a bit undersized by todays standards, and, additionally, has been known to contain theoretical flaws which have recently been shown to be exploitable for applications like you are describing. It is still a viable hashing algorythm for certain types of applications but not for your application.
I would recommend SHA256 at a minimum (256 bit hash value) or for extreme security SHA384 or SHA512. SHA384 or SHA512 require 64 bit arithmetic and you must be carefull if you are implementing them on a 32 bit processor due to the difference in the way numbers are stored on different architectures. Therefore, since SHA256 exceeds the current standard for security and can be implemented with 32 bit arithmetic I would recommend that you use it as your hashing algorythm.
So I have a lot of different C++ objects with members. Strings, ints etc.
Objects get populated from database. Used to do it using MFC ODBC classes. Then I decided to go OLE DB. Wow! So. Now instead of CRecordset we use CAccessor<>, right? To map members to fields now I have to use TCHAR or CComBSTR for strings, right?
But I'd like to keep my objects as CString or std::string. I don't want to change all my code to operate with CComBSTR and I don't want make parallel just members to transfer data from database to my members. What do I do then? Is there a way to make COLUMN_ENTRY to accept CString or std::string? Or somehow make an automatic transfer from one global CComBSTR (that would be used to retrieve the data) to those members?
for linking fields to members require members to be CComBSTR (or _bstr_t you are talking about). But my members are CString and/or std:string
and I don't want to convert the rest of my code to use BSTRs.
inner wrote: I don't want to convert the rest of my code to use BSTRs.
You must whenever using COM interfaces. It is the COM form of string. Unless you want to use byte arrays which are not easier. At least _bstr_t has simple conversion interface to char and wchar making life easy to use CString and std::string/wstring
I have a win32 application that I'm using to test some stuff (just basic algorithm) and timing the execution of the program depending on the file I drop on the exe. When it's done, it displays a messagebox with the amount of time it took to complete the operation. However, if it takes a long time, the DOS-looking console window is displayed the whole time. I don't want any window displayed except the messagebox signaling that the event is over. How can I accomplish this?