Diff of /SharedMemoryWinCpp/MyShmExample.cpp [000000] .. [r1]  Maximize  Restore

Switch to unified view

a b/SharedMemoryWinCpp/MyShmExample.cpp
1
// MyShmExample.cpp : Defines the entry point for the console application.
2
//
3
4
#include "stdafx.h"
5
#include <Windows.h>
6
#include <Windowsx.h>
7
#include <stdio.h>
8
#include <conio.h>
9
#include <stdlib.h>
10
11
#if 0
12
//Beispiel wie man mit eingeschalteter UAC für den lokalen Prozess die erforderlichen Rechte anfordern kann.
13
static void* BuildSDForAccessToAllAuthenticatedUsers(SECURITY_DESCRIPTOR* pSD) 
14
{
15
#if defined (_WIN32_WCE)
16
    return NULL;
17
#else
18
    DWORD  dwAclLength;
19
    PSID   pAuthenticatedUsersSID = NULL;
20
    PACL   pDACL   = NULL;
21
    BOOL   bResult = FALSE;
22
    PACCESS_ALLOWED_ACE pACE = NULL;
23
    SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
24
25
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
26
27
    // initialize the security descriptor
28
    if (InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
29
    {
30
        // obtain a sid for the Authenticated Users Group
31
        if (AllocateAndInitializeSid(&siaNT, 1, SECURITY_AUTHENTICATED_USER_RID, 0, 0, 
32
                0, 0, 0, 0, 0, &pAuthenticatedUsersSID)) 
33
        {
34
            // NOTE:
35
            // 
36
            // The Authenticated Users group includes all user accounts that
37
            // have been successfully authenticated by the system. If access
38
            // must be restricted to a specific user or group other than 
39
            // Authenticated Users, the SID can be constructed using the
40
            // LookupAccountSid() API based on a user or group name.
41
42
            // calculate the DACL length
43
            dwAclLength = sizeof(ACL) 
44
                            // add space for Authenticated Users group ACE
45
                            + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
46
                            + GetLengthSid(pAuthenticatedUsersSID);
47
48
            // allocate memory for the DACL
49
            pDACL = (PACL) malloc(dwAclLength);
50
            if (pDACL) 
51
            {
52
                // initialize the DACL
53
                if (InitializeAcl(pDACL, dwAclLength, ACL_REVISION)) 
54
                {
55
                    // add the Authenticated Users group ACE to the DACL with
56
                    // GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access
57
                    if (AddAccessAllowedAce(pDACL, ACL_REVISION, 
58
                            GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | SECTION_ALL_ACCESS,
59
                            pAuthenticatedUsersSID)) 
60
                    {
61
                        if (SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE)) 
62
                            bResult = TRUE;
63
                    }
64
                }
65
            }
66
        }
67
    }
68
69
    if (!bResult)
70
    {
71
        if (pAuthenticatedUsersSID) 
72
            FreeSid(pAuthenticatedUsersSID);
73
74
        if (pDACL)
75
        {
76
            free(pDACL);
77
            pDACL = NULL;
78
        }
79
    }
80
    return pDACL;
81
#endif
82
}
83
#endif
84
85
#include <WtsApi32.h>
86
/* help functions for shared memory on windows vista */
87
typedef struct _COPIED_WTS_SESSION_INFO {
88
  DWORD SessionId;
89
  LPSTR pWinStationName;        /* A-function, so we have a char-string */
90
  DWORD dummy;                  /* originally an enum */
91
} COPIED_WTS_SESSION_INFO, *PCOPIED_WTS_SESSION_INFO;
92
93
BOOL LocalSysCreateNamedShm(char* szName, unsigned long ulSize, HANDLE* phShmHandle, void** ppUserSpace)
94
{
95
    HANDLE  hProcess;
96
    unsigned long lMinimumWorkingSetSize;
97
    unsigned long lMaximumWorkingSetSize;
98
    // the global... is needed for the following case: 
99
    // - runtime is running as a system service (the default for the plcwinnt)
100
    // - runtime wants to communicate with a process that does not run under the system accout
101
    // -> Will fail because of the different namespaces, at least in Windows Vista!
102
    // Problem occurred in the Targetvisu that is started from the service unter Vista
103
104
    char szNameBuffer[MAX_PATH];
105
    char szGlobalPrefix[] = "Global\\";
106
    char szSessionPrefix[] = "Session\\";
107
108
    strcpy(szNameBuffer, szGlobalPrefix);
109
    strcat(szNameBuffer, szName);
110
111
    // prefer the global entry and afterwards check for the local name
112
    *phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szNameBuffer);
113
    if (*phShmHandle == 0) 
114
        *phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szName);
115
116
    // check if a shared memory exists in any active user session
117
    if (*phShmHandle == 0)
118
    {
119
        /* walk over all sessions to check if the shared memory is opened somewhere */
120
        COPIED_WTS_SESSION_INFO* pResult;
121
        DWORD dwCount;
122
        DWORD i;
123
124
        WTSEnumerateSessions(0 /* current machine */, 0, 1, (WTS_SESSION_INFO**)&pResult, &dwCount);
125
126
        for (i = 0; i < dwCount; ++i)
127
        {
128
            char szTemp[15];
129
            strcpy(szNameBuffer, szSessionPrefix);
130
            strcat(szNameBuffer, _itoa((int) pResult[i].SessionId, szTemp, 10));
131
            strcat(szNameBuffer, "\\");
132
            strcat(szNameBuffer, szName);       
133
134
            *phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szNameBuffer);
135
            if (*phShmHandle != 0)
136
                break;
137
        }
138
139
        WTSFreeMemory(pResult);
140
    }
141
142
    if (*phShmHandle == 0)
143
    {
144
#if 0
145
        //See examlpe above how to obtain a security descriptor. 
146
        SECURITY_ATTRIBUTES sa;
147
        SECURITY_ATTRIBUTES* psa = NULL;
148
        if (s_pSecurityDescriptorData)
149
        {
150
            sa.nLength = sizeof(sa);
151
            sa.bInheritHandle = FALSE;
152
            sa.lpSecurityDescriptor = &s_SecurityDescriptor;
153
            psa = &sa;
154
        }
155
#endif
156
157
        //*phShmHandle = CreateFileMapping((HANDLE)0xffffffff, psa, PAGE_READWRITE, 0, ulSize, szName);
158
        *phShmHandle = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE, 0, ulSize, szName);
159
    }
160
161
    if (*phShmHandle == 0)
162
    {
163
        return FALSE;
164
    }
165
    *ppUserSpace = MapViewOfFile((HANDLE)*phShmHandle, FILE_MAP_WRITE, 0, 0, 0);
166
    if (*ppUserSpace == NULL)
167
    {
168
        return FALSE;
169
    }
170
171
    hProcess = GetCurrentProcess();
172
    GetProcessWorkingSetSize(hProcess, (PSIZE_T)&lMinimumWorkingSetSize, (PSIZE_T)&lMaximumWorkingSetSize);
173
    if (lMinimumWorkingSetSize <= ulSize)
174
    {
175
        lMinimumWorkingSetSize = ulSize + 0x10000UL;
176
        if(lMaximumWorkingSetSize <= lMinimumWorkingSetSize)
177
        {
178
            lMaximumWorkingSetSize = lMinimumWorkingSetSize + 0x1000000UL;
179
        }
180
        if (!SetProcessWorkingSetSize(hProcess, lMinimumWorkingSetSize, lMaximumWorkingSetSize))
181
        {
182
            DWORD dwError = GetLastError();
183
        /*  return 0; When this call produces an error, everything still seems to work, but returning 0 will lead to a crash of Targetvisu.*/
184
        }
185
    }
186
    /* Lock memory mapped file */
187
    if (!VirtualLock((LPVOID)*ppUserSpace, ulSize))
188
    {
189
        DWORD dwError = GetLastError();
190
        /* TOCHECK: Don't know why locking does not work for SHM larger than 1MB */
191
        /*return 0;*/
192
    }
193
194
    return TRUE;
195
}
196
197
198
199
struct DataExchangeStruct
200
{
201
    INT32 i1;
202
    INT32 i2;
203
};
204
int main(int argc, char* argv[])
205
{
206
    HANDLE hShmRead, hShmWrite;
207
    DataExchangeStruct* pDESRead = NULL;
208
    DataExchangeStruct* pDESWrite = NULL;
209
210
    printf("Opening Shared Memory _CODESYS_SharedMemoryTest_Write (means a memory mapped file)...\n");
211
    LocalSysCreateNamedShm("_CODESYS_SharedMemoryTest_Write",sizeof(DataExchangeStruct),&hShmRead,(void**)&pDESRead);
212
    printf("ShmPointer: 0x%X, handle: 0x%X \n",pDESRead,pDESRead);
213
214
    printf("Opening Shared Memory _CODESYS_SharedMemoryTest_Read (means a memory mapped file)...\n");
215
    LocalSysCreateNamedShm("_CODESYS_SharedMemoryTest_Read",sizeof(DataExchangeStruct),&hShmWrite,(void**)&pDESWrite);
216
    printf("ShmPointer: 0x%X, handle: 0x%X \n",pDESWrite,hShmWrite);
217
218
    if(pDESRead == NULL)
219
    {
220
        printf("Could not Created SHM!\r\n");
221
        return 1;
222
    }
223
224
    while(!_kbhit())
225
    {
226
        printf("Read: i1:%d, i2:%d  Write: i1:%d, i2:%d                 \r", pDESRead->i1, pDESRead->i2, pDESWrite->i1, pDESWrite->i2);
227
        pDESWrite->i1++;
228
        if(pDESWrite->i1 > 1000)
229
            pDESWrite->i1 = 0;
230
        pDESWrite->i2--;
231
        if(pDESWrite->i2 < -1000)
232
            pDESWrite->i2 = 0;
233
        Sleep(200);
234
    }
235
    return 0;
236
}
237