DLL shared variables problem

I have writen a DLL which is used by several different apps

There are 2 global variables (called started and currentLoggedLevel) that I want to be shared so that if one app makes started=TRUE, every other app sees started as true.
The way I have tried to go about this is to declared the variables as follows:



#pragma data_seg (".shared")
   
     bool started = false;
     int currentLoggedLevel = -1;

#pragma data_seg()


and then to include the following in my .DEF file

SECTIONS
.shared READ WRITE SHARED;



This does not seem to work, and if one application makes started=TRUE, the others still see it as false.

My question is should this technique work i.e. have I got the right idea but have probably done something wrong somewhere else (if not, what technique could I use to achieve this "shared" behaviour ?).


tpemckiernanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

vadikCommented:
This is my dll without a *.def file. This is working correct.

#include "stdafx.h"
#include "shr.h"

#include <stdlib.h>
#include <tchar.h>



#pragma data_seg (".shared")
 
    bool started = false;
    int currentLoggedLevel = -1;

#pragma data_seg()

#pragma comment(linker, "/SECTION:.shared,RWS")



BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                          )
{
    switch (ul_reason_for_call)
     {
          case DLL_PROCESS_ATTACH:
               if (started)
               {
                    TCHAR buf[10];

                    _itot(currentLoggedLevel++, &buf[0], 10);

                    MessageBox(0, TEXT("started"), &buf[0], MB_OK);
                   
               }
               else
               {
                    MessageBox(0, TEXT("not started"), TEXT("not started"), MB_OK);
                    started = true;
                    currentLoggedLevel++;
               }

          case DLL_THREAD_ATTACH:
          case DLL_THREAD_DETACH:
          case DLL_PROCESS_DETACH:
               break;
    }
    return TRUE;
}
0
DanRollinsCommented:
tpemckiernan,
Did that work for you?  If that did not work, try:

    static bool started = false;
    static int currentLoggedLevel = -1;

Please reply to all comments.  Thanks for maintaining your open questions!
-- Dan
0
tpemckiernanAuthor Commented:
Thanks for your suggestions.

declaring the variables as static didn't seem to help

However, the linker comment did seem to help - when apps call the DLL they can read the correct values. However, other DLLS don't read the correct values - any idea why this might be ?
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

vadikCommented:
What do you means "However, other DLLS don't read the correct values - any idea why this might be "??
DLL's in other processes? Sorry for my English...
0
DanRollinsCommented:
>>what technique could I use to achieve this "shared" behaviour

A very simple technique is to create a global MUTEX.

#define strMutexName "MyAppsDllIsWorking"

HANDLE hMutex;
DWORD  dwLastError;

hMutex= CreateMutex(NULL, FALSE, strMutexName);
dwLastError= GetLastError();
if (hMutex==0) {
    // some screball erro, probaly strMutexName has slashes or something
}

if ( dwLastError == ERROR_ALREADY_EXISTS ) {
    // the DLL is already running or whatever
}

.... later....
CloseHandle( hMutex );

=-=-=-=-=-=-=-=-=-=-=-=-
I'm not sure exactly what you are going for, but here is how this works... see if it will do the trick for you:

Whenever any program or DLL or anything executes that CreateMutex API call with the sanem name, the first time it is called, you will get a handle return and no error.  But the next time it is called, you will get

  dwLastError == ERROR_ALREADY_EXISTS

so, you know that some other process called it first.  So the combination of CreateMutex and GetLastError makes for a one-shot 'gateway'.

Mutexes are more often used in synchronzing threads and processes via fns like WaitForSingleObject (and other complicated stuff), but they can also be used in a simpler fashion as shown.

If you are writing in C++, I can give you a tight little class call CLimitSingleInstance that uses this techique to prevent a user from running a second copy of my program and instead I can display the first one (it's probably forgotton on the taskbar).

-- Dan
0
keitha1Commented:
As far as I know, the simplest way to share memory between processes is by using memory-mapped files.
0
vadikCommented:
I don't think so because it's very expensive solution for  two variables only...
0
DanRollinsCommented:
This was hard to track down -- I know the technique works since I've used it in hook DLLs, but when I tried, it kept failing!

A clue: Dunpbin did not even display the .shared section!

Here it is:
      HOWTO: Share Data Between Different Mappings of a DLL
      http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B125677
and
      http://msdn.microsoft.com/library/en-us/vccore/html/_core_How_do_I_share_data_in_my_DLL_with_an_application_or_with_other_DLLs.3f.asp


In the "fine print" it says that you need to use INITIALIZED data!  For instance, this will fail...

      #pragma data_seg(".shared")
          int nShared;  
      #pragma data_seg()

but this will work exactly as advertized:

      #pragma data_seg(".shared")
         int nShared= 77;  
      #pragma data_seg()


I used the following code for testing (and my thanks go out to  vadik  for the #pragma(linker,... ) tip -- it's better than the often-documented .DEF file variation.

#include "stdafx.h"
#include "DllSharedMem.h"

#pragma data_seg(".shared")   // Make a new section that we'll make shared
   int nShared=77;  
#pragma data_seg() // Back to regular, nonshared data
#pragma comment(linker, "/SECTION:.shared,RWS")

int nUnshared;  

BOOL APIENTRY DllMain( HANDLE hModule, DWORD reason, LPVOID lpReserved ) {
      return TRUE;
}
DLLSHAREDMEM_API int  GetUnsharedInt(void) { return nUnshared; }
DLLSHAREDMEM_API void SetUnsharedInt(int nNewVal) { nUnshared= nNewVal; }
DLLSHAREDMEM_API int  GetSharedInt(void) { return nShared; }
DLLSHAREDMEM_API void SetSharedInt(int nNewVal) { nShared= nNewVal; }


Use that DLL in several processes and the nShared value will be the same everywhere.  There is one thing to watch out for.... If you have more than one copy of the DLL, or if you gave just one copy, but it can be called using different path names, then the modules are considered different and nothing is shard, including code or SHARED data.   See:
      PRB: Problem with Shared Data Sections in DLLs.
      http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B147136

-- Dan
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.