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

Switch to side-by-side view

--- a
+++ b/SharedMemoryWinCpp/MyShmExample.cpp
@@ -0,0 +1,237 @@
+// MyShmExample.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+#include <Windows.h>
+#include <Windowsx.h>
+#include <stdio.h>
+#include <conio.h>
+#include <stdlib.h>
+
+#if 0
+//Beispiel wie man mit eingeschalteter UAC für den lokalen Prozess die erforderlichen Rechte anfordern kann.
+static void* BuildSDForAccessToAllAuthenticatedUsers(SECURITY_DESCRIPTOR* pSD) 
+{
+#if defined (_WIN32_WCE)
+	return NULL;
+#else
+	DWORD  dwAclLength;
+	PSID   pAuthenticatedUsersSID = NULL;
+	PACL   pDACL   = NULL;
+	BOOL   bResult = FALSE;
+	PACCESS_ALLOWED_ACE pACE = NULL;
+	SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
+
+	SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
+
+	// initialize the security descriptor
+	if (InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
+	{
+		// obtain a sid for the Authenticated Users Group
+		if (AllocateAndInitializeSid(&siaNT, 1, SECURITY_AUTHENTICATED_USER_RID, 0, 0, 
+				0, 0, 0, 0, 0, &pAuthenticatedUsersSID)) 
+		{
+			// NOTE:
+			// 
+			// The Authenticated Users group includes all user accounts that
+			// have been successfully authenticated by the system. If access
+			// must be restricted to a specific user or group other than 
+			// Authenticated Users, the SID can be constructed using the
+			// LookupAccountSid() API based on a user or group name.
+
+			// calculate the DACL length
+			dwAclLength = sizeof(ACL) 
+							// add space for Authenticated Users group ACE
+							+ sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
+							+ GetLengthSid(pAuthenticatedUsersSID);
+
+			// allocate memory for the DACL
+			pDACL = (PACL) malloc(dwAclLength);
+			if (pDACL) 
+			{
+				// initialize the DACL
+				if (InitializeAcl(pDACL, dwAclLength, ACL_REVISION)) 
+				{
+					// add the Authenticated Users group ACE to the DACL with
+					// GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access
+					if (AddAccessAllowedAce(pDACL, ACL_REVISION, 
+							GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | SECTION_ALL_ACCESS,
+							pAuthenticatedUsersSID)) 
+					{
+						if (SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE)) 
+							bResult = TRUE;
+					}
+				}
+			}
+		}
+	}
+
+	if (!bResult)
+	{
+		if (pAuthenticatedUsersSID) 
+			FreeSid(pAuthenticatedUsersSID);
+
+		if (pDACL)
+		{
+			free(pDACL);
+			pDACL = NULL;
+		}
+	}
+	return pDACL;
+#endif
+}
+#endif
+
+#include <WtsApi32.h>
+/* help functions for shared memory on windows vista */
+typedef struct _COPIED_WTS_SESSION_INFO {
+  DWORD SessionId;
+  LPSTR pWinStationName;		/* A-function, so we have a char-string */
+  DWORD dummy;					/* originally an enum */
+} COPIED_WTS_SESSION_INFO, *PCOPIED_WTS_SESSION_INFO;
+
+BOOL LocalSysCreateNamedShm(char* szName, unsigned long ulSize, HANDLE* phShmHandle, void** ppUserSpace)
+{
+	HANDLE	hProcess;
+	unsigned long lMinimumWorkingSetSize;
+	unsigned long lMaximumWorkingSetSize;
+	// the global... is needed for the following case: 
+	// - runtime is running as a system service (the default for the plcwinnt)
+	// - runtime wants to communicate with a process that does not run under the system accout
+	// -> Will fail because of the different namespaces, at least in Windows Vista!
+	// Problem occurred in the Targetvisu that is started from the service unter Vista
+
+	char szNameBuffer[MAX_PATH];
+	char szGlobalPrefix[] = "Global\\";
+	char szSessionPrefix[] = "Session\\";
+
+	strcpy(szNameBuffer, szGlobalPrefix);
+	strcat(szNameBuffer, szName);
+
+	// prefer the global entry and afterwards check for the local name
+	*phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szNameBuffer);
+	if (*phShmHandle == 0) 
+		*phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szName);
+
+	// check if a shared memory exists in any active user session
+	if (*phShmHandle == 0)
+	{
+		/* walk over all sessions to check if the shared memory is opened somewhere */
+		COPIED_WTS_SESSION_INFO* pResult;
+		DWORD dwCount;
+		DWORD i;
+
+		WTSEnumerateSessions(0 /* current machine */, 0, 1, (WTS_SESSION_INFO**)&pResult, &dwCount);
+
+		for (i = 0; i < dwCount; ++i)
+		{
+			char szTemp[15];
+			strcpy(szNameBuffer, szSessionPrefix);
+			strcat(szNameBuffer, _itoa((int) pResult[i].SessionId, szTemp, 10));
+			strcat(szNameBuffer, "\\");
+			strcat(szNameBuffer, szName);		
+
+			*phShmHandle = OpenFileMapping(FILE_MAP_WRITE, TRUE, szNameBuffer);
+			if (*phShmHandle != 0)
+				break;
+		}
+
+		WTSFreeMemory(pResult);
+	}
+
+	if (*phShmHandle == 0)
+	{
+#if 0
+		//See examlpe above how to obtain a security descriptor. 
+		SECURITY_ATTRIBUTES sa;
+		SECURITY_ATTRIBUTES* psa = NULL;
+		if (s_pSecurityDescriptorData)
+		{
+			sa.nLength = sizeof(sa);
+			sa.bInheritHandle = FALSE;
+			sa.lpSecurityDescriptor = &s_SecurityDescriptor;
+			psa = &sa;
+		}
+#endif
+
+		//*phShmHandle = CreateFileMapping((HANDLE)0xffffffff, psa, PAGE_READWRITE, 0, ulSize, szName);
+		*phShmHandle = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE, 0, ulSize, szName);
+	}
+
+	if (*phShmHandle == 0)
+	{
+		return FALSE;
+	}
+	*ppUserSpace = MapViewOfFile((HANDLE)*phShmHandle, FILE_MAP_WRITE, 0, 0, 0);
+	if (*ppUserSpace == NULL)
+	{
+		return FALSE;
+	}
+
+	hProcess = GetCurrentProcess();
+	GetProcessWorkingSetSize(hProcess, (PSIZE_T)&lMinimumWorkingSetSize, (PSIZE_T)&lMaximumWorkingSetSize);
+	if (lMinimumWorkingSetSize <= ulSize)
+	{
+		lMinimumWorkingSetSize = ulSize + 0x10000UL;
+		if(lMaximumWorkingSetSize <= lMinimumWorkingSetSize)
+		{
+			lMaximumWorkingSetSize = lMinimumWorkingSetSize + 0x1000000UL;
+		}
+		if (!SetProcessWorkingSetSize(hProcess, lMinimumWorkingSetSize,	lMaximumWorkingSetSize))
+		{
+			DWORD dwError = GetLastError();
+		/*	return 0; When this call produces an error, everything still seems to work, but returning 0 will lead to a crash of Targetvisu.*/
+		}
+	}
+	/* Lock memory mapped file */
+	if (!VirtualLock((LPVOID)*ppUserSpace, ulSize))
+	{
+		DWORD dwError = GetLastError();
+		/* TOCHECK: Don't know why locking does not work for SHM larger than 1MB */
+		/*return 0;*/
+	}
+
+	return TRUE;
+}
+
+
+
+struct DataExchangeStruct
+{
+	INT32 i1;
+	INT32 i2;
+};
+int main(int argc, char* argv[])
+{
+	HANDLE hShmRead, hShmWrite;
+	DataExchangeStruct* pDESRead = NULL;
+	DataExchangeStruct* pDESWrite = NULL;
+
+	printf("Opening Shared Memory _CODESYS_SharedMemoryTest_Write (means a memory mapped file)...\n");
+	LocalSysCreateNamedShm("_CODESYS_SharedMemoryTest_Write",sizeof(DataExchangeStruct),&hShmRead,(void**)&pDESRead);
+	printf("ShmPointer: 0x%X, handle: 0x%X \n",pDESRead,pDESRead);
+
+	printf("Opening Shared Memory _CODESYS_SharedMemoryTest_Read (means a memory mapped file)...\n");
+	LocalSysCreateNamedShm("_CODESYS_SharedMemoryTest_Read",sizeof(DataExchangeStruct),&hShmWrite,(void**)&pDESWrite);
+	printf("ShmPointer: 0x%X, handle: 0x%X \n",pDESWrite,hShmWrite);
+
+	if(pDESRead == NULL)
+	{
+		printf("Could not Created SHM!\r\n");
+		return 1;
+	}
+
+	while(!_kbhit())
+	{
+		printf("Read: i1:%d, i2:%d  Write: i1:%d, i2:%d                 \r", pDESRead->i1, pDESRead->i2, pDESWrite->i1, pDESWrite->i2);
+		pDESWrite->i1++;
+		if(pDESWrite->i1 > 1000)
+			pDESWrite->i1 = 0;
+		pDESWrite->i2--;
+		if(pDESWrite->i2 < -1000)
+			pDESWrite->i2 = 0;
+		Sleep(200);
+	}
+	return 0;
+}
+