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?