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 |