Jump to content
The simFlight Network Forums

FSUIPC 1.0 Question


Recommended Posts

this code belong in a Visual C++ 6.0 and i think im using FSUIPC 1.0...

i got some questions to ask about some of the error messages.

//	FSUIPC.cpp: MFC user interface library for FSUIPC
//
//	Version 1.0
//
//////////////////////////////////////////////////////////////////////

/*****************************************************************************

Started:          28th November 2000

With acknowledgements to Adam Szofran (author of original FS6IPC).

******************************************************************************/

#include "stdafx.h"
#include "FSUIPC.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

/******************************************************************************
			IPC client stuff
******************************************************************************/

#define LIB_VERSION 1004	// 1.003
#define MAX_SIZE 0x7F00		// Largest data (kept below 32k to avoid
							// any possible 16-bit sign problems)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFSUIPC::CFSUIPC()
{
	this->InitializeVariables();
}

CFSUIPC::CFSUIPC(DWORD dwFSRequired)
{
	this->InitializeVariables();
	this->Open(dwFSRequired);
}

CFSUIPC::~CFSUIPC()
{
	this->Close();
}

/*
 *	Close:	Closes your connection to FSUIPC, this is automatic when the 
 *			the CFSUIPC object is destroyed.
 */
void CFSUIPC::Close()
{
	m_hWnd = 0;
	m_msg = 0;

	if (m_atom)
	{	
		GlobalDeleteAtom(m_atom);
		m_atom = 0;
	}

	if (m_pView)
	{	
		UnmapViewOfFile((LPVOID)m_pView);
		m_pView = 0;
	}

	if (m_hMap)
	{	
		CloseHandle(m_hMap);
		m_hMap = 0;
	}
}

/*
 *	Open:	Opens a connection to FSUIPC.  This should be called if you
 *			used the default constructor, otherwise this is called from 
 *			the constructor
 */
BOOL CFSUIPC::Open(DWORD dwFSReq)
{
	char szName[MAX_PATH];
	static int nTry = 0;
	BOOL fWideFS = FALSE;
	int i = 0;

	// abort if already started
	if (m_pView)
	{
		m_dwResult = FSUIPC_ERR_OPEN;
		return FALSE;
	}

	// Clear version information, so know when connected
	FSUIPC_Version = FSUIPC_FS_Version = 0;

	// Connect via FSUIPC, which is known to be FSUIPC's own
	// and isn't subject to user modificiation
	m_hWnd = FindWindowEx(NULL, NULL, "UIPCMAIN", NULL);
	if (!m_hWnd)
	{
		// If there's no UIPCMAIN, we may be using WideClient
		// which only simulates FS98
		m_hWnd = FindWindowEx(NULL, NULL, "FS98MAIN", NULL);
		fWideFS = TRUE;
		if (!m_hWnd)
		{
			m_dwResult = FSUIPC_ERR_NOFS;
			return FALSE;
		}
	}

	// register the window message
	m_msg = RegisterWindowMessage(FS6IPC_MSGNAME1);
	if (m_msg == 0)
	{
		m_dwResult = FSUIPC_ERR_REGMSG;
		return FALSE;
	}

	// create the name of our file-mapping object
	nTry++; 
	// Generate a unique string in case user closes and reopens
	wsprintf(szName, FS6IPC_MSGNAME1 ":%X:%X", GetCurrentProcessId(), nTry);

	// stuff the name into a global atom
	m_atom = GlobalAddAtom(szName);
	if (m_atom == 0)
	{
		m_dwResult = FSUIPC_ERR_ATOM;
		this->Close();
		return FALSE;
	}

	// create the file-mapping object
	m_hMap = CreateFileMapping(
				(HANDLE)0xFFFFFFFF, // use system paging file
				NULL,               // security
				PAGE_READWRITE,     // protection
				0, MAX_SIZE+256,       // size
				szName);            // name 

	if ((m_hMap == 0) || (GetLastError() == ERROR_ALREADY_EXISTS))
	{	
		m_dwResult = FSUIPC_ERR_MAP;
		this->Close();
		return FALSE;    
	}

	// get a view of the file-mapping object
	m_pView = (BYTE*)MapViewOfFile(m_hMap, FILE_MAP_WRITE, 0, 0, 0);
	if (m_pView == NULL)
	{	
		m_dwResult = FSUIPC_ERR_VIEW;
		this->Close();
		return FALSE;
	}

	// Okay, now determine FSUIPC version AND FS type
	m_pNext = m_pView;

	// Try up to 5 times with a 100mSec rest between each
	// Note that WideClient returns zeroes initially, whilst waiting
	// for the Server to get the data
	while ((i++ < 5) && ((FSUIPC_Version == 0) || (FSUIPC_FS_Version == 0)))
	{	// Read FSUIPC version
		if (!Read(0x3304, 4, &FSUIPC_Version))
		{
			this->Close();
			return FALSE;
		}

		// Read FS version and validity check pattern
		if (!Read(0x3308, 4, &FSUIPC_FS_Version))
		{	
			this->Close();
			return FALSE;
		}


		// Write our Library version number to a special read-only offset
		// This is to assist diagnosis from FSUIPC logging
		// But only do this on first try
		if ((i < 2) && !Write(0x330a, 2, &FSUIPC_Lib_Version))
		{
			this->Close();
			return FALSE;
		}

		// Actually send the requests and get the responses ("process")
		if (!Process())
		{	
			this->Close();
			return FALSE;
		}

		// Maybe running on WideClient, and need another try
	//	Sleep(100); // Give it a chance
	}

	// Only allow running on FSUIPC 1.998e or later
	// with correct check pattern 0xFADE
	if ((FSUIPC_Version < 0x19980005) || ((FSUIPC_FS_Version & 0xFFFF0000L) != 0xFADE0000))
	{	
		m_dwResult = fWideFS ? FSUIPC_ERR_RUNNING : FSUIPC_ERR_VERSION;
		this->Close();
		return FALSE;
	}

	FSUIPC_FS_Version &= 0xffff; // Isolates the FS version number
	if (dwFSReq && (dwFSReq != FSUIPC_FS_Version)) // Optional user specific FS request
	{	
		m_dwResult = FSUIPC_ERR_WRONGFS;
		this->Close();
		return FALSE;
	}

	m_dwResult = FSUIPC_ERR_OK;
	return TRUE;
}

/*
 *	Process:	Process your read and/or write requests
 */
BOOL CFSUIPC::Process()
{
	DWORD dwError;
	DWORD *pdw;
	FS6IPC_READSTATEDATA_HDR *pHdrR;
	FS6IPC_WRITESTATEDATA_HDR *pHdrW;
	int i = 0;

	if (!m_pView)
	{	
		m_dwResult = FSUIPC_ERR_NOTOPEN;
		return FALSE;
	}

	if (m_pView == m_pNext)
	{	
		m_dwResult = FSUIPC_ERR_NODATA;
		return FALSE;
	}

	ZeroMemory(m_pNext, 4); // Terminator
	m_pNext = m_pView;

	// send the request (allow up to 9 tries)
	while ((++i < 10) && !SendMessageTimeout(
			m_hWnd,       // FS6 window handle
			m_msg,        // our registered message id
			m_atom,       // wParam: name of file-mapping object
			0,            // lParam: offset of request into file-mapping obj
			SMTO_BLOCK,   // halt this thread until we get a response
			2000,			  // time out interval
			&dwError))    // return value
	//{	
	//	Sleep(100); // Allow for things to happen
	//}

	if (i >= 10) // Failed all tries?
	{	
		m_dwResult = GetLastError() == 0 ? FSUIPC_ERR_TIMEOUT : FSUIPC_ERR_SENDMSG;
		return FALSE;
	}

	if (dwError != FS6IPC_MESSAGE_SUCCESS)
	{	
		m_dwResult = FSUIPC_ERR_DATA; // FSUIPC didn't like something in the data!
		return FALSE;
	}

	// Decode and store results of Read requests
	pdw = (DWORD *) m_pView;

	while (*pdw)
	{	
		switch (*pdw)
		{	
			case FS6IPC_READSTATEDATA_ID:
				pHdrR = (FS6IPC_READSTATEDATA_HDR *) pdw;
				m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR);
				if (pHdrR->pDest && pHdrR->nBytes)
					CopyMemory(pHdrR->pDest, m_pNext, pHdrR->nBytes);
				m_pNext += pHdrR->nBytes;
				break;

			case FS6IPC_WRITESTATEDATA_ID:
				// This is a write, so there's no returned data to store
				pHdrW = (FS6IPC_WRITESTATEDATA_HDR *) pdw;
				m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW->nBytes;
				break;

			default:
				// Error! So terminate the scan
				*pdw = 0;
				break;
		}
		pdw = (DWORD *) m_pNext;
	}

	m_pNext = m_pView;
	m_dwResult = FSUIPC_ERR_OK;
	return TRUE;
}

/*
 *	Read:	Place a read request in the queue to be processed
 */
BOOL CFSUIPC::Read(DWORD dwOffset, DWORD dwSize, void *pDest)
{
	FS6IPC_READSTATEDATA_HDR *pHdr = (FS6IPC_READSTATEDATA_HDR *) m_pNext;

	// Check link is open
	if (!m_pView)
	{	
		m_dwResult = FSUIPC_ERR_NOTOPEN;
		return FALSE;
	}

	// Check have space for this request (including terminator)
	if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_READSTATEDATA_HDR))) > MAX_SIZE)
	{	
		m_dwResult = FSUIPC_ERR_SIZE;
		return FALSE;
	}

	// Initialise header for read request
	pHdr->dwId = FS6IPC_READSTATEDATA_ID;
	pHdr->dwOffset = dwOffset;
	pHdr->nBytes = dwSize;
	pHdr->pDest = (BYTE *) pDest;

	// Zero the reception area, so rubbish won't be returned
	if (dwSize) ZeroMemory(&m_pNext[sizeof(FS6IPC_READSTATEDATA_HDR)], dwSize);

	// Update the pointer ready for more data
	m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR) + dwSize;

	m_dwResult = FSUIPC_ERR_OK;
	return TRUE;
}

/*
 *	Write:	Place a write request in the queue to be processed
 */
BOOL CFSUIPC::Write(DWORD dwOffset, DWORD dwSize, void *pSrce)
{
	FS6IPC_WRITESTATEDATA_HDR *pHdr = (FS6IPC_WRITESTATEDATA_HDR *) m_pNext;

	// check link is open
	if (!m_pView)
	{	
		m_dwResult = FSUIPC_ERR_NOTOPEN;
		return FALSE;
	}

	// Check have spce for this request (including terminator)
	if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_WRITESTATEDATA_HDR))) > MAX_SIZE)
	{	
		m_dwResult = FSUIPC_ERR_SIZE;
		return FALSE;
	}

	// Initialise header for write request
	pHdr->dwId = FS6IPC_WRITESTATEDATA_ID;
	pHdr->dwOffset = dwOffset;
	pHdr->nBytes = dwSize;

	// Copy in the data to be written
	if (dwSize) CopyMemory(&m_pNext[sizeof(FS6IPC_WRITESTATEDATA_HDR)], pSrce, dwSize);

	// Update the pointer ready for more data
	m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + dwSize;

	m_dwResult = FSUIPC_ERR_OK;
	return TRUE;
}

/*
 *	InitializeVariables:	Initialize the variables that are used internally.
 */
void CFSUIPC::InitializeVariables()
{
	FSUIPC_Version = 0;
	FSUIPC_FS_Version = 0;
	FSUIPC_Lib_Version = LIB_VERSION;

	m_atom = 0;
	m_dwResult = 0;
	m_hMap = 0;
	m_hWnd = 0;
	m_msg = 0;
	m_pNext = 0;
	m_pView = 0;
}

/*
 *	ReadAndProcess:	Place a read request in the queue and then process
 *					all entries in the queue.
 */
BOOL CFSUIPC::ReadAndProcess(DWORD dwOffset, DWORD dwSize, void *pDest)
{
	if ( this->Read(dwOffset, dwSize, pDest) == FALSE)
		return FALSE;

	if (this->Process() == FALSE)
		return FALSE;

	if (this->Read(dwOffset, dwSize, pDest) == FALSE)
		return FALSE;		// /////////////////////////////////////

	return TRUE;
}

/*
 *	WriteAndProcess:	Place a write request in the queue and then process
 *						all entries in the queue
 */
BOOL CFSUIPC::WriteAndProcess(DWORD dwOffset, DWORD dwSize, void *pSrce)
{
	if ( this->Write(dwOffset, dwSize, pSrce) == FALSE)
		return FALSE;

	if (this->Process() == FALSE)
		return FALSE;

	return TRUE;
}

/*
 *	GetResultMessage:	Returns the last result message.
 */
DWORD CFSUIPC::GetResultMessage()
{
	return m_dwResult;
}

/*
 *	GetResultMessageString():	Returns the last result message returned in
 *								a user readable format.
 */
CString CFSUIPC::GetResultMessageString()
{
	char *pszErrors[] =
	{	
		"Okay",
		"Attempt to Open when already Open",
		"Cannot link to FSUIPC or WideClient",
		"Failed to Register common message with Windows",
		"Failed to create Atom for mapping filename",
		"[color=#FF0000][b]Failed to create a file mapping object[/b][/color]",
		"Failed to open a view to the file map",
		"Incorrect version of FSUIPC, or not FSUIPC",
		"Flight Simulator is not version requested",
		"Call cannot execute: Link not Open",
		"Call cannot execute: No requests accumulated",
		"IPC timed out all retries",
		"IPC sendmessage failed all retries",
		"[b][color=#FF4000]IPC request contains bad data[/color][/b]",
		"Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC",
		"Read or Write request cannot be added, memory for Process is full",
	};

	if (m_dwResult > sizeof(pszErrors) / sizeof( pszErrors[0] ) -1)
		return CString("Unknown error");
	else
		return CString(pszErrors[m_dwResult]);
}

DWORD CFSUIPC::GetFSVersion()
{
	return FSUIPC_FS_Version;
}

DWORD CFSUIPC::GetVersion()
{
	return FSUIPC_Version;
}

"Failed to create a file mapping object",

"IPC request contains bad data",

what does the two errors mean?

Link to comment
Share on other sites

Hi,

Version 1.0 is super old and is not supported. You'll want to go here and get the latest:

http://www.schiratti.com/dowson.html

this version of FSUIPC is being used by my school project and i dont know whether i can change it to FSUIPC 4.0 or not and dont know whether my Visual C++ program code can handle FSUIPC 4.0 if can use 4.0 then i may have to change alot of thing inside my program.... i shall ask my seniors whether can change to FSUIPC 4.0 when i back to school on monday

btw another thing... when im running my program i keep having that two errors. what does the two error means?

Link to comment
Share on other sites

this version of FSUIPC is being used by my school project and i dont know whether i can change it to FSUIPC 4.0 or not

You do NOT use FSUIPC4 for FS2004 or before, only for FSX. The current version for FS2004 and before is 3.81. no other version is supported from versions of FS before FSX.

If you are using FSX you must use FSUIPC4 as there is no way FSUIPC3 (or 1) will work on FSX.

btw another thing... when im running my program i keep having that two errors. what does the two error means?
They mean exactly what they say, of course. They are in English. And you showed the code where they are set. Look:

// create the file-mapping object
   m_hMap = CreateFileMapping(
            (HANDLE)0xFFFFFFFF, // use system paging file
            NULL,               // security
            PAGE_READWRITE,     // protection
            0, MAX_SIZE+256,       // size
            szName);            // name

   if ((m_hMap == 0) || (GetLastError() == ERROR_ALREADY_EXISTS))
   {   
      m_dwResult = FSUIPC_ERR_MAP;
      this->Close();
      return FALSE;   
   }

The "Failed to create a file mapping object" message is error FSUIPC_ERR_MAP, so the CreateFileMapping call to Windows failed, and the "IPC request contains bad data" message is the error FSUIPC_ERR_DATA from this code:

 if (dwError != FS6IPC_MESSAGE_SUCCESS)
   {   
      m_dwResult = FSUIPC_ERR_DATA; // FSUIPC didn't like something in the data!
      return FALSE;
   }

You should have easily worked all that out yourself.

If you got the second error the most likely problem on the first is that you've tried to Create the same file mapping twice, so got "ALREADY EXISTS" returned.

Pete

Link to comment
Share on other sites

we using FSX as our database but we using FSUIPC 1.0 for it and we using Project Magenta too..

FSUIPC 1 cannot load at all in FSX and has no chance of working. In fact I don't think it'll work in anything but FS98 and FS2000. You must install FSUIPC4 for use with FSX, you have no alternative at all.

I'd like to know where you got FSUIPC 1 from in the first place. It hasn't been available anywhere for many years!

I suspect that you are in fact using FSUIPC4 after all and just don't know much about what you are doing. Take a look at the options screen, or in the Log, or just right-click on the DLL and check Properties-Version.

Certainly Project magenta will not run with FSUIPC 1 nor on FSX without FSUIPC4.

Pete

Link to comment
Share on other sites

FSUIPC 1 cannot load at all in FSX and has no chance of working. In fact I don't think it'll work in anything but FS98 and FS2000. You must install FSUIPC4 for use with FSX, you have no alternative at all.

I'd like to know where you got FSUIPC 1 from in the first place. It hasn't been available anywhere for many years!

I suspect that you are in fact using FSUIPC4 after all and just don't know much about what you are doing. Take a look at the options screen, or in the Log, or just right-click on the DLL and check Properties-Version.

Certainly Project magenta will not run with FSUIPC 1 nor on FSX without FSUIPC4.

Pete

ok i will go and check it out on monday thank Pete :D

btw im 3rd batch of students doing this project so i dont know how they got the FSUIPC 1.0... if i have to use FSUIPC4 then do i need to file a source file and header file that are FSUIPC4 for Visual C++ too?

Link to comment
Share on other sites

if i have to use FSUIPC4 then do i need to file a source file and header file that are FSUIPC4 for Visual C++ too?

The files in the SDK cover FSUIPC3 and 4, and you don't actually need any source file for C/C++ as I supply a ready-built library for the interface. The source for the library is inside the SDK in a separate ZIP.

Pete

Link to comment
Share on other sites

The files in the SDK cover FSUIPC3 and 4, and you don't actually need any source file for C/C++ as I supply a ready-built library for the interface. The source for the library is inside the SDK in a separate ZIP.

Pete

thanks alot Pete :D

if can i will try out on monday.

Link to comment
Share on other sites

oone more question... if imu using FSUIPC 1.0 how can i update to FSUIPC 4.0 without changing lots of stuff like uninstalling and setting up all the parameter.

If you are running FSX and Project Magenta you cannot be using FSUIPC 1, so the question does not arise. And there's no "uninstalling" to do in any case -- simply deleting the DLL does it. Please do look at the supplied documentation where it tells you all you need to know!

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.