thelamb 163 Posting Pro in Training

Do you know what a class is? Have you learned anything about object oriented programming?

thelamb 163 Posting Pro in Training

You run the program, select the option that will read the file, then the program closes and you re-open. You then select the option that will print the data that was previously read?

That won't work. In the first instance, the data is read into memory. All of that memory is cleaned up when the program exits. So when you start it again, it remembers nothing from its previous run.

What you should do is modify the menu function, so that after finishing one of the cases it asks you again which action you would like to take.
That way you don't exit the program, and all the data that was read is still there.

You should also check of course, before printing the data that it already has been read. If not, give an error that the user should first select the action to read the data.

thelamb 163 Posting Pro in Training

Also note that returning a pointer to a local variable is not very nice. It'll probably work in most cases.

A 'better' solution would be to make buf static, at least you can be sure then that it still exists after the pQuery function returned.
It's still not very elegant though.

Or allocate the buffer before calling pQuery, and hand it over as a parameter.

char buf[100];
if( pQuery( buf, "blabla %i", 4 ) ) {
// use buf
}
thelamb 163 Posting Pro in Training

First post I thought I spotted an error in pQuery, since this is rather weird:

sprintf(buf,"");
int		ret = vsprintf(buf + strlen(buf)

the strlen put me off.

The real error is that you can't compare a char array with ==, there are functions to do this (e.g. strcmp, strncmp). Note that these functions return 0 when the two char arrays match.

Edit: aaand you beat me to it ;)

thelamb 163 Posting Pro in Training

Run your code under a debugger (You use Visual Studio after all) to get more detailed information about the crash.

The pasted code is too long to read through when the range can be narrowed down very easily ;)

thelamb 163 Posting Pro in Training

You're not receiving anything, it prints uninitialized data. You set the socket to 'nonblocking' and then continuously call recv. So even if there is no data coming from there server, recv will return.
You do not check the return value of recv before printing it, the return value is probably SOCKET_ERROR, and WsaGetLastError() will return WSAEWOULDBLOCK.

Try first to keep the socket in block 'mode', and check the return value of recv (checking return values is one of the most important things, especially when things do not work as you expected).

thelamb 163 Posting Pro in Training

In write_it (I guess that is where it crashes?), check what the value of 'buf' is, is it a valid pointer?

I don't know how this 'curl' library works though, so just guessing here

thelamb 163 Posting Pro in Training
thelamb 163 Posting Pro in Training

And that's exactly where it shouldn't be used any more ;)

Details are out on Google.

As for other suggestions, you need to ask yourself some questions:
- How skilled is my attacker?
- How motivated is my attacker?
- How important is what I'm protecting.

When some very big, cold country is your attacker... you're in trouble, if your program has 20 users then your solution above is going to be fine.

Also a big thing to keep in mind is how does the protection affect your users? There is nothing more annoying than an elaborate scheme to protect your software but is a nuisance to users.

For example, some game company tried to protect their game by requiring a constant internet connection even in single player... so genuine users who bought the game could not play if their connection failed, but players with a cracked copy had no trouble at all.

thelamb 163 Posting Pro in Training

tei.h:56:10: warning: multi-character character constant

'T0' is not a character, it's two characters.

tei.h:7: error: aggregate ‘foititis p’ has incomplete type and cannot be defined

Where is 'foititis' declared? Is this declaration available in tei.h ?

thelamb 163 Posting Pro in Training

For one, MD5 shouldn't be used any more.

And it's going to be fairly trivial to bypass this. A reverser can just put a breakpoint on when your program attempts to open a file.. this is going to be somewhere at the beginning of the 'check license file' function. He then checks where it was called from and modifies the binary to skip the check.

only the software would know how to open the licence file using a built-in algorithm

Sure, until someone gets motivated enough to reverse the algorithm.

Of course there is always going to be a way around software protection, so you can only make it as hard as possible... but your described way wouldn't take too long for someone who's motivated

thelamb 163 Posting Pro in Training

What happens here:

char* a = "Hello world";
cout << a;

a is a char*, so cout starts printing until it finds a null character.
It prints Hello World.

char a = 'p';
cout << &a;

a is a char, but &a is also a char* just like in the last example.
So cout prints the p, and then whatever is after the p in memory until it finds a null byte.

thelamb 163 Posting Pro in Training

Is it a pile of .c, .cpp and .h files? If so, try to add those to a C::B project and set the additional include paths to the same folder. Then try to compile and see how many errors it spits at you.

You can mess around with the object files, but even if you get it to link, it won't be ideal to make changes.

Or, pressure the guy who wrote it to help you ;).

thelamb 163 Posting Pro in Training

You can't execute another query, without freeing the last result.
So you need to do one query, use the results, free the results, do the next query

etc.

thelamb 163 Posting Pro in Training

There are many ways to do this..
Why do you ask if your solution is correct? You can check it for yourself by printing the first 11 values of f, to see if they match a.

Your declaration of 'main' is bad.. I hope the teacher did not show you to do it that way. It will still work though, but it makes more sense to write

int main() {

    return 0;
}
thelamb 163 Posting Pro in Training

Google basically... if you want general information about C++ there are many good books, there is a sticky on this forum with a few good suggestions.

I THINK there are converters for C# to C++ as well, they won't do a good job on big chunks of code, but may help if you need a few functions 'translated'.

thelamb 163 Posting Pro in Training

Basically I want to be able to implement the C# code that occurs into C++ code instead.

Your question is a bit vague...
Do you want to execute C++ code from this C# program so that you can replace it 'in small parts'? If yes... don't even try.

What I think you mean is that you want some ideas on how to write / modify binary files in C++?

This is a good way to learn things though... so what I would do:
- Look at all the major classes in the C# code, it's probably a good idea to stick to roughly the same design in C++.
- Start a new C++ Project :P (don't copy any code from C#).
- Bit by bit start to implement what the C# code is doing, like(I'm guessing here):
* Read the file
* Try some random stuff, like searching in the file, changing something hard-coded etc.
* Write the file

Some things you need to know:
If you want to read a binary file, you need to open the file in 'binary' mode, look up ios::binary in fstream.
Then you just read the entire file in an array, modify what you need and write it back.


If you have any more specific questions (easier for us than kind of guessing what you mean ;)) - please do ask.

thelamb 163 Posting Pro in Training

No, notice the & sign before tc_a? This means tc_a is a reference.
So tc_a will reference p, which essentially makes them one and the same object.

Have you ever used references in function parameters? If not.. this is a good time to read about it ;)

thelamb 163 Posting Pro in Training

Hmm ok that's annoying, but I suppose it makes sense.
I hoped that I overlooked something that would eliminate the copy, too bad ;)

Thanks Narue

thelamb 163 Posting Pro in Training

I'm designing an exception class, but ran into a case where a copy is being made which I don't want (plus, I don't understand why).

Consider the following cases:

// 1
Exception e;
throw e; // Copy: yes

//2
throw Exception(); // Copy: no

//3
throw Exception() << "extra info"; // Copy: yes

//4
Exception e;
e << "extra info"; // Copy: no
throw e; // Copy: yes

//5
Exception() << "test"; // Copy: no

//Where:
const CException& operator<<(const char* p)
{
    m_extramsg.append( p );
    return *this;
}

I can understand why in //1 a copy is made.. it is possible that e is defined before the try/catch and being used after the catch block.
I don't understand why case 3 needs a copy, and this is exactly how I want to use the Exception class. By the way, the copy is (afaik) being made at the return *this; in operator<<

Is there any way I can prevent this copy?

I've used a similar design in another project... had I known that it would make copies all the time I would not have done it...

P.S.
Yes, I catch by reference, also tried const reference but did not seem to matter.

P.S. 2
I don't want the 'const char*' to be an argument to the constructor - I want to basically use the class as cout, with (semi) arbitrary data.. like status codes etc. e.g.:

HRESULT status = Some_function();
if( …
thelamb 163 Posting Pro in Training

Think about what you're doing.

You want to start j at i + 1, is there any orther variable that you could use for this, that IS defined at for( int j=... ) ?

If you declare a variable inside the for statement like this, it is ONLY visible inside the for block, after that you can not use it any more (unless you re-define it).

FutureWebDev commented: This thread is not marked as answered. My post is a suggestion. And how is int i = 0; messy? And the negative counter for being an arrogant self rightous person. Just pm me dude. Or reply in the thread. +0
thelamb 163 Posting Pro in Training

The instance detection won't work if an Event with the same name (or any object with the same name in the Global namespace) exists (as you've discovered). In that case, as defined by the documentation after CreateMutex, GetLastError() returns ERROR_INVALID_HANDLE.

If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Using a sufficiently random name for the mutex should eliminate any accidental name clash. As I think we've already mentioned a few times... if CreateMutex fails, your program should also exit, you've still not added this check so if someone would want to circumvent your protection they just create an Event with the same name, as nicely pointed out by mitrmkar.

I don't know what you mean with problems across LANs. The mutex is local to your computer, it does not check all of the computers on the network to see if they have a mutex with the same name. So two computers on the same LAN can both run your program one time.

However across users, only one user on one PC can run it. So if I log in as UserA, run your program and then switch to UserB, I can not run it again.
The Mutex is created in the 'Global' namespace (hence my suggestion to prepend the Mutex name with Global\ some posts back.

thelamb 163 Posting Pro in Training

I tried CreateProcess for him, to be sure but it suffers from the same problem.
Since I executed that from an elevated cmd I doubt it is at all possible (without a lot of hacking around)

thelamb 163 Posting Pro in Training

It is not trivial to execute bcdedit from a C++ program...

If you open cmd.exe without admin permissions, it also will tell you that the command is not recognized (just bcdedit is enough.. you dont need the whole path), but if you open cmd.exe as admin it does work.

Also, opening cmd.exe with admin privileges, and then executing a C++ program that does system( "bcdedit" ); or CreateProcess( "paht_to_bcdedit", ... ); does not work.

So there is something special about the cmd environment that allows the execution of bcdedit, the environment where your C++ program runs is different from that.
I'm actually glad this is not possible, now not just any program with admin access can edit the boot options.

Why do you want to do this anyway? Maybe there is a better way to do what you want, without bcdedit.

thelamb 163 Posting Pro in Training

How can we help you if we don't know what your program needs the access for... And how do you know it's not working - is there are an error code like that says access is denied?

thelamb 163 Posting Pro in Training

My excuse is that I was doing 5 things at the same time ;) - but well spotted.

I already mentioned in one of my posts that the return value of CreateMutex must be checked, and some error returned if it failed (e.g. the handle is NULL).

I've lost where this thread is going..

thelamb 163 Posting Pro in Training

A singleton class is one that allows only 1 object of its type to be created..

But this will (as far as I know) do you no good, if you run two instances of your program there will be 1 object in each of those instances.. not violating the singleton 'pattern'


--


Unfortunately, I don't have time to test your code on my pc atm.. probably later I can

thelamb 163 Posting Pro in Training

Hmm, that is weird... maybe one of the mutexes during testing didn't clean up properly (even though windows closes any outstanding handles when a program exits).

Try a different name for the mutex.
Also, I think it is cleaner if you name it "Global\somename" - it is clearer to any reader of your code what the purpose of this mutex is then.

Edit, something silly:
try before calling CreateMutex to call

SetLastError(0);
thelamb 163 Posting Pro in Training

I don't know what exactly you mean with 'if I use the code in WinMain it doesnt start' ... can you show us what you have?

The warning makes sense.. you are creating a variable that you never use. However, I guess IF something goes wrong with creating the mutex... you also do not want to run, so you should give an error message back after checking ghMutex.

thelamb 163 Posting Pro in Training

This is a case of reading the documentation carefully:

If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.

With other words, the case of 'The mutex exists' is not considered an error, so the return value will not be NULL.

What you need to do is call GetLastError() and compare it with ERROR_ALREADY_EXISTS

thelamb 163 Posting Pro in Training

Discussing this kind of stuff is never polluting ;)

Your experience is that argv[0] is the program name, and argc >= 1... you're right that this is generally the case but it is never guaranteed. Someone with bad intentions can run your program without argv[0], or replace it with something else. For example on Linux, if you printf( "%s\n", argv[0] ) then an attacker can replace argv[0] with a string that for example changes the colour of the terminal, or even execute another binary.

So, never assume anything - unless it is explicitly guaranteed, and even then be suspicious.

thelamb 163 Posting Pro in Training

Forgive me for being a pain in the ass.

std::cerr << argv[0]

It's bad to assume that argv[0] exists, using any array, you should first check the bounds, in this case: if argc == 1. Or not print argv[0] at all ;)

thelamb 163 Posting Pro in Training

There are several ways...
Create a file on startup, and remove it again on exit.
If on startup the file already exists, then refuse to start.

Or.. a better way: Create a mutex in the global namespace(CreateMutex @msdn) on startup and destroy it on exit. If the creation fails with something like 'mutex already exists', then you know that your program is already running and you can exit.

thelamb 163 Posting Pro in Training

If you compare a building to an ant, are they ever going to be the same?
userCode can be an int, but you will need to convert it to a string before comparing it with code, which is a string. Or it should be possible to change code to an int.

Also, why are the 2 getline calls (after 'read another line') inside the if block? If you only want to read another code if the current one matches userCode then this is fine.. but I guess you want to read the next one when the current code doesnt match the userCode.

If there can only be one userCode in the whole text file, you can 'break;' out of the while loop when userCode==code

thelamb 163 Posting Pro in Training

Better show us the code..

You probably have the implementation of this class in two .cpp files

thelamb 163 Posting Pro in Training

That's because the ascii value of 5 is 53 and of 6 is 54. 53+54=107.
When casting a char to an int, you get the ascii value of that character.

You're better off using frogboy's suggestion, or substract 48 from ch.

(see www.asciitable.com)

thelamb 163 Posting Pro in Training

Depends on the type you're reading..

If you store the user input as string, you can access the individual numbers(characters) just like you would with an array:

string test = "12345";
test[0]; // '1'
test[4]; // '5'
thelamb 163 Posting Pro in Training

When someone is 'tenured' it means that they can not be fired without a 'good reason'.

In C++, a 'Boolean' is 'bool'.
So you can just give the class a member 'bool m_tenured;'

thelamb 163 Posting Pro in Training

You are printing everything... in the while( ! eof ) there should be an if before the cout.

You have 1 'code' variable, that you both use for the input from the user (cin >> code) and when reading from the file(getline(..,code,..)).

You need two variables.. one for the user input (e.g. userCode) and the one you have now, for reading from the file.

Then you check if( userCode == code ) cout << etc.

Hope that helps

thelamb 163 Posting Pro in Training

The whole point that it's not ok is because p20 has the same value...

How is the 'picture' not clear? p20 is pointing to the middle of the allocated 20 bytes, while at the beginning it was pointing to the start.

This is not easy to fix - allocating variable sized blocks from a fixed size (continuous) buffer is inherent to this problem... you need to re-think the allocation strategy.

There are many possible ways, best thing is to find a book on operating systems and reading the memory section - there is a lot of discussion about this stuff.

thelamb 163 Posting Pro in Training

Exactly - the intention of the move is fine(eliminating holes), but there can be allocated memory after what you're freeing right? So you will move this allocated memory to another address, but the person who allocated it will have no idea that you moved it - and just keeps on using it.

In my example the user of p20 assumes that he has 20 bytes, starting from the p20 pointer. But because p10 was free'ed, you moved the allocated 20 bytes back 10 bytes. So if now p20 writes 20 bytes, he will start writing in the middle of his 20-byte block and write 10 bytes past the end.

[ -10-  |     -20-     ]  <-- before
^p10     ^p20

[     -20-     ]          <-- after Free( p10 )
         ^p20

Ok the scaling is not perfect, but hopefully you got the idea ;)

thelamb 163 Posting Pro in Training

Why do you do the memmove in Free? You move whatever is after end, to start.
That makes little sense...
Let's say I allocate 10 bytes, and after that 20.
So I get two pointers from you, p10 and p20.

Now I Free p10, so you move everything that was after p10 to the start of p10.
What if I use my p20 now? It's pointing to something totally different.

Welcome to fragmentation ;)

thelamb 163 Posting Pro in Training
while (start == 1)
  cout << "\n";

Those two lines will be executed forever, you need to indicate all the code that belongs inside the while loop by putting it in { }'s

thelamb 163 Posting Pro in Training
if(nextLetter==phrase[i]);

There is a ; after the if, so letterFound will _always_ be set to true.

Edit:
Also, I think it would be cleaner to use for loops instead of while... the use of while is confusing in this case, and it is very easy to forget the i=0 before the while loop...
I'd say this is better:

for( i=0; i < phraseLength && !letterFound; ++i ) 
{

}
thelamb 163 Posting Pro in Training

Look at QT, it is a cross platform UI 'framework'

thelamb 163 Posting Pro in Training

When you add a Looper, it is 'sliced' to it's base class.
What you need to do is store pointers or references to AudioTrackElement, they will 'preserve' the class hierarchy.

So:

AudioTrackElement* pNewEl = new Looper();
pNewEl->process( ... ); // calls Looper::process

delete pNewEl;
Looper newLoop;
AudioTrackElement newEl = newLoop; // Here it slices the object
newEl.process( ... ); // calls AudioTrackElement::process
thelamb 163 Posting Pro in Training

You have to do some bookkeeping yourself, to keep track of the size.

For instance, a map that maps the pointer to the size

map<byte*,int> m_blockSize;

When you allocate, you add the pointer and the size to this map.. and when you free you search for the pointer, and get the matching size (if the pointer passed to free is not in the map, it's an invalid call to free).

There are other ways, but I think this is quite straight forward.

thelamb 163 Posting Pro in Training

You are calling a function 'isEmpty()'. That does not exist anywhere, does it?
If you want to check if a stack is empty, you can call 'empty()' on the stack.

So:

while( !myStack.empty() )
thelamb 163 Posting Pro in Training

sizeof is a compile-time 'function'... it cannot get the size of dynamic arrays.
So, your code is very wrong... your intention is to write 3 items into a, but there is only space for 0 items.

thelamb 163 Posting Pro in Training

In windows 2000/XP it even seems to be possible in Usermode... to double check that, download physmem from SysInternals (by Mark Russinovich) and check if that runs on your XP machine.

I don't know how long you have left for this... but it is a very complicated thing to read from physical memory (the virtual to physical address translation alone is a pain).

In any case... I'm very interested in the intentions of the teacher... would you mind posting the solution, how he had things in mind after the assignment is finished and he explained?