Basic Smart Card testing in Windows - c++

I am attempting to simply test for the presence of a Smart Card in Windows. The goal is to have a "daemon" running that will perform an action whenever (and for the duration) a card is inserted.
I have zero experience with things of this nature. I have read the documentation for SCardStatus and such, but I don't understand how the whole API works so I'm a bit lost.
What would be most helpful for me is if someone has a very simple example of a complete program that simply tests for the presence of a card (preferably in C++ but I'll take what I can get!). I would be most appreciative. I don't need any card status other than it exists. Thanks!

if you work on windows you need to use WinSCard API, if you use unix, then use PCSC. These two APIs are very similar, because of standards, but WinSCard API is much bigger and gives much more functions to use. These two APIs are implemented with C language, but you can wrap them in C++ pretty easy. I just whant to point out if you gonna wrap those two APIs in to C++ to use it ever on windows AND on unix take a look at smart card protocols numerical values, those are different on these platforms.
Basics:
You need to establish context (its like creating smart card manager)
SCardEstablishContext
It takes 4 parameters but, for basic using, you need only 2, scope and pointer to context handle.
LPSCARDCONTEXT hSCardContext = NULL;
int ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSCardContext);
if (ret != ERROR_SUCCES) ... // handle error
Smart card are grouped in different groups. So there is functions to work with groups, to create it and so on.
To get readers list (for basic applications you actually dont really need groups)
SCardListReaders
It takes 4 parameters, context, pointer to group, pointer to readers and pointer to reader count
you can use it lise this
char *szGroups = NULL;
long readers = 0;
int res = SCardListReaders(hSCardContext, szGroups, NULL, &readers);
// handle errors
you get readers count first. now you can allocate memory for actual readers.
szReaders = (char *) malloc(sizeof(char) * readers);
int res = SCardListReaders(hSCardContext, szGroups, szReaders , &readers);
Now you have list of readers connected.
You can connect to a reader like so
LPSCARDHANDLE hSCard = NULL;
long activeProtocols = 0;
int ret = SCardConnect(hSCardContext, myReader, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_TX, &hSCard, &activeProtocols);
// .. handle errors
specify protocols, share mode, use SCARD_SHARE_EXCLUSIVE for share mode if youre working with sensitive stuff witch needs protection that OS wont interact with transactions.
Once again if you are wrapping for windows and unix ( unix does not have SCARD_PROTOCOL_TX protocol) but it is a representation of these two SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1.
myReader is the name of connected reader. Like (LPCTSTR)"Dermalog LF10"
you get those reader names from SCardListReaders function.
now you are connected with a card. with SCARD_SHARE_EXCLUSIVE sharing dont forget to release the smart card context, because it will deadlock.
use SCardDisconnect to disconnect, it takes 2 parameters, SmartCard handle, and disposition, for basic application SCARD_LEAVE_CARD disposition should be ok. It specifies that you dont want to do anything special to the card, you dont want to eject or whatever.
Transactions are more complex, because you need to know SCard standards and what not. But i covered the basics.
Keep in mind that this code might not compile, you need to improve types, for windows you need to cast those types in WinAPI types, like LPCTSTR, that it wont complain and unix dont have such types so you need to work around these problems too.

This sample code assumes card readers are plugged in at the start, it does not handle a changing number of card readers.
Other than that, it simply spams the console with inserted / not inserted status of cards.
Please do not use this as-is in production code, most error checking is omitted and some shortcuts are taken to keep the code short(ish).
#pragma comment(lib, "winscard.lib")
#include <vector>
bool test()
{
DWORD dwReaders;
LPSTR szReaders = NULL;
SCARDCONTEXT hContext;
bool bRunning = true;
std::vector<const char*> cards;
LONG status = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
if( status != SCARD_S_SUCCESS ) {
return false;
}
dwReaders = SCARD_AUTOALLOCATE;
if( SCardListReadersA(hContext, NULL, (LPSTR)&szReaders, &dwReaders) == SCARD_S_SUCCESS ) {
LPSTR reader = szReaders;
while (reader != NULL && *reader != '\0') {
std::cout << "Reader name: '" << reader << "'" << std::endl;
cards.push_back( reader );
reader += strlen(reader)+1;
}
LPSCARD_READERSTATEA lpState = new SCARD_READERSTATEA[cards.size()];
for( size_t n = 0; n < cards.size(); ++n ) {
memset( lpState + n, 0, sizeof(SCARD_READERSTATEA) );
lpState[n].szReader = cards[n];
}
do {
status = SCardGetStatusChangeA( hContext, 500, lpState, cards.size() );
switch( status )
{
case SCARD_S_SUCCESS:
case SCARD_E_TIMEOUT:
for( size_t n = 0; n < cards.size(); ++n ) {
if( lpState[n].dwEventState & SCARD_STATE_PRESENT) {
std::cout << "'" << lpState[n].szReader << "' present" << std::endl;
} else {
std::cout << "'" << lpState[n].szReader << "' not present" << std::endl;
}
}
break;
default:
std::cout << "Other result: " << status << std::endl;
break;
}
Sleep( 1000 ); // do not spam too bad
} while( bRunning );
// only do this after being done with the strings, or handle the names another way!
SCardFreeMemory( hContext, szReaders );
}
SCardReleaseContext( hContext );
return true;
}

Related

Reading Memory from Another Process in C++ | Copilot's Solution

As the title suggests, I am trying to read memory from another process in C++ in order to check if the values from the other process reach a certain level. Since I don't know anything about this, I decided to consult GitHub Copilot for help. On a normal basis, I would search the docs, but Github seems to disagree. Since I have access to GitHub Copilot, and since the front page advertisement clearly encourages users to trust Copilot's programming ability, I chose to let Copilot make this function.
So I gave it a prompt in the form of a comment: //A function that can grab an address from the memory of another process and store it as a double value
What it gave me seemed pretty good, but I will never take a function that copilot makes and blindly use it unless I know for sure it will work (because I don't trust that everything Copilot makes is never going to cause issues, especially when dealing with pointers and such). I wanted to see if someone who had experience with memory in C++ could tell me if this function will work and why it would or wouldn't work as I know nothing about getting memory from another process.
There are three main reasons why I am not just searching the docs anyway despite GitHub's statement:
Since this is a complicated and real-world use case, this will really test Copilot's programming ability and it will give me insight into how much I can trust Copilot in the future for stuff I don't know how to do (Obviously I wouldn't let this get out of hand, but it would be good to know I can trust Copilot a little more than I do right now).
Searching the docs anyways despite the statement that GitHub made on their website is quite the opposite of what Copilot is supposed to help users with, and while I understand that it's a public beta and it's not complete yet, it should at least be good enough for real-world use cases rather than simple coding cases. An answer from someone experienced will really show if it is good enough for real-world coding cases.
The docs only tell me what a function does and what to put as its parameters, it doesn't tell me how to use it. If I really wanted to know how to use it, I would have to search the web. Searching the web will most likely get me complicated examples that don't pertain to my issue and defer me from what I am actually trying to accomplish. Not only that, but it is the opposite of what Copilot is supposed to help users with, as stated in reason #2.
Here is the code that Copilot generated for me:
DWORD GetAddress(DWORD dwProcessId, LPCWSTR szModuleName, const char* szProcName)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == NULL)
return 0;
MODULEINFO modinfo;
GetModuleInformation(hProcess, GetModuleHandle(szModuleName), &modinfo, sizeof(MODULEINFO));
DWORD dwAddress = (DWORD)modinfo.lpBaseOfDll;
DWORD dwSize = (DWORD)modinfo.SizeOfImage;
MEMORY_BASIC_INFORMATION mbi;
while (dwSize > 0)
{
VirtualQueryEx(hProcess, (LPVOID)dwAddress, &mbi, sizeof(mbi));
if (mbi.State == MEM_COMMIT && !(mbi.Protect & PAGE_GUARD) && mbi.Protect & PAGE_EXECUTE_READWRITE)
{
DWORD dwOldProtect;
VirtualProtectEx(hProcess, (LPVOID)dwAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
char* szBuffer = new char[mbi.RegionSize];
ReadProcessMemory(hProcess, (LPVOID)dwAddress, szBuffer, mbi.RegionSize, NULL);
for (DWORD dwIndex = 0; dwIndex < mbi.RegionSize - 4; dwIndex++)
{
if (szBuffer[dwIndex] == '\x55' && szBuffer[dwIndex + 1] == '\x8B' && szBuffer[dwIndex + 2] == 'E' && szBuffer[dwIndex + 3] == 'A')
{
DWORD dwAddress2 = dwAddress + dwIndex + 7;
DWORD dwAddress3 = dwAddress2 + *(DWORD*)(dwAddress2);
if (strcmp((char*)dwAddress3, szProcName) == 0)
{
delete[] szBuffer;
CloseHandle(hProcess);
return dwAddress2 + 4;
}
}
}
delete[] szBuffer;
VirtualProtectEx(hProcess, (LPVOID)dwAddress, mbi.RegionSize, dwOldProtect, &dwOldProtect);
}
dwAddress += mbi.RegionSize;
dwSize -= mbi.RegionSize;
}
CloseHandle(hProcess);
return 0;
}
You may point out an immediately noticeable error: The function returns DWORD rather than double, which is what I asked Copilot to return. I saw that error but from examples that I have seen (Yes, I have done at least some searching), returning DWORD works as well. I could have seen those examples wrong, and if I am correct me.
The function returns double but it only returns the value that is stored in the memory, not actually double-typed data. If you do a casting to double, you get back your original data.
You can't search in memory with anything other than a byte pointer on 64-bit systems: http://msdn.microsoft.com/en-us/library/aa746449%28v=vs.85%29.aspx
There are different ways to search for a string in memory, depending on what you are looking for: http://www.catatonicsoft.com/blog/need-to-read-and-write-strings-and-data-in-a-processs-memory/
(Read more here: https://github.com/MicrosoftArchiveOrgMember/copilot)
Memory Scraper
This program uses several techniques to obtain information from processes and memory as it runs so that it can be added to the evidence file when Cofactor terminates the target process (by default) or when you terminate the program manually (with CTRL+C).
This code was mostly cobbled together from various examples at http://www.codeproject.com and https://forums.hak5.org, with some heavy modifications made to get the output in a useful format.
The process memory usage is checked continuously and added to the log file when it changes. This is done by getting a pointer to the process' memory region, then checking all of its pages as they are referenced. When they are changed, the contents of that page will be read and added to the log file as evidence. If a process goes in and out of sleep mode or is stopped for some other reason, this program will detect that and add it to the log file accordingly.
The current DLLs loaded by processes are recorded every 5 seconds so that if a DLL gets loaded after Cofactor terminates its target, it will still be included in the log file as evidence. A process is also checked every 5 seconds for new threads being spawned so that child processes are also included in our evidence files.
We could extend this program by having it check for two modules:
1) A module containing functions that correspond to debug breakpoints (which would detect whether a debugger was attached).
2) A module containing crash signatures - integers that would trigger an alert if they were found written to memory in any of our processes (like stack smashing protections might provide).
In order to do this without complicating things too much, I'd probably use CreateRemoteThread with an address within each module to continue execution from that thread into your own code where you can check for the breakpoint or crash signature and act accordingly.
Conclusion
If you need to debug a process and can't get it to stop for any reason, this program will still be able to grab the process memory at any time so that you can search for whatever you need.
You'll have to do some extra work in order to use the log file that is created, like parsing it with a parser of your choice and searching it (using regexes or something) which I assume is outside of the scope of what Copilot is designed to do.
If you end up using this program, please let me know! I'm curious to see how many people find this program useful.
Interesting Techniques I Learned From Other Programs
Finding DLLs Loaded by a Process
The C++ code below uses the Windows API GetModuleFileNameW() to get the full path of loaded DLLs and parses it with split() to extract just the filename and not the whole path. The rest of that code just tries to avoid duplicates while being simple enough that it doesn't get too confused between different processes and file system cases (hopefully).
// Code Example: Finding DLLs Loaded by a Process
#include <stdio.h>
#include <string.h>
#include <tchar.h>
#define BUFF_SIZE 200
// Find the full path to a loaded DLL by process ID (PID) and its filename (first 8 characters)
void GetModuleFileNameEx(int pid, const char* szName, char* buff, int buffSize)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (hProcess == NULL) { return; }
HMODULE hMods[1024];
DWORD cbNeeded;
if (!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { return; }
for (int i = 0; i < (int)(cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModName[MAX_PATH];
if (!GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName))) { continue; }
strcat_s((char*)buff, buffSize - 1 , (char*)szModName);
// Check if the first 8 characters of the filename in the process matches
// with what we are looking for and avoid adding duplicates
char* chPtr = strchr((char*)buff, '\\');
if (chPtr != NULL) {
*chPtr = 0;
strcat_s((char*)buff, buffSize - 1 , "\\");
strcat_s((char*)buff, buffSize - 1 , szName);
HANDLE hFile = CreateFileA((LPCSTR)buff, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); return; }
} else { break; }
}
}
int main() {
char szDllName[8]; // Maximum length of a module name is MAXPATH - 1 bytes including the NULL terminator. However we only need 8 characters to store the DLL name so use this limit to save memory.
int pid; scanf("%d", &pid);
if (pid == 0) { return 0; }
char buff[BUFF_SIZE];
GetModuleFileNameEx(pid, szDllName, buff, BUFF_SIZE);
char* chPtr = strchr(buff, '\\');
// Change the path separator character to a null terminator so we can split it
if (chPtr != NULL) { *chPtr = 0; }
chPtr = strtok(buff, "\\");
while (chPtr != NULL) {
printf("%s\n", chPtr);
chPtr = strtok(NULL, "\\");
}
return 0;
}

C++ SQLite Serialized Mode Questions

I have been through Quite a few pages, and have an ok Idea of whats happening it think, but I have a few Questions just to be sure....
my program uses the -DTHREADSAFE=1 compile options, forks on receiving a database request (Select, Delete, Insert, Update) from a user or my network, then the child process handles the various database tasks, and relaying of messages should that be required and so on,
at the moment my database is not setup for concurrency which I wont lie is a major design flaw, but that's beside the point at the moment, let's say I have a function that prints all the entries in my table LEDGER as follows...
void PersonalDataBase::printAllEntries()
{
//get all entries
const char query [] = "select * from LEDGER";
sqlite3_stmt *stmt;
int error
try
{
if ((error = sqlite3_prepare(publicDB, query, -1, &stmt, 0 )) == SQLITE_OK)
{
int ctotal = sqlite3_column_count(stmt);
int res = 0;
while ( 1 )
{
res = sqlite3_step(stmt);
if ( res == SQLITE_ROW )
{
Entry *temp = loadBlockRow(stmt);
string from, to;
from = getNameForHash(temp -> from);
to = getNameForHash(temp -> to);
temp -> setFromOrTo(from, 0);
temp -> setFromOrTo(to, 1);
temp -> printEntry();
printlnEnd();
delete temp;
}
else if ( res == SQLITE_DONE || res==SQLITE_ERROR)
{
if (res == SQLITE_ERROR) { throw res; }
sqlite3_finalize(stmt);
break;
}
}
}
//problems
else
{
throw error;
}
}
catch (int err)
{
sqlite3_finalize(stmt);
setupOutput();
cout << "Database Error: " << sqlite3_errmsg(publicDB) << ", Error Code: " << (int) error << endl;
cout << "Did Not Find Values Try Again After Fixing Problems Above." << endl;
printlnEnd();
}
println("Done!");
}
my setupOutput(), printlnEnd(), println(), all help with my use of 'non-blocking' keyboard i/o, they work as I want lets not worry about them here, and think of them as just a call to cout
ok so now at this point I figure there are 4 options...
A while around my try/catch, then in catch check if err = 5, if so I need to setup a sqlite3_busy_handler and have it wait for whatever is blocking the current operation (once it returns SQLITE_OK and have cleaned up all my old variables I reiterate through the while/try again), now as only one of these can be setup at a time, let's say for instance Child1 is doing a large write and child2 and child3 are trying to say read and update concurrently on top of the first child's write, so if a SQLITE_BUSY is returned by this function I print out an error, then restart my while loop (restarting the function), of course after I have finalized my old statement, and cleared up any local objects that may have been created, if this a correct line of thinking?
Should I setup a recursive mutex, say screw it to SQLites own locking mechanism, set it up to be shared across processes then only allow one operation on a database at a time? for using my app on a small scale this doesn't seem to bad of an option, however I'm reading a lot of warnings on using a recursive mutex and am wondering if this is is the best option, as many posts say handle mutual exclusion yourself. however then I cannot have concurrent reads, which is a bit of a pain
Use option 1 but instead of using the SQLite busy handler, just call usleep on a random number, clean up data, and restart while?
before/after any function involving my database use sqlite3_exec() with "BEGIN IMMEDIATE"/"COMMIT" respectively, Locking the database for the duration of the code in between those 2 statements. So that nothing enclosed within can(or at least should) return SQLITE_BUSY, then if my "BEGIN IMMEDIATE" returns BUSY (it should be the only one so long as everything is set up correctly), I use the sqlite3_busy_handler which honestly, if only one process can use it at a time seems annoying... or a random number with usleep(), (presumably at this number is rather large 1mil = 1 second the chance of overlap between 1-20 processes is pretty slim) so each process will constantly try to re lock the database at random intervals for their own purposes
Is there a better way? or which one of these is best?
SQLite's internal busy handler (installed with sqlite3_busy_timeout()) already sleeps a more-or-less random number of times; there is no need to write your own handler.
Using your own locking mechanism would be more efficient than random waiting, but only if you have reader/writer locks.
BEGIN or BEGIN IMMEDIATE ensure that no other statement in the same transaction can run into a lock, but only if IMMEDIATE is used for transactions that write.
To allow concurrent readers and writers, consider using WAL mode. (But this does not allow multiple writers either.)

Problems with pointers and memory adresses

I wonder why this code doesn't work:
#include <iostream>
using namespace std;
int main()
{
int *pointer = (int*)0x02F70BCC;
cout<<*pointer;
return 0;
}
In my opinion it should write on the screen value of 0x02F70BCC,
instead of this my programm crashes.
I know that memory with adress 0x02F70BCC stores value of 20.
But like I said no matter what it just doesn't want to show correct number.
Please help me guys, detailed explanation would be very nice of you.
It doesn't work, because you won't get access to every location in memory you want. Not every location in memory is valid, you may want to read about Virtual Address Space.
Some addresses are reserved for device drivers and kernel mode operations. Another range of addresses (for example 0xCCCCCCCC and higher) may be reserved for uninitialized pointers.
Even if some location is valid, operating system may still deny access to write to/read from certain location, if that would cause undefined behaviour or violate system safety.
EDIT
I think you might be interested in creating some kind of "GameHack", that allows you to modify amount of resources, number of units, experience level, attributes or anything.
Memory access is not a simple topic. Different OSes use different strategies to prevent security violations. But many thing can be done here, after all there is a lot software for doing such things.
First of all, do you really need to write your own tool? If you just want some cheating, use ArtMoney - it is a great memory editor, that I have been using for years.
But if you really have to write it manually, you need to do some research first.
On Windows, for example, I would start from these:
ReadProcessMemory
WriteProcessMemory
Also, I am quite certain, that one of possible techniques is to pretend, that you are a debugger:
DebugActiveProcess.
EDIT 2
I have done some research and it looks, that on Windows (I assume this is your platform, since you mentioned gaming; can't imagine playing anything on crappy Linux), steps required to write another process' memory are:
1. Enumerate processes: (EnumProcesses)
const size_t MAX_PROC_NUM = 512;
DWORD procIDs[MAX_PROC_NUM] = { 0 };
DWORD idsNum = 0;
if(!EnumProcesses(procIDs, sizeof(DWORD) * MAX_PROC_NUM, &idsNum))
//handle error here
idsNum /= sizeof(DWORD); //After EnumProcesses(), idsNum contains number of BYTES!
2. Open required process. (OpenProcess,GetModuleFileNameEx)
const char* game_exe_path = "E:\\Games\\Spellforce\\Spellforce.exe"; //Example
HANDLE game_proc_handle = nullptr;
DWORD proc_access = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE; //read & write memory, query info needed to get .exe name
const DWORD MAX_EXE_PATH_LEN = 1024;
for(DWORD n = 0 ; n < idsNum ; ++idsNum)
{
DWORD current_id = procIDs[n];
HANDLE current_handle = OpenProcess(proc_access, false, current_id);
if(!current_handle)
{
//handle error here
continue;
}
char current_path[MAX_EXE_PATH_LEN];
DWORD length = GetModuleFileNameEx(current_handle, nullptr, current_path, MAX_EXE_PATH_LEN);
if(length > 0)
{
if(strcmp(current_path, game_exe_path) == 0) //that's our game!
{
game_proc_handle = current_handle;
break;
}
}
CloseHandle(current_handle); //don't forget this!
}
if(!game_proc_handle)
//sorry, game not found
3. Write memory (WriteProcessMemory)
void* pointer = reinterpret_cast<void*>(0x02F70BCC);
int new_value = 5000; //value to be written
BOOL success = WriteProcessMemory(game_proc_handle, pointer, &new_value, sizeof(int), nullptr);
if(success)
//data successfully written!
else
//well, that's... em...
This code is written just 'as is', but I see no errors, so you can use it as your starting point. I also provided links for all functions I used, so with some additional research (if necessary), you can achieve what you are trying to.
Cheers.
When you use,
cout<<*pointer;
the program tries to dereference the value of the pointer and writes the value at the address.
If you want to print just the pointer, use:
cout << pointer;
Example:
int main()
{
int i = 20;
int* p = &i;
std::cout << *p << std::endl; // print the value stored at the address
// pointed to by p. In this case, it will
// print the value of i, which is 20
std::cout << p << std::endl; // print the address that p points to
// It will print the address of i.
}

Word-Net Thread safety

I am using Word-Net in a C++ project (although the library is in C). In specific, I am calling only two functions:
findtheinfo_ds
traceptrs_ds
Now, if I understand correctly the underlying structure (its quite old as it was written in the late nineties I think), the library uses files as the database from where it retrieves the buffer results I get.
However, I am not sure about the thread safety of the library.
My current algorithm is:
SynsetPtr syn = findtheinfo_ds( query , NOUN, HYPERPTR, ALLSENSES );
if ( syn )
{
// Iterate all senses
while ( syn )
{
for ( int i = 0; i < syn->wcount; i++ )
std::cout << "synonym: " << syn->words[i] << std::endl;
int i = 0;
SynsetPtr ptr = traceptrs_ds( syn, HYPERPTR, NOUN, 1 );
while ( ptr )
{
for ( int x = 0; x <= i; x++ )
std::cout << "\t";
for ( int i = 0; i < ptr->wcount; i++ )
std::cout << ptr->words[i] << ", ";
std::cout << std::endl;
i++;
auto old_ptr = ptr;
ptr = traceptrs_ds( ptr, HYPERPTR, NOUN, 1 );
free_syns( old_ptr );
}
free_syns( ptr );
syn = syn->nextss;
}
free_syns( syn );
}
}
However, I want to run parallel threads, searching for different words at the same time.
I understand that most UNIX/Linux distributions of today have thread-safe file system calls.
Furthermore, I intend to access to the above loop, per one thread only.
What I am worried about, is that before this loop above, a
wninit();
call has to take place, which makes me assume that in the library, a singleton is somewhere initialized. I cannot take a peek at the code as it is closed-source, and I do not have access to that singleton, as winit() only returns an int for success.
Is there any way to either:
Ensure thread-safety in this scenario, or
Find out (through any possible way), if the library is thread safe?
It is loaded dynamically, from a Debian package called wordnet-base, which installs libwordnet-3.0.so
Many thanks to anyone who can help!
Well, the only way to ensure that a library is really thread-safe, is to analyze its code. Or simply ask its author and then trust hisr/her answer:). Usually data stored on disk isn't the cause of thread unsafety but there's a lot of places where code may break in a multi-threaded environment. One has to check for global variables, existance of variables declared static inside library functions etc.
There's however a solution which could be used if you don't have time and/or intent to study the code. You may use a multiprocess technique when parallel tasks are performed in worker processes, not worker threads, and there's a director process which prepares job units for workers and collects results. Depending on the task such workers may be implemented as FastCGI, or communicate with parent using Boost.Interprocess

Runtime check failure #2 C/C++

I have encountered a problem in my program that has me somewhat stumped. I had a program that was working fine (it was working fine on VS 2010 this is not an I upgraded to .NET and this error started happening post) with a program that is mostly c and some c++ (my boss HATES object oriented since it usually involves making calls to libraries that he is paranoid microsoft will stop supporting and would also have to be delivered to the customer if they have an older version which could be a problem since a lot of them are government and he also thinks that these calls cause unnecessary overhead so I have to try to avoid it as much as possible) then I uncommented a block of code (I will post this block a little lower as it has been modified some from the original one I uncomented) to start working on it and got the error "Runtime check error #2 the stack around "std" has been corrupted" where std is a c style string of wchar.
I tried to figure out what the problem was by implementing some of the not so good fixes since if one works I will know what the actual problem is and then have a good base starting point for debugging. First I tried to increase the size of std to make it large enough that I wouldn't be putting a string larger than it can handle in it (it's values come from no more than 3 columns from a list view each of which can't be bigger than 80 characters) and even though this made me get the error less often I still got it.
So I tried switching std in that block of code to msg (which was exactly the same as std at the time) to see if msg got the same error (which would mean it was produced by that block of code) but the error still came up around std.
case IDC_TXT:
//FileSaveBox(hwnd, L"Save as...",L"Text Files (*.txt)\0*.txt\0All Files\0*.*\0",L"*.txt",wFileName);
FileSaveBox(hwnd, L"Save as...",L"CSV (Coma delimited) (*.csv)\0*.csv\0All Files\0*.*\0",L"*.csv",wFileName);
if(wcslen(wFileName)==0) return 0;
fin.open(wFileName);
if(fin.is_open())
val=MessageBox(hwnd,L"This file allready exists. Do you want to overwrite it?",L"Confirm Save", MB_YESNO);
fin.close();
if (val == IDNO)
return 0;
fout.open(wFileName);
if(!fout.is_open()) return 0;
/*if ((fp = _wfopen (wFileName, L"w"))==NULL)
{
Message("Cannot Open File");
return 0;
}*/
_swprintf(msg,L"Some string");
if(im.col3)
wcscat(msg,L", another string");
fout << msg << L"\n";
count = ListView_GetItemCount(hlvim);
for(i=0;i<count;i++)
{
ListView_GetItemText(hlvim,i,0,msg,240);
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,1,temp,80);
wcscat(msg,temp);
if(im.col3)
{
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,2,temp,80);
wcscat(msg,temp);
}
fout << msg << L"\n";
//fprintf(fp,"%s\n",msg);
}
//fclose(fp);
fout.close();
SetFocus(hwnd);
return 0;
This made me think that maybe it was just some other variable writing over the canary around std so I commented it out after replacing all instances of it with msg (execpt for the ones where it is a local variable to a function that hasn't gotten called yet when the error occurs) but this just caused the error to appear around msg (which actually also shows up as a local variable to a function).
Next I tried declaring msg on the heap instead of the stack by using static (since using new would involve my bosses so hated modern code) but this only cased the following error to occur: "Unhandled exception at 0x00300030 in HTZx86.exe: 0xC0000005: Access violation reading location 0x00300030." and at location 0x00300030 is a call to an external API which I have no control over.
Now after I have made some unrelated modifications to other parts of my code I randomly get the stack arror around std and msg at the same time (sometimes after the function call and sometimes before) and not on a consistent basis ether. I would like to know if there is any good way to debugged this problem since break points alone aren't helping me and neither is the call stack (although I may be using them wrong)?
Bellow are the declarations of the variables and the only other place where it would be called before the function gets called:
Declarations:
int i,j,k,count,val,ntx,nrx,IsActive, rxcount;
BOOL callsign, map2rx, rxhit;
double f1,f2,f3;
WCHAR str[80];
static WCHAR msg[240];
WCHAR temp[80];
static short dir;
//FILE* fp;
std::wofstream fout;
std::wifstream fin;
LV_COLUMN pcol;
LV_ITEM pit, pit2;
static HWND hlvtx;
static HWND hlvrx;
static HWND hlvim;
and other calls:
count = ExternalAPIFunction2t();
for(i=0;i<count;i++)
{
ntx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBTXCH));
nrx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBRXCH));
IsActive = _wtoi(ExternalAPIFunction1(i+1,_SP_ISACTIVE));
try
{
for(j=0;j<ntx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_TXCH01+j));
_swprintf(msg,L"%09.4f MHz",f1);
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy_s(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat_s(msg,L"_CH");
_itow(j+1,temp,80);
wcscat_s(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvtx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_NOMINALPOWER));
_swprintf(msg,L"%.1f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
}
}catch(std::exception &e)
{
MessageBox(hwnd,(wchar_t*) e.what(),L"Error", MB_OK);
}
for(j=0;j<nrx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXCH01+j));
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat(msg,L"_CH");
_itow(j+1,temp,10);
wcscat(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvrx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXBANDWIDTH));
_swprintf(msg,L"%.2f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
}
}
P.S. ExternalAPIFunction1 was the one with the access violation.
The code is littered with time bombs. That starts with FileSaveBox where you pass a string buffer but don't tell the function how long the buffer is. Add copious amounts of _swprintf, wcscpy and wcscat calls, none of which checks if the buffer may overrun and the RTC error is easily explained.
You know how to use wcspcy_s and wcscat_s, make it consistent.