#pragma once

class   CEZGemPlusCtrl;
typedef CEZGemPlusCtrl*	EZGEMCLASS;

typedef void(*pNativeCallBackEvent)(void*, short, long);	// Handle, EventID, Param
typedef void(*pNativeCallBackMsg)(void*, long);			// Handle, SECS MsgId

enum 
{
	TRNASFERSTATE_NOSTATE = 0,
	TRANSFERSTATE_OUTOFSERVICE = 1,  
	TRANSFERSTATE_INSERVICE = 2,
	TRANSFERSTATE_READYTOLOAD = 3, 
	TRANSFERSTATE_READYTOUNLOAD = 4, 
	TRANSFERSTATE_TRANSFERBLOCKED = 5,

	DOORSTATE_CLOSED = 0,
	DOORSTATE_OPENED = 1,

	ACCESSMODE_MANUAL= 0,
	ACCESSMODE_AUTO	 = 1,

	CARRIERACCESS_NOTACCESSED = 0,
	CARRIERACCESS_INACCESS = 1,
	CARRIERACCESS_COMPLETED = 2,
	CARRIERACCESS_STOPPED = 3,

	CARRIERIDREAD_OK	=	0,
	CARRIERIDREAD_FAIL	=	1,

	CARRIERIDSTATE_NOTREAD = 0,
	CARRIERIDSTATE_WAITFORHOST = 1,
	CARRIERIDSTATE_VERIFYOK = 2,
	CARRIERIDSTATE_VERIFYFAIL = 3,

	SLOTMAPREAD_OK	=	0,
	SLOTMAPREAD_FAIL	=	1,

	SLOTMAPSTATE_NOTREAD = 0,
	SLOTMAPSTATE_WAITFORHOST = 1,
	SLOTMAPSTATE_VERIFYOK = 2,
	SLOTMAPSTATE_VERIFYFAIL = 3,

	SLOTMAP_MAXSLOT = 25,
};

enum
{
	// Error Codes
	RESULT_OK = 0,
	LICENSE_PROBLEM = -1,

	CONFIG_FILE_NOTFOUND = -101,
	FILE_NOT_FOUND = -102,
	FILE_IO_FAILURE = -103,
	FILE_CREATION_ERROR = -104,

	ID_NOT_EXIST = -200,
	NO_ITEM = -201,
	TYPE_MISMATCH = -202,
	SIZE_MISMATCH = -203,
	ITEM_I1_OVERFLOW = -204,
	ITEM_I2_OVERFLOW = -205,
	ITEM_I4_OVERFLOW = -206,
	ITEM_U1_OVERFLOW = -207,
	ITEM_U2_OVERFLOW = -208,
	ITEM_U4_OVERFLOW = -209,
	INVALID_MSGID = -210,
	INVALID_STREAM = -211,
	INVALID_FUNCTION = -212,
	DUPLICATE_SYSTEMBYTE = -213,
	UNDEFINED_STRUCTURE = -214,
	OUT_OF_RANGE = -215,

	NOT_CONNECTED = -301,
	LOW_LEVEL_ERROR = -302,
	NOT_SUPPORTED = -303,
	ALREADY_CONNECTED = -304,
	ALREADY_STARTED = -305,
	THREAD_NULL = -306,
	CREATE_EVENT_FAIL = -307,
	SERIAL_OPEN_FAIL = -308,
	SERIAL_SETUP_FAIL = -309,
	TIMER_CREATE_FAIL = -310,
	NOT_STARTED_YET = -311,
	ALREADY_DEFINED = -312,
	NOT_ESTABLISHED = -313,
	NOT_ONLINE_STATE = -314,
	ITEMS_NOT_READY = -315,
	
	SOCKET_INUSE = -501,
	SOCKET_STARTERROR = -502,
	SOCKET_INVALID = -503,
	SOCKET_WINDOWERROR = -504,
	SOCKET_LOCALNAME = -505,
	SOCKET_CONNECTERROR = -506,
	SOCKET_SETEVENT = -507,
	SOCKET_RESOLVE = -508,

	ERROR_GEM300_INVALID_PORTID = -901,
	ERROR_GEM300_INVALID_STATE = -902,
	ERROR_GEM300_INVALID_MODE = -903,
	ERROR_GEM300_INVALID_DATA = -904,
	ERROR_GEM300_NO_DATA		= -905,
	ERROR_GEM300_ALREADY_EXIST = -906,
	ERROR_GEM300_INVALID_CARRIER = -907,
	ERROR_GEM300_INVALID_SLOT = -908,
	ERROR_GEM300_INVALID_RECIPE = -909,
	ERROR_GEM300_INVALID_PRJOB = -910,
	ERROR_GEM300_INVALID_CJOB = -911,
	ERROR_GEM300_INVALID_LOCATION = -912,
	ERROR_GEM300_INVALID_OBJTYPE = -913,
	ERROR_GEM300_INVALID_OBJID = -914,
	ERROR_GEM300_INVALID_ATTR = -915,

	// Event Codes
	DLL_EVENT_CONNECTED = 1,
	DLL_EVENT_DISCONNECTED = 2,
	DLL_EVENT_MSGRECEIVED = 3,
	DLL_EVENT_OTHEREVENT = 9,

	EVENT_KEY_EVALUATION_MODE_START = 10,
	EVENT_KEY_RUNTIME_MODE_START = 11,
	EVENT_LINKTEST_REQUEST_IN = 101,
	EVENT_LINKTEST_REQUEST_OUT = 102,
	EVENT_LINKTEST_RESPONSE_OUT = 104,
	EVENT_TRANSACTION_TIMEOUT = 202,
	EVENT_UNRECOGNIZED_DEVICEID = 203,
	EVENT_UNRECOGNIZED_STREAM = 204,
	EVENT_LINKTEST_RESPONSE_IN = 103,
	EVENT_UNRECOGNIZED_FUNCTION = 205,
	EVENT_INVALID_DATA = 206,
	EVENT_DISCARD_MSG = 207,
	EVENT_ABORTMSG_IN = 208,

	EVENT_TIMEOUT_T1 = 301,
	EVENT_TIMEOUT_T2 = 302,
	EVENT_TIMEOUT_T3 = 303,
	EVENT_TIMEOUT_T4 = 304,
	EVENT_TIMEOUT_T5 = 305,
	EVENT_TIMEOUT_T6 = 306,
	EVENT_TIMEOUT_T7 = 307,
	EVENT_TIMEOUT_T8 = 308,
	EVENT_RETRY_LIMIT = 309,
	EVENT_MSG_IN = 401,
	EVENT_MSG_OUT = 402,
	EVENT_ENABLED = 501,
	EVENT_DATAID_CHANGED = 511,

	EVENT_GEMDLL_CONTROL_HOSTOFFLINE	= 1001,
	EVENT_GEMDLL_CONTROL_ONLINE_LOCAL	= 1002,
	EVENT_GEMDLL_CONTROL_ONLINE_REMOTE	= 1003,
	EVENT_GEMDLL_COMM_ESTABLISHED		= 1010,
	EVENT_GEMDLL_HOST_SENT_NEWECV		= 1015,
	EVENT_GEMDLL_TRACE_TIMESET			= 1020,
	EVENT_GEMDLL_HOST_COMMAND			= 1030,
	EVENT_GEMDLL_SPOOL_UPDATED			= 1040,
	EVENT_GEMDLL_SPOOL_FULL				= 1041,
	EVENT_GEMDLL_TERMMSG				= 1050,
	EVENT_GEMDLL_TRANSACTION			= 1060,
	EVENT_GEMDLL_IN_DEADBAND			= 1070,

	///// GEM300 EVENT //////
	EVENT_GEMDLL_CMS_TRANSFER_STATE_CHANGE		= 1301,
	EVENT_GEMDLL_CMS_RESERVATION_STATE_CHANGE	= 1311,
	EVENT_GEMDLL_CMS_CARRIERACCESS_STATE_CHANGE = 1321,
	EVENT_GEMDLL_CMS_ASSOCIATION_STATE_CHANGE	= 1331,

	EVENT_GEMDLL_CMS_CARRIERID_STATE_CHANGE		= 1401,
	EVENT_GEMDLL_CMS_CARRIERID_VERIFY_OK		= 1411,
	EVENT_GEMDLL_CMS_CARRIERID_VERIFY_FAILED	= 1412,
	EVENT_GEMDLL_CMS_CARRIER_DELETED		= 1421,
	EVENT_GEMDLL_CMS_CARRIER_RECREATED		= 1422,


	EVENT_GEMDLL_CMS_SLOTMAP_STATE_CHANGE		= 1501,
	EVENT_GEMDLL_CMS_SLOTMAP_VERIFY_OK			= 1511,
	EVENT_GEMDLL_CMS_SLOTMAP_VERIFY_FAILED		= 1512,

	EVENT_GEMDLL_CMS_HOST_PROCEED_WITH_CARRIER	= 1601,	//	<<--- HOST : S3F17, ProceedWithCarrier
	EVENT_GEMDLL_CMS_HOST_CANCEL_CARRIER		= 1602,	//	<<--- HOST : S3F17, CancelCarrier
	EVENT_GEMDLL_CMS_HOST_CANCEL_CARRIER_AT_PORT= 1603,	//	<<--- HOST : S3F17, CancelCarrierAtPort
	EVENT_GEMDLL_CMS_HOST_BIND					= 1604, //  <<--- HOST : S3F17, Bind
	EVENT_GEMDLL_CMS_HOST_CANCELBIND			= 1605, //  <<--- HOST : S3F17, CancelBind
	EVENT_GEMDLL_CMS_HOST_RESERVEATPORT			= 1606, //  <<--- HOST : S3F17, ReserveAtPort
	EVENT_GEMDLL_CMS_HOST_CANCEL_RESERVEATPORT	= 1607,	//  <<--- HOST : S3F17, CancelReservationAtPort
	EVENT_GEMDLL_CMS_HOST_CANCEL_ALLCARRIEROUT	= 1608,	//  <<--- HOST : S3F17, CancelAllCarrierOut
	EVENT_GEMDLL_CMS_HOST_CANCEL_CARRIER_NOTIFICATION = 1609, //  <<--- HOST : S3F17, CancelCarrierNotification
	EVENT_GEMDLL_CMS_HOST_CANCEL_CARRIER_OUT	= 1610, //  <<--- HOST : S3F17, CancelCarrierOut
	EVENT_GEMDLL_CMS_HOST_CARRIER_IN			= 1611, //  <<--- HOST : S3F17, CarrierIn
	EVENT_GEMDLL_CMS_HOST_CARRIER_NOTIFICATION  = 1612, //  <<--- HOST : S3F17, CarrierNotification
	EVENT_GEMDLL_CMS_HOST_CARRIER_OUT			= 1613, //  <<--- HOST : S3F17, CarrierOut
	EVENT_GEMDLL_CMS_HOST_CARRIER_RELEASE		= 1614, //  <<--- HOST : S3F17, CarrierRelease
	EVENT_GEMDLL_CMS_HOST_CARRIER_RECREATE		= 1615, //  <<--- HOST : S3F17, CarrierReCreate

	EVENT_GEMDLL_CMS_HOST_SET_ACCESSMODE_CHANGE = 1701,	//	<<--- HOST : S3F27, CHANGEACCESS MODE : MANUAL
	EVENT_GEMDLL_CMS_HOST_SET_PORTSERVICE_CHANGE= 1702, //  <<--- HOST : S3F25, CHANGESERVICESTATUS (PORTID, IN_OUT)

	EVENT_GEMDLL_PJM_HOST_SET_PRJOB_CREATE		= 1801,	//  <<--- HOST : S16F11/15, PRJob(Multi)Create
	EVENT_GEMDLL_PJM_HOST_SET_PRJOB_DEQUE		= 1802, //  <<--- HOST : S16F17, PRJobSetDeque
	EVENT_GEMDLL_PJM_HOST_SET_PRJOB_RECIPE_VAL	= 1803, //  <<--- HOST : S16F23, PRJobSetRevipeVariable
	EVENT_GEMDLL_PJM_HOST_SET_PRJOB_STARTMETHOD	= 1804,	//	<<--- HOST : S16F25, PRJobSetStartMethod
	EVENT_GEMDLL_PJM_HOST_SET_PRJOB_COMMAND		= 1805,	//  <<--- HOST : S16F5,  PrJobCommandRequest
	EVENT_GEMDLL_PJM_EQ_CREATE_PRJOB			= 1809,

	EVENT_GEMDLL_CJM_HOST_SET_CONTROLJOB_CREATE	= 1901,	//	<<--- HOST : S14F9,  CreateObjectRequest (CJ)
	EVENT_GEMDLL_CJM_HOST_SET_CONTROLJOB_DELETE = 1902,	//  <<--- HOST : S14F11, DeleteObjectRequest (CJ)
	EVENT_GEMDLL_CJM_HOST_SET_CTRLJOB_COMMAND	= 1905,	//  <<--- HOST : S16F27, CtrlJobCommand
	EVENT_GEMDLL_CJM_EQ_CREATE_CONTROLJOB		= 1909,

	EVENT_GEMDLL_STS_HOST_SET_SUBST_CREATE		= 2001, //  <<--- HOST : S14F9,  CreateObjectRequest (Substrate)
	EVENT_GEMDLL_STS_HOST_SET_SUBST_DELETE		= 2002, //  <<--- HOST : S14F11, DeleteObjectRequest (Substrate)
	EVENT_GEMDLL_STS_HOST_SET_PROCEED_SUBST		= 2003, //  <<--- HOST : S14F19, GenericServiceRequest
	EVENT_GEMDLL_STS_HOST_SET_CANCEL_SUBST		= 2004, //  <<--- HOST : S14F19, GenericServiceRequest

	EVENT_GEMDLL_EXPIRED				= 9999,
};

extern "C"
{
	__declspec(dllimport)  EZGEMCLASS  EZGEM_CreateClass();
	__declspec(dllimport)  void  EZGEM_DeleteClass(EZGEMCLASS);

	__declspec(dllimport)  void   EZGEM_SetEventHandler(EZGEMCLASS pGem, LPVOID lpHandle, pNativeCallBackEvent cb);
	__declspec(dllimport)  void   EZGEM_SetMsgHandler(EZGEMCLASS pGem, LPVOID lpHandle, pNativeCallBackMsg cb);
	__declspec(dllimport)  short  EZGEM_Start(EZGEMCLASS pGem);
	__declspec(dllimport)  short  EZGEM_Stop(EZGEMCLASS pGem);
	__declspec(dllimport)  long   EZGEM_CreateMsg(EZGEMCLASS pGem, short nStream, short nFunction, short nWbit);
	__declspec(dllimport)  long   EZGEM_CreateReplyMsg(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_SendMsg(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_SendMsgEx(EZGEMCLASS pGem, long lMsgId, long nTransactionID);
	__declspec(dllimport)  short  EZGEM_CloseMsg(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_GetMsgInfo(EZGEMCLASS pGem, long lMsgId, short *pnStream, short * pnFunction, short * pnWbit, long * plLength);

	__declspec(dllimport)  short  EZGEM_GetDeviceID(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetDeviceID(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetPassiveMode(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetPassiveMode(EZGEMCLASS pGem, short bNewValue);
	__declspec(dllimport)  BSTR   EZGEM_GetIP(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetIP(EZGEMCLASS pGem, LPCTSTR lpszNewValue);
	__declspec(dllimport)  short  EZGEM_GetPort(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetPort(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetT3(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetT3(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetT5(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetT5(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetT6(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetT6(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetT7(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetT7(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetT8(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetT8(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetRetry(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetRetry(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetLinkTestInterval(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetLinkTestInterval(EZGEMCLASS pGem, short nNewValue);
	__declspec(dllimport)  short  EZGEM_GetRuntimeState(EZGEMCLASS pGem);

	__declspec(dllimport)  short  EZGEM_OpenListItem(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_CloseListItem(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_AddBinaryItem(EZGEMCLASS pGem, long lMsgId, short * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddByteItem(EZGEMCLASS pGem, long lMsgId, BYTE * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddAsciiItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR pszValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddBoolItem(EZGEMCLASS pGem, long lMsgId, short * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddI1Item(EZGEMCLASS pGem, long lMsgId, short * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddI2Item(EZGEMCLASS pGem, long lMsgId, short * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddI4Item(EZGEMCLASS pGem, long lMsgId, long * plValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddI8Item(EZGEMCLASS pGem, long lMsgId, long * plValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddI8ItemI64(EZGEMCLASS pGem, long lMsgId, LONGLONG * plValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddU1Item(EZGEMCLASS pGem, long lMsgId, short * pValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddU2Item(EZGEMCLASS pGem, long lMsgId, long * plValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddU4Item(EZGEMCLASS pGem, long lMsgId, double * prValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddU8Item(EZGEMCLASS pGem, long lMsgId, double * prValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddU8ItemU64(EZGEMCLASS pGem, long lMsgId, ULONGLONG * prValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddF4Item(EZGEMCLASS pGem, long lMsgId, float * prValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddF8Item(EZGEMCLASS pGem, long lMsgId, double * prValue, long lCount);
	__declspec(dllimport)  short  EZGEM_AddJ8Item(EZGEMCLASS pGem, long lMsgId, LPCTSTR pszValue, long lCount);
	__declspec(dllimport)  short  EZGEM_GetMsgInfo(EZGEMCLASS pGem, long lMsgId, short * pnStream, short * pnFunction, short * pnWbit, long * plLength);
	__declspec(dllimport)  short  EZGEM_GetListItemOpen(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_GetListItemClose(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_GetAsciiItem(EZGEMCLASS pGem, long lMsgId, BSTR * pszValue);
	__declspec(dllimport)  long   EZGEM_GetJ8Item(EZGEMCLASS pGem, long lMsgId, BSTR * pszValue);
	__declspec(dllimport)  long   EZGEM_GetBinaryItem(EZGEMCLASS pGem, long lMsgId, short * pnValue);
	__declspec(dllimport)  long   EZGEM_GetByteItem(EZGEMCLASS pGem, long lMsgId, BYTE * pnValue);
	__declspec(dllimport)  long   EZGEM_GetBoolItem(EZGEMCLASS pGem, long lMsgId, short * pnValue);
	__declspec(dllimport)  long   EZGEM_GetI1Item(EZGEMCLASS pGem, long lMsgId, short * pnValue);
	__declspec(dllimport)  long   EZGEM_GetI2Item(EZGEMCLASS pGem, long lMsgId, short * pnValue);
	__declspec(dllimport)  long   EZGEM_GetI4Item(EZGEMCLASS pGem, long lMsgId, long * plValue);
	__declspec(dllimport)  long   EZGEM_GetI8Item(EZGEMCLASS pGem, long lMsgId, long * plValue);
	__declspec(dllimport)  long   EZGEM_GetI8ItemI64(EZGEMCLASS pGem, long lMsgId, LONGLONG * plValue);
	__declspec(dllimport)  long   EZGEM_GetU1Item(EZGEMCLASS pGem, long lMsgId, short * pnValue);
	__declspec(dllimport)  long   EZGEM_GetU2Item(EZGEMCLASS pGem, long lMsgId, long * plValue);
	__declspec(dllimport)  long   EZGEM_GetU4Item(EZGEMCLASS pGem, long lMsgId, double * prValue);
	__declspec(dllimport)  long   EZGEM_GetU8Item(EZGEMCLASS pGem, long lMsgId, double * prValue);
	__declspec(dllimport)  long   EZGEM_GetU8ItemU64(EZGEMCLASS pGem, long lMsgId, ULONGLONG * prValue);
	__declspec(dllimport)  long   EZGEM_GetF4Item(EZGEMCLASS pGem, long lMsgId, float * prValue);
	__declspec(dllimport)  long   EZGEM_GetF8Item(EZGEMCLASS pGem, long lMsgId, double * prValue);
	__declspec(dllimport)  void   EZGEM_SetLogFile(EZGEMCLASS pGem, LPCTSTR strFileName, short bLogSecsII);
	__declspec(dllimport)  long   EZGEM_GetCurLogFile(EZGEMCLASS pGem, BSTR *psCurLogFile);
	__declspec(dllimport)  short  EZGEM_GetNextItemFormat(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_GetSubItemFormat(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_GetNextItemCount(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_GetSubItemCount(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  short  EZGEM_AbortMsg(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  void   EZGEM_SetLogRetention(EZGEMCLASS pGem, short nDays);
	__declspec(dllimport)  short  EZGEM_GetLogRetention(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetFormatCheck(EZGEMCLASS pGem, short bEnabled);
	__declspec(dllimport)  short  EZGEM_GetFormatCheck(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SetFormatFile(EZGEMCLASS pGem, LPCTSTR lpszFormatFile);
	__declspec(dllimport)  long   EZGEM_AddFileBinaryItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR szFile);
	__declspec(dllimport)  long   EZGEM_GetFileBinaryItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR szFile);
	__declspec(dllimport)  long   EZGEM_GetMsgHead(EZGEMCLASS pGem, long lMsgId, UCHAR *pnByteBuff);
	__declspec(dllimport)  long   EZGEM_GetMsgBody(EZGEMCLASS pGem, long lMsgId, UCHAR *pnByteBuff, long lSize);
	__declspec(dllimport)  void   EZGEM_EnableErrorMessage(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_DisableErrorMessage(EZGEMCLASS pGem);
	__declspec(dllimport)  short  EZGEM_AddListItem(EZGEMCLASS pGem, long lMsgId, long lCount);
	__declspec(dllimport)  long   EZGEM_GetListItem(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  void   EZGEM_SetConfigFile(EZGEMCLASS pGem, LPCTSTR strConfigFile);
	__declspec(dllimport)  void   EZGEM_SaveConfigFile(EZGEMCLASS pGem, LPCTSTR strConfigFile);
	__declspec(dllimport)  short  EZGEM_SeparateLog(EZGEMCLASS pGem, LPCTSTR szLogFileName, short nStream, short nFunction);
	__declspec(dllimport)  void   EZGEM_SetMaxLogFileSize(EZGEMCLASS pGem, short nMegaByte);
	__declspec(dllimport)  short  EZGEM_SetLogDelTime(EZGEMCLASS pGem, long nDelTime);
	__declspec(dllimport)  long   EZGEM_SetMsgHead(EZGEMCLASS pGem, long lMsgId, UCHAR *pnBuff);
	__declspec(dllimport)  long   EZGEM_SetMsgBody(EZGEMCLASS pGem, long lMsgId, UCHAR *pnBuff, long lSize);
	__declspec(dllimport)  long   EZGEM_AddArrayItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR pszType, long nDataCount, LPCTSTR pszData);
	__declspec(dllimport)  long   EZGEM_GetArrayItem(EZGEMCLASS pGem, long lMsgId, BSTR * pszValue);
	__declspec(dllimport)  void   EZGEM_EnableLog(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_DisableLog(EZGEMCLASS pGem);
	__declspec(dllimport)  void   EZGEM_SkipLog(EZGEMCLASS pGem, short nStream, short nFunction);
	__declspec(dllimport)  void   EZGEM_SkipLogReset(EZGEMCLASS pGem, short nStream, short nFunction);
	__declspec(dllimport)  void   EZGEM_WriteUserLog(EZGEMCLASS pGem, LPCTSTR pszLog);
	__declspec(dllimport)  long   EZGEM_GetNextEvent(EZGEMCLASS pGem, short  *pnEventID, long  *plParam);
	__declspec(dllimport)  long   EZGEM_GetNextMsg(EZGEMCLASS pGem, long  *plMsgId);
	__declspec(dllimport)  short  EZGEM_GetMsgQueSize(EZGEMCLASS pGem);
	__declspec(dllimport)  long   EZGEM_GetSysByte(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_GetSysByteEx(EZGEMCLASS pGem, long nTransactionID);
	__declspec(dllimport)  long   EZGEM_GetItem(EZGEMCLASS pGem, long lMsgId, BSTR *pstrValue);
	__declspec(dllimport)  long   EZGEM_SaveMsgToFile(EZGEMCLASS pGem, long lMsgId, LPCTSTR sFile);
	__declspec(dllimport)  long   EZGEM_SendMsgFromFile(EZGEMCLASS pGem, LPCTSTR sFile);
	__declspec(dllimport)  long   EZGEM_GetListChildItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR sDelimiter,  BSTR *pszValue, long *plLength);
	__declspec(dllimport)  long   EZGEM_GetNameValueListItem(EZGEMCLASS pGem, long lMsgId, LPCTSTR sDelimiter, BSTR *pszNameList, BSTR *pszValueList, long *plLength);
	__declspec(dllimport)  long   EZGEM_SendS9F3(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_SendS9F5(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_SendS9F7(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long   EZGEM_SendS9F11(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  void   EZGEM_GetVersionInfo(EZGEMCLASS pGem, BSTR *psVersionInfo);
	__declspec(dllimport)  long   EZGEM_GetItemInfo(EZGEMCLASS pGem, long lMsgId, LPCTSTR sPos, short *pnFormat, long *plCount);
	__declspec(dllimport)  long   EZGEM_GetItemValue(EZGEMCLASS pGem, long lMsgId, LPCTSTR sPos, BSTR *psValue);
	__declspec(dllimport)  long   EZGEM_SetOption(EZGEMCLASS pGem, LPCTSTR sOptionName, int nOptionVal);
	//--------------------------------- END OF EZNET FUNCTION ------------------------------------------------------------
	__declspec(dllimport)  void  EZGEM_SetCommRequestTime(EZGEMCLASS pGem, short nTimerCR);
	__declspec(dllimport)  short EZGEM_GetCommRequestTime(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_SetModelName(EZGEMCLASS pGem, const char *lpszModelName);
	__declspec(dllimport)  void  EZGEM_SetSoftRev(EZGEMCLASS pGem, const char *lpszSoftRev);
	__declspec(dllimport)  void  EZGEM_GoOffline(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_GoOnlineLocal(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_GoOnlineRemote(EZGEMCLASS pGem);
	__declspec(dllimport)  long  EZGEM_AddCEID(EZGEMCLASS pGem, long CEID, const char *pszName, const char *pszDescription);
	__declspec(dllimport)  long  EZGEM_AddSVID(EZGEMCLASS pGem, long SVID, const char *pszName, const char *pszFormat, const char *pszUnit);
	__declspec(dllimport)  long  EZGEM_AddDVID(EZGEMCLASS pGem, long DVID, const char *pszName, const char *pszFormat);
	__declspec(dllimport)  long  EZGEM_AddALID(EZGEMCLASS pGem, long ALID, const char *pszName, const char *pszALCD);
	__declspec(dllimport)  long  EZGEM_AddECID(EZGEMCLASS pGem, long ECID, const char *pszName, const char *pszUnit, const char *pszFormat);
	__declspec(dllimport)  long  EZGEM_AddRemoteCommand(EZGEMCLASS pGem, const char *pszCommand);
	__declspec(dllimport)  short EZGEM_GetRemoteCommand(EZGEMCLASS pGem, long lMsgId, BSTR  *pstrCommandName);
	__declspec(dllimport)  short EZGEM_GetRemoteCommandParam(EZGEMCLASS pGem, long lMsgId, short nIndex, BSTR  *pstrName, BSTR  *pstrValue, short *pnFormat);
	__declspec(dllimport)  short EZGEM_ReplyRemoteCommand(EZGEMCLASS pGem, long lMsgId, short HCACK);
	__declspec(dllimport)  short EZGEM_SendEventReport(EZGEMCLASS pGem, long CEID);
	__declspec(dllimport)  short EZGEM_SendEventReportEx(EZGEMCLASS pGem, long CEID, long nTransactionID);
	__declspec(dllimport)  short EZGEM_SendAlarmReport(EZGEMCLASS pGem, long ALID, short ALCD);
	__declspec(dllimport)  short EZGEM_SendAlarmReportEx(EZGEMCLASS pGem, long ALID, short ALCD, short nMode);
	__declspec(dllimport)  long  EZGEM_DisableAutoReply(EZGEMCLASS pGem, short nStream, short nFunction);
	__declspec(dllimport)  long  EZGEM_EnableAutoReply(EZGEMCLASS pGem, short nStream, short nFunction);
	__declspec(dllimport)  long  EZGEM_SetSVIDValue(EZGEMCLASS pGem, long SVID, const char *pszValue);
	__declspec(dllimport)  long  EZGEM_SetVIDValue(EZGEMCLASS pGem, long VID, const char *pszValue);
	__declspec(dllimport)  short EZGEM_GetSVIDValue(EZGEMCLASS pGem, long SVID, BSTR  *pstrCurrentValue);
	__declspec(dllimport)  long  EZGEM_GetSVID(EZGEMCLASS pGem, long SVID, short  *pnFormat, BSTR  *pstrName);
	__declspec(dllimport)  short EZGEM_GetHostSetECID(EZGEMCLASS pGem, long lMsgId, long *lpECID, BSTR *pstrNewValue);
	__declspec(dllimport)  short EZGEM_SetECValue(EZGEMCLASS pGem, long ECID, const char *pszValue);
	__declspec(dllimport)  long  EZGEM_GetECValue(EZGEMCLASS pGem, long ECID, BSTR  *pstrValue);
	__declspec(dllimport)  short EZGEM_SetECRange(EZGEMCLASS pGem, long ECID, const char *pszMinValue, const char *pszMaxValue);
	__declspec(dllimport)  short EZGEM_ReplyHostSetECID(EZGEMCLASS pGem, long lMsgId, short EAC);
	__declspec(dllimport)  void  EZGEM_EnableSpooling(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_DisableSpooling(EZGEMCLASS pGem);
	__declspec(dllimport)  long  EZGEM_GetSpoolCount(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_SetMaxSpoolCount(EZGEMCLASS pGem, UINT nMaxSpoolCount);
	__declspec(dllimport)  long  EZGEM_GetMaxSpoolCount(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_SetMaxSpoolTransmitCount(EZGEMCLASS pGem, UINT nMaxSpoolTransmit);
	__declspec(dllimport)  long  EZGEM_GetMaxSpoolTransmitCount(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_EnableSpoolOverwrite(EZGEMCLASS pGem);
	__declspec(dllimport)  void  EZGEM_DisableSpoolOverwrite(EZGEMCLASS pGem);
	__declspec(dllimport)  long  EZGEM_GetTerminalMsg(EZGEMCLASS pGem, long lMsgId, short *pnTID, BSTR  *pstrMsg);
	__declspec(dllimport)  void  EZGEM_SetReportFilePath(EZGEMCLASS pGem, const char *pszFilePath);
	__declspec(dllimport)  long  EZGEM_AddStatusValueToMsg(EZGEMCLASS pGem, long lMsgId, long SVID);
	__declspec(dllimport)  long  EZGEM_SetTimeFormat(EZGEMCLASS pGem, short nTimeFormat);
	__declspec(dllimport)  short EZGEM_SetFormatCode(EZGEMCLASS pGem, const char *szItemName, const char *szFormatCode);
	__declspec(dllimport)  void  EZGEM_GetSpoolTime(EZGEMCLASS pGem, BSTR  *pstrStartTime, BSTR  *pstrFullTime);
	__declspec(dllimport)  long  EZGEM_GetAlarmInfo(EZGEMCLASS pGem, long ALID, short  *pnALCD, BSTR  *pstrText);
	__declspec(dllimport)  BSTR  EZGEM_GetAlarmText(EZGEMCLASS pGem, long ALID);
	__declspec(dllimport)  short EZGEM_GetAlarmCode(EZGEMCLASS pGem, long ALID);
	__declspec(dllimport)  long  EZGEM_GetAlarmState(EZGEMCLASS pGem, long ALID);
	__declspec(dllimport)  void  EZGEM_SetRemoteCommandErrorCode(EZGEMCLASS pGem, long lMsgId, LPCTSTR szCommand, short nParamIndex, short nErrorCode);
	__declspec(dllimport)  long  EZGEM_ResetMsgReceived(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport)  long  EZGEM_WriteEZGemStatus(EZGEMCLASS pGem);
	__declspec(dllimport)  long  EZGEM_GetReport(EZGEMCLASS pGem, long RPTID, long *plSVID);
	__declspec(dllimport)  long  EZGEM_GetEventReport(EZGEMCLASS pGem, long CEID, long *plRPTID);
	__declspec(dllimport)  long  EZGEM_GetTraceInfo(EZGEMCLASS pGem, long TRID, long *plSampleCount, long *plVidCount, BSTR *pstrVidList, BSTR *pstrPeriod);
	//------------------------------------------------------------------------------------------
	// 	GEM300 API
	__declspec(dllimport) long EZGEM_Set300IniFile(EZGEMCLASS pGem, LPCTSTR szFileName);
	//  CMS
	__declspec(dllimport) long EZGEM_SetLoadPort(EZGEMCLASS pGem, int nPortID, int nTransferState, int nAccessMode, LPCTSTR strLocationName, LPCTSTR strCarrierID);
	__declspec(dllimport) long EZGEM_SetTransferState(EZGEMCLASS pGem, int nPortID, int nTransferState);
	__declspec(dllimport) long EZGEM_SetCarrierArrived(EZGEMCLASS pGem, int nPortID);
	__declspec(dllimport) long EZGEM_SetCarrierRemoved(EZGEMCLASS pGem, int nPortID);
	__declspec(dllimport) long EZGEM_SetDoorState(EZGEMCLASS pGem, int nPortID, int nState);
	__declspec(dllimport) long EZGEM_SetDockState(EZGEMCLASS pGem, int nPortID, int nState);
	__declspec(dllimport) long EZGEM_SetClampState(EZGEMCLASS pGem, int nPortID, int nState);
	__declspec(dllimport) long EZGEM_SetLoadPortAccessMode(EZGEMCLASS pGem, int nPortID, int nMode);
	__declspec(dllimport) long EZGEM_SetCarrierAccessState(EZGEMCLASS pGem, int nPortID, int nState, LPCTSTR strCarrierID);
	__declspec(dllimport) long EZGEM_SetCarrierIDRead(EZGEMCLASS pGem, int nPortID, LPCTSTR strCarrierID, int nResult);
	__declspec(dllimport) long EZGEM_SetCarrierIDStatus(EZGEMCLASS pGem, int nPortID, LPCTSTR strCarrierID, int nStatus);
	__declspec(dllimport) long EZGEM_SetSlotMapRead(EZGEMCLASS pGem, int nPortID, LPCTSTR strCarrierID, LPCTSTR strSlotMap, int nResult);
	__declspec(dllimport) long EZGEM_SetSlotMapStatus(EZGEMCLASS pGem, int nPortID, LPCTSTR strCarrierID, int nStatus);
	__declspec(dllimport) long EZGEM_GetCarrierActionInfo(EZGEMCLASS pGem, long lMsgId, int *pnPortID, BSTR *pstrCarrierID, int *pnContentMapCount, int *pnSlotMapCount);
	__declspec(dllimport) long EZGEM_GetContentMapInfo(EZGEMCLASS pGem, long lMsgId, int nIndex, BSTR *pstrContentMap);
	__declspec(dllimport) long EZGEM_GetSlotMapInfo(EZGEMCLASS pGem, long lMsgId, BSTR *pstrSlotMap);
	__declspec(dllimport) long EZGEM_GetHostSetLoadPortAccessMode(EZGEMCLASS pGem, long lMsgId, int *pnAccessMode, BSTR *pstrPortList);
	__declspec(dllimport) long EZGEM_GetHostSetLoadPortServiceMode(EZGEMCLASS pGem, long lMsgId, int *pnServiceMode, BSTR *pstrPortList);
	__declspec(dllimport) long EZGEM_ReplyCarrierAction(EZGEMCLASS pGem, long lMsgId, int CAACK);
	__declspec(dllimport) long EZGEM_SetCarrierActionErrorCode(EZGEMCLASS pGem, long lMsgId, int nErrorCode, LPCTSTR strErrorText);
	__declspec(dllimport) long EZGEM_DeleteCarrier(EZGEMCLASS pGem, LPCTSTR sCarrierID);
	__declspec(dllimport) long EZGEM_DeleteAllCarrier(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetLoadPortInfo(EZGEMCLASS pGem, int nPortID, BSTR *psLocID, BSTR *psCarrierID, int *pnAccessMode, int *pnTransferState, int *pnReservState, int *pnAssocState);
	__declspec(dllimport) long EZGEM_GetCarrierInfo(EZGEMCLASS pGem, LPCTSTR szCarrierID, BSTR *psLocID, int *pnIDStatus, int *pnSlotMapStatus, int *pnAccessStatus, BSTR *pstrSlotMap, BSTR *psUsage);
	__declspec(dllimport) long EZGEM_GetSlotInfo(EZGEMCLASS pGem, LPCTSTR szCarrierID, int nSlotNo, int *pnSlotType, BSTR *psLotID, BSTR *psSubstID);	
	__declspec(dllimport) long EZGEM_CreateCarrierLoc(EZGEMCLASS pGem, LPCTSTR szLocationID);
	__declspec(dllimport) long EZGEM_SetCarrierLocInfo(EZGEMCLASS pGem, LPCTSTR szLocationID, LPCTSTR szCarrierID);
	__declspec(dllimport) long EZGEM_GetCarrierLocInfo(EZGEMCLASS pGem, LPCTSTR szLocationID, BSTR *psCarrierID);
	__declspec(dllimport) long EZGEM_GetCarrierLocation(EZGEMCLASS pGem, LPCTSTR szCarrierID, BSTR *psLocationID);
	__declspec(dllimport) long EZGEM_SetCarrierMove(EZGEMCLASS pGem, LPCTSTR szCarrierID, LPCTSTR szLocationID);
	__declspec(dllimport) long EZGEM_GetCarrierCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetCarrierList(EZGEMCLASS pGem, long nIndex, BSTR *psCarrierID, BSTR *psLocID);
	__declspec(dllimport) long EZGEM_GetCarrierLocCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetCarrierLocList(EZGEMCLASS pGem, long nIndex, BSTR *psLocationID, BSTR *psCarrierID);
	__declspec(dllimport) long EZGEM_SetCarrierInternalBufferMode(EZGEMCLASS pGem, int nMode);


	// PJM
	__declspec(dllimport) long EZGEM_GetHostSetPrJobCount(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport) long EZGEM_GetHostSetPrJob(EZGEMCLASS pGem, long lMsgId, long nIndex, BSTR *pstrPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount);
	__declspec(dllimport) long EZGEM_GetHostSetPrJobStartMethod(EZGEMCLASS pGem, long lMsgId, int *pnPrJobCount, BSTR *pstrPrJobList, int *pnStartMethod);
	__declspec(dllimport) long EZGEM_GetHostSetPrJobParam(EZGEMCLASS pGem, long lMsgId, BSTR *pstrPrJob, int *pnParamCount);
	__declspec(dllimport) long EZGEM_GetPrJobCarrier(EZGEMCLASS pGem, LPCTSTR szPrJobID, long nIndex, BSTR *pstrCarrierID, BSTR *pstrSlotList);
	__declspec(dllimport) long EZGEM_GetPrJobParam(EZGEMCLASS pGem, LPCTSTR szPrJobID, long nIndex, BSTR *pstrParamName, BSTR *pstrParamVal);
	__declspec(dllimport) long EZGEM_GetPrJobRecipeMethod(EZGEMCLASS pGem, LPCTSTR szPrJobID, int *pnRecipeMethod);
	__declspec(dllimport) long EZGEM_GetPrJobCommand(EZGEMCLASS pGem, long lMsgId, BSTR *pstrPrJobID, BSTR *pstrCommand);
	__declspec(dllimport) long EZGEM_SetPrJobErrorCode(EZGEMCLASS pGem, long lMsgId, LPCTSTR szPrJobID, int nErrorCode, LPCTSTR szErrorText);
	__declspec(dllimport) long EZGEM_ReplyHostSetPrJob(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport) long EZGEM_ReplyPrJobCommand(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport) long EZGEM_GetPrJobCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetPrJobSpace(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetPrJob(EZGEMCLASS pGem, long nIndex, BSTR *pstrPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount);
	__declspec(dllimport) long EZGEM_GetPrJobInfo(EZGEMCLASS pGem, LPCTSTR szPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount);
	__declspec(dllimport) long EZGEM_GetPrJobDeleted(EZGEMCLASS pGem, BSTR *pstrPrJobID);
	__declspec(dllimport) long EZGEM_DeletePrJob(EZGEMCLASS pGem, LPCTSTR szPrJobID);
	__declspec(dllimport) long EZGEM_DeleteAllPrJob(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetPrJobState(EZGEMCLASS pGem, LPCTSTR szPrJobID, int *pnPrJobState);
	__declspec(dllimport) long EZGEM_SetPrJobState(EZGEMCLASS pGem, LPCTSTR szPrJobID, int nPrJobState);
	__declspec(dllimport) long EZGEM_CreatePrJob(EZGEMCLASS pGem, LPCTSTR sPrJobID, int nAutoStart, LPCTSTR sCarrierList, LPCTSTR sSlotList, LPCTSTR sPPID);
	__declspec(dllimport) long EZGEM_CreatePrJobSubst(EZGEMCLASS pGem, LPCTSTR sPrJobID, int nAutoStart, LPCTSTR sSubstrateList, LPCTSTR sPPID);
	__declspec(dllimport) long EZGEM_GetPrJobMaterialFormatCode(EZGEMCLASS pGem, LPCTSTR sPrJobID);
	__declspec(dllimport) long EZGEM_AddPrJobParam(EZGEMCLASS pGem, LPCTSTR szPrJobID, LPCTSTR szParamName, LPCTSTR szParamVal);
	// CJM
	__declspec(dllimport) long EZGEM_GetHostSetCtrlJob(EZGEMCLASS pGem, long lMsgId, BSTR *pstrCtrlJobID, int *pnPrJobCount, int *pnAutoStart); 
	__declspec(dllimport) long EZGEM_GetCtrlJob(EZGEMCLASS pGem, long nIndex, BSTR *pstrCtrlJobID, int *pnPrJobCount, int *pnAutoStart);
	__declspec(dllimport) long EZGEM_GetCtrlJobInfo(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int *pnPrJobCount, int *pnAutoStart);
	__declspec(dllimport) long EZGEM_GetCtrlJobMtrlOutMapCount(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int *pnMtrlOutMapCount);
	__declspec(dllimport) long EZGEM_GetCtrlJobMtrlOutInfo(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int nMapIndex, BSTR *pstrSrcCarrier, BSTR *pstrSrcSlotList, BSTR *pstrDestCarrier, BSTR *pstrDestSlotList);
	__declspec(dllimport) long EZGEM_GetPrJobInCtrlJob(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int nIndex, BSTR *pstrPrJobID);
	__declspec(dllimport) long EZGEM_GetCtrlJobCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetCtrlJobSpace(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetCtrlJobCommand(EZGEMCLASS pGem, long lMsgId, BSTR *pstrCJobID, int *pnCommand);
	__declspec(dllimport) long EZGEM_GetCtrlJobDeleted(EZGEMCLASS pGem, BSTR *pstrCJobID);
	__declspec(dllimport) long EZGEM_ReplyCtrlJob(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport) long EZGEM_ReplyCtrlJobCommand(EZGEMCLASS pGem, long lMsgId);
	__declspec(dllimport) long EZGEM_SetCtrlJobErrorCode(EZGEMCLASS pGem, long lMsgId, int nErrorCode, LPCTSTR szErrorText);
	__declspec(dllimport) long EZGEM_DeleteCtrlJob(EZGEMCLASS pGem, LPCTSTR szCtrlJobID);
	__declspec(dllimport) long EZGEM_DeleteAllCtrlJob(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_SetCtrlJobState(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int nState);
	__declspec(dllimport) long EZGEM_GetCtrlJobState(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, int *pnState);
	__declspec(dllimport) long EZGEM_CreateCtrlJob(EZGEMCLASS pGem, LPCTSTR sCtrlJobID, LPCTSTR sPrJobList, int nAutoStat);
	__declspec(dllimport) long EZGEM_AddCtrlJobCarrierInputSpec(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, LPCTSTR szCarrierID);
	__declspec(dllimport) long EZGEM_AddCtrlJobMtrlOutSpec(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, LPCTSTR szSrcCarrierID, LPCTSTR szSrcSlotList, LPCTSTR szDestCarrierID, LPCTSTR szDestSlotList);
	__declspec(dllimport) long EZGEM_GetCtrlJobCarrierInputSpec(EZGEMCLASS pGem, LPCTSTR szCtrlJobID, BSTR *bstrCarrerList);
	// STS
	__declspec(dllimport) long EZGEM_CreateSubstLoc(EZGEMCLASS pGem, LPCTSTR sLocID);
	__declspec(dllimport) long EZGEM_CreateSubstBatchLoc(EZGEMCLASS pGem, LPCTSTR sBatchLocID);
	__declspec(dllimport) long EZGEM_CreateSubstrate(EZGEMCLASS pGem, LPCTSTR sSubstID);
	__declspec(dllimport) long EZGEM_SetSubstLocInfo(EZGEMCLASS pGem, LPCTSTR sLocID, LPCTSTR sSubstID);
	__declspec(dllimport) long EZGEM_SetSubstBatchLocInfo(EZGEMCLASS pGem, LPCTSTR sBatchLocID, int nPosInBatch, LPCTSTR sSubstID);
	__declspec(dllimport) long EZGEM_GetSubstLocCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetSubstBatchLocCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetSubstrateCount(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_GetSubstrate(EZGEMCLASS pGem, long nIndex, BSTR *psSubstID, BSTR *psCurrentLoc);
	__declspec(dllimport) long EZGEM_GetSubstrateState(EZGEMCLASS pGem, LPCTSTR sSubstID, int *pnTranState, int *pnProcState, int *pnReadState);
	__declspec(dllimport) long EZGEM_GetSubstLocation(EZGEMCLASS pGem, long nIndex, BSTR *psLocID, BSTR *psSubstID, int *pnLocState);
	__declspec(dllimport) long EZGEM_GetSubstBatchLoc(EZGEMCLASS pGem, long nIndex, BSTR *psBatchLocID, int *pnSubstCount, char *psSubstList[]);
	__declspec(dllimport) long EZGEM_GetSubstHostCommand(EZGEMCLASS pGem, long lMsgId, int *pnCommand, BSTR *psSubstID, BSTR *psLocID);
	__declspec(dllimport) long EZGEM_DeleteAllSubstrate(EZGEMCLASS pGem);
	__declspec(dllimport) long EZGEM_DeleteSubstrate(EZGEMCLASS pGem, LPCTSTR sSubstID);
	__declspec(dllimport) long EZGEM_SetSubstrateMove(EZGEMCLASS pGem, LPCTSTR sSubstID, LPCTSTR sToLocID, int nTransferState);
	__declspec(dllimport) long EZGEM_SetSubstBatchMove(EZGEMCLASS pGem, int nCount, BSTR *psSubstList, LPCTSTR sBatchLocID, int nStartPosInBatch, int nTransState);
	__declspec(dllimport) long EZGEM_SetSubstTranState(EZGEMCLASS pGem, LPCTSTR sSubstID, int nTranState);
	__declspec(dllimport) long EZGEM_SetSubstProcState(EZGEMCLASS pGem, LPCTSTR sSubstID, int nProcState);
	__declspec(dllimport) long EZGEM_SetSubstReadState(EZGEMCLASS pGem, LPCTSTR sSubstID, int nReadState);
	__declspec(dllimport) long EZGEM_SetSubstIDRead(EZGEMCLASS pGem, LPCTSTR sSubstID, LPCTSTR sReadID, int nReadResult);
	__declspec(dllimport) long EZGEM_ReplySubstAction(EZGEMCLASS pGem, long lMsgId, int nRetCode, int nErrCode, LPCTSTR szErrText);
	__declspec(dllimport) long EZGEM_SetSubstLocState(EZGEMCLASS pGem, LPCTSTR sLocID, int nLocState);
	// OSS
	__declspec(dllimport) long EZGEM_GetAttrName(EZGEMCLASS pGem, LPCTSTR sObjType, BSTR *psAttrNameList);		
	__declspec(dllimport) long EZGEM_GetAttrData(EZGEMCLASS pGem, LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sObjName, BSTR *psAttrData);		
	__declspec(dllimport) long EZGEM_SetAttrData(EZGEMCLASS pGem, LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sObjName, LPCTSTR psAttrData);
	__declspec(dllimport) long EZGEM_GetObjectList(EZGEMCLASS pGem, LPCTSTR sObjType, BSTR *psObjList);
};

#include <vector>
#include <sstream>
#include <iostream>

using namespace std;

class EZGemPlus
{
private:
	EZGEMCLASS pGEM;
public:
	EZGemPlus() { pGEM = EZGEM_CreateClass(); }
	//~EZGemPlus()	{ EZGEM_DeleteClass(pGEM); }

	short Start() { return EZGEM_Start(pGEM); }
	short Stop() { return EZGEM_Stop(pGEM); }

	void  SetEventHandler(void* lpHandle, pNativeCallBackEvent cb) { EZGEM_SetEventHandler(pGEM, lpHandle, cb); }
	void  SetMsgHandler(void* lpHandle, pNativeCallBackMsg cb) { EZGEM_SetMsgHandler(pGEM, lpHandle, cb); }

	void  SetPassiveMode(short bNewValue) { EZGEM_SetPassiveMode(pGEM, bNewValue); }
	short GetPassiveMode() { return EZGEM_GetPassiveMode(pGEM); }

	long  CreateMsg(short nStream, short nFunction, short nWbit) { return EZGEM_CreateMsg(pGEM, nStream, nFunction, nWbit); }
	long  CreateReplyMsg(long lMsgId) { return EZGEM_CreateReplyMsg(pGEM, lMsgId); }
	short SendMsg(long lMsgId) { return EZGEM_SendMsg(pGEM, lMsgId); }
	short SendMsgEx(long lMsgId, long nTransactionID) { return EZGEM_SendMsgEx(pGEM, lMsgId, nTransactionID); }
	short CloseMsg(long lMsgId) { return EZGEM_CloseMsg(pGEM, lMsgId); }
	short GetMsgInfo(long lMsgId, short * pnStream, short * pnFunction, short * pnWbit, long * plLength)
	{
		return EZGEM_GetMsgInfo(pGEM, lMsgId, pnStream, pnFunction, pnWbit, plLength);
	}
	short GetDeviceID() { return EZGEM_GetDeviceID(pGEM); }
	void  SetDeviceID(short nNewValue) { EZGEM_SetDeviceID(pGEM, nNewValue); }
	BSTR  GetIP() { return EZGEM_GetIP(pGEM); }
	void  SetIP(LPCTSTR lpszNewValue) { EZGEM_SetIP(pGEM, lpszNewValue); }
	short GetPort() { return EZGEM_GetPort(pGEM); }
	void  SetPort(short nNewValue) { EZGEM_SetPort(pGEM, nNewValue); }
	short GetT3() { return EZGEM_GetT3(pGEM); }
	void  SetT3(short nNewValue) { EZGEM_SetT3(pGEM, nNewValue); }
	short GetT5() { return EZGEM_GetT5(pGEM); }
	void  SetT5(short nNewValue) { EZGEM_SetT5(pGEM, nNewValue); }
	short GetT6() { return EZGEM_GetT6(pGEM); }
	void  SetT6(short nNewValue) { EZGEM_SetT6(pGEM, nNewValue); }
	short GetT7() { return EZGEM_GetT7(pGEM); }
	void  SetT7(short nNewValue) { EZGEM_SetT7(pGEM, nNewValue); }
	short GetT8() { return EZGEM_GetT8(pGEM); }
	void  SetT8(short nNewValue) { EZGEM_SetT8(pGEM, nNewValue); }
	short GetRetry() { return EZGEM_GetRetry(pGEM); }
	void  SetRetry(short nNewValue) { EZGEM_SetRetry(pGEM, nNewValue); }
	short GetLinkTestInterval() { return EZGEM_GetLinkTestInterval(pGEM); }
	void  SetLinkTestInterval(short nNewValue) { EZGEM_SetLinkTestInterval(pGEM, nNewValue); }
	short GetRuntimeState() { return EZGEM_GetRuntimeState(pGEM); }
	short OpenListItem(long lMsgId) { return EZGEM_OpenListItem(pGEM, lMsgId); }
	short CloseListItem(long lMsgId) { return EZGEM_CloseListItem(pGEM, lMsgId); }
	short AddBinaryItem(long lMsgId, short * pValue, long lCount) { return EZGEM_AddBinaryItem(pGEM, lMsgId, pValue, lCount); }
	short AddBinaryItem(long lMsgId, BYTE * pValue, long lCount) { return EZGEM_AddByteItem(pGEM, lMsgId, pValue, lCount); }
	short AddAsciiItem(long lMsgId, LPCTSTR pszValue, long lCount) { return EZGEM_AddAsciiItem(pGEM, lMsgId, pszValue, lCount); }
	short AddBoolItem(long lMsgId, short * pValue, long lCount) { return EZGEM_AddBoolItem(pGEM, lMsgId, pValue, lCount); }
	short AddI1Item(long lMsgId, short * pValue, long lCount) { return EZGEM_AddI1Item(pGEM, lMsgId, pValue, lCount); }
	short AddI2Item(long lMsgId, short * pValue, long lCount) { return EZGEM_AddI2Item(pGEM, lMsgId, pValue, lCount); }
	short AddI4Item(long lMsgId, long * plValue, long lCount) { return EZGEM_AddI4Item(pGEM, lMsgId, plValue, lCount); }
	short AddI8Item(long lMsgId, long * plValue, long lCount) { return EZGEM_AddI8Item(pGEM, lMsgId, plValue, lCount); }
	short AddI8ItemI64(long lMsgId, LONGLONG * plValue, long lCount) { return EZGEM_AddI8ItemI64(pGEM, lMsgId, plValue, lCount); }
	short AddU1Item(long lMsgId, short * pValue, long lCount) { return EZGEM_AddU1Item(pGEM, lMsgId, pValue, lCount); }
	short AddU2Item(long lMsgId, long * plValue, long lCount) { return EZGEM_AddU2Item(pGEM, lMsgId, plValue, lCount); }
	short AddU4Item(long lMsgId, double * prValue, long lCount) { return EZGEM_AddU4Item(pGEM, lMsgId, prValue, lCount); }
	short AddU8Item(long lMsgId, double * prValue, long lCount) { return EZGEM_AddU8Item(pGEM, lMsgId, prValue, lCount); }
	short AddU8ItemU64(long lMsgId, ULONGLONG * prValue, long lCount) { return EZGEM_AddU8ItemU64(pGEM, lMsgId, prValue, lCount); }
	short AddF4Item(long lMsgId, float * prValue, long lCount) { return EZGEM_AddF4Item(pGEM, lMsgId, prValue, lCount); }
	short AddF8Item(long lMsgId, double * prValue, long lCount) { return EZGEM_AddF8Item(pGEM, lMsgId, prValue, lCount); }
	short AddJ8Item(long lMsgId, LPCTSTR pszValue, long lCount) { return EZGEM_AddJ8Item(pGEM, lMsgId, pszValue, lCount); }
	short GetListItemOpen(long lMsgId) { return EZGEM_GetListItemOpen(pGEM, lMsgId); }
	short GetListItemClose(long lMsgId) { return EZGEM_GetListItemClose(pGEM, lMsgId); }
	long  GetAsciiItem(long lMsgId, BSTR * pszValue) { return EZGEM_GetAsciiItem(pGEM, lMsgId, pszValue); }
	long  GetAsciiItem(long lMsgId, CString* pstrValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetAsciiItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		*pstrValue = CString(bstrValue);
		SysFreeString(bstrValue);
		return nRet;
	}
	long  GetAsciiItem(long lMsgId, CString& pstrValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetAsciiItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		pstrValue = CString(bstrValue);
		SysFreeString(bstrValue);
		return nRet;
	}
	long  GetJ8Item(long lMsgId, BSTR * pszValue) { return EZGEM_GetJ8Item(pGEM, lMsgId, pszValue); }
	long  GetBinaryItem(long lMsgId, short * pnValue) { return EZGEM_GetBinaryItem(pGEM, lMsgId, pnValue); }
	long  GetBinaryItem(long lMsgId, BYTE * pnValue) { return EZGEM_GetByteItem(pGEM, lMsgId, pnValue); }
	long  GetBoolItem(long lMsgId, short * pnValue) { return EZGEM_GetBoolItem(pGEM, lMsgId, pnValue); }
	long  GetI1Item(long lMsgId, short * pnValue) { return EZGEM_GetI1Item(pGEM, lMsgId, pnValue); }
	long  GetI2Item(long lMsgId, short * pnValue) { return EZGEM_GetI2Item(pGEM, lMsgId, pnValue); }
	long  GetI4Item(long lMsgId, long * plValue) { return EZGEM_GetI4Item(pGEM, lMsgId, plValue); }
	long  GetI8Item(long lMsgId, long * plValue) { return EZGEM_GetI8Item(pGEM, lMsgId, plValue); }
	long  GetI8ItemI64(long lMsgId, LONGLONG * plValue) { return EZGEM_GetI8ItemI64(pGEM, lMsgId, plValue); }
	long  GetU1Item(long lMsgId, short * pnValue) { return EZGEM_GetU1Item(pGEM, lMsgId, pnValue); }
	long  GetU2Item(long lMsgId, long * plValue) { return EZGEM_GetU2Item(pGEM, lMsgId, plValue); }
	long  GetU4Item(long lMsgId, double * prValue) { return EZGEM_GetU4Item(pGEM, lMsgId, prValue); }
	long  GetU8Item(long lMsgId, double * prValue) { return EZGEM_GetU8Item(pGEM, lMsgId, prValue); }
	long  GetU8ItemU64(long lMsgId, ULONGLONG * prValue) { return EZGEM_GetU8ItemU64(pGEM, lMsgId, prValue); }
	long  GetF4Item(long lMsgId, float * prValue) { return EZGEM_GetF4Item(pGEM, lMsgId, prValue); }
	long  GetF8Item(long lMsgId, double * prValue) { return EZGEM_GetF8Item(pGEM, lMsgId, prValue); }
	void  SetLogFile(LPCTSTR strFileName, short bLogSecsII) { EZGEM_SetLogFile(pGEM, strFileName, bLogSecsII); }
	long  GetCurLogFile(BSTR *psCurLogFile) { return EZGEM_GetCurLogFile(pGEM, psCurLogFile); }
	long  GetCurLogFile(CString *psLogFile)
	{
		BSTR bsLogFile = nullptr;
		long nRet = EZGEM_GetCurLogFile(pGEM, &bsLogFile);
		if (nRet < 0) return nRet;
		*psLogFile = (CString)bsLogFile;
		SysFreeString(bsLogFile);
		return nRet;
	}
	long  GetCurLogFile(CString& strLogFile)
	{
		BSTR bstrLogFile = nullptr;
		long nRet = EZGEM_GetCurLogFile(pGEM, &bstrLogFile);
		if (nRet < 0) return nRet;
		strLogFile = CString(bstrLogFile);
		SysFreeString(bstrLogFile);
		return nRet;
	}
	short GetNextItemFormat(long lMsgId) { return EZGEM_GetNextItemFormat(pGEM, lMsgId); }
	short GetSubItemFormat(long lMsgId) { return EZGEM_GetSubItemFormat(pGEM, lMsgId); }
	long  GetNextItemCount(long lMsgId) { return EZGEM_GetNextItemCount(pGEM, lMsgId); }
	long  GetSubItemCount(long lMsgId) { return EZGEM_GetSubItemCount(pGEM, lMsgId); }
	short AbortMsg(long lMsgId) { return EZGEM_AbortMsg(pGEM, lMsgId); }
	void  SetLogRetention(short nDays) { EZGEM_SetLogRetention(pGEM, nDays); }
	short GetLogRetention() { return EZGEM_GetLogRetention(pGEM); }
	void  SetFormatCheck(short bEnabled) { EZGEM_SetFormatCheck(pGEM, bEnabled); }
	short GetFormatCheck() { return EZGEM_GetFormatCheck(pGEM); }
	void  SetFormatFile(LPCTSTR lpszFormatFile) { EZGEM_SetFormatFile(pGEM, lpszFormatFile); }
	long  AddFileBinaryItem(long lMsgId, LPCTSTR szFile) { return EZGEM_AddFileBinaryItem(pGEM, lMsgId, szFile); }
	long  GetFileBinaryItem(long lMsgId, LPCTSTR szFile) { return EZGEM_GetFileBinaryItem(pGEM, lMsgId, szFile); }
	long  GetMsgHead(long lMsgId, UCHAR *pnByteBuff) { return EZGEM_GetMsgHead(pGEM, lMsgId, pnByteBuff); }
	long  GetMsgBody(long lMsgId, UCHAR *pnByteBuff, long lSize) { return EZGEM_GetMsgBody(pGEM, lMsgId, pnByteBuff, lSize); }
	void  EnableErrorMessage() { EZGEM_EnableErrorMessage(pGEM); }
	void  DisableErrorMessage() { EZGEM_DisableErrorMessage(pGEM); }
	short AddListItem(long lMsgId, long lCount) { return EZGEM_AddListItem(pGEM, lMsgId, lCount); }
	long  GetListItem(long lMsgId) { return EZGEM_GetListItem(pGEM, lMsgId); }
	void  SetConfigFile(LPCTSTR strConfigFile) { EZGEM_SetConfigFile(pGEM, strConfigFile); }
	void  SaveConfigFile(LPCTSTR strConfigFile) { EZGEM_SaveConfigFile(pGEM, strConfigFile); }
	short SeparateLog(LPCTSTR szLogFileName, short nStream, short nFunction) { return EZGEM_SeparateLog(pGEM, szLogFileName, nStream, nFunction); }
	void  SetMaxLogFileSize(short nMegaByte) { EZGEM_SetMaxLogFileSize(pGEM, nMegaByte); }
	short SetLogDelTime(long nDelTime) { return EZGEM_SetLogDelTime(pGEM, nDelTime); }
	long  SetMsgHead(long lMsgId, UCHAR * pnBuff) { return EZGEM_SetMsgHead(pGEM, lMsgId, pnBuff); }
	long  SetMsgBody(long lMsgId, UCHAR * pnBuff, long lSize) { return EZGEM_SetMsgBody(pGEM, lMsgId, pnBuff, lSize); }
	long  AddArrayItem(long lMsgId, LPCTSTR pszType, long nDataCount, LPCTSTR pszData) { return EZGEM_AddArrayItem(pGEM, lMsgId, pszType, nDataCount, pszData); }
	long  GetArrayItem(long lMsgId, BSTR * pszValue) { return EZGEM_GetArrayItem(pGEM, lMsgId, pszValue); }
	long  GetArrayItem(long lMsgId, CString *psValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetArrayItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		*psValue = (CString)bstrValue;
		SysFreeString(bstrValue);
		return nRet;
	}
	long  GetArrayItem(long lMsgId, CString& strValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetArrayItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		strValue = CString(bstrValue);
		SysFreeString(bstrValue);
		return nRet;
	}
	void  EnableLog() { EZGEM_EnableLog(pGEM); }
	void  DisableLog() { EZGEM_DisableLog(pGEM); }
	void  SkipLog(short nStream, short nFunction) { EZGEM_SkipLog(pGEM, nStream, nFunction); }
	void  SkipLogReset(short nStream, short nFunction) { EZGEM_SkipLogReset(pGEM, nStream, nFunction); }
	void  WriteUserLog(LPCTSTR pszLog) { EZGEM_WriteUserLog(pGEM, pszLog); }
	long  GetNextEvent(short  *pnEventID, long  *plParam) { return EZGEM_GetNextEvent(pGEM, pnEventID, plParam); }
	long  GetNextMsg(long  *plMsgId) { return EZGEM_GetNextMsg(pGEM, plMsgId); }
	short GetMsgQueSize() { return EZGEM_GetMsgQueSize(pGEM); }
	long  GetSysByte(long lMsgId) { return EZGEM_GetSysByte(pGEM, lMsgId); }
	long  GetSysByteEx(long nTransactionID) { return EZGEM_GetSysByteEx(pGEM, nTransactionID); }
	long  GetItem(long lMsgId, BSTR *pstrValue) { return EZGEM_GetItem(pGEM, lMsgId, pstrValue); }
	long  GetItem(long lMsgId, CString *pstrValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		*pstrValue = (CString)bstrValue;
		SysFreeString(bstrValue);
		return nRet;
	}
	long  GetItem(long lMsgId, CString& strValue)
	{
		BSTR bstrValue = nullptr;
		long nRet = EZGEM_GetItem(pGEM, lMsgId, &bstrValue);
		if (nRet < 0) return nRet;
		strValue = CString(bstrValue);
		SysFreeString(bstrValue);
		return nRet;
	}
	long  SaveMsgToFile(long lMsgId, LPCTSTR sFile) { return EZGEM_SaveMsgToFile(pGEM, lMsgId, sFile); }
	long  SendMsgFromFile(LPCTSTR sFile) { return EZGEM_SendMsgFromFile(pGEM, sFile); }
	long  GetListChildItem(long lMsgId, LPCTSTR sDelimiter, BSTR *psValue, long *plLength)	{ return EZGEM_GetListChildItem(pGEM, lMsgId, sDelimiter, psValue,  plLength); }
	long  GetListChildItem(long lMsgId, CStringArray* pValueList)
	{
		BSTR bstrValue;
		long lLength = 0;
		long nResult = GetListChildItem(lMsgId, _T(","), &bstrValue, &lLength);
		if (nResult < 0) return nResult;

		CString strValue(bstrValue);  // BSTR -> CString
		SysFreeString(bstrValue);

#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strValue);
		std::wstring token;
		while (std::getline(ssValue, token, L',')) 
		{
			pValueList->Add(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strValue);
		std::string token;
		while (std::getline(ssValue, token, ',')) 
		{
			pValueList->Add(token.c_str());
		}
#endif
		if (pValueList->GetSize() == nResult - 1) 
		{
			pValueList->Add(_T(""));  // 마지막 공백 처리
		}
		return nResult;
	}
	long  GetListChildItem(long lMsgId, CStringArray& pValueList)
	{
		BSTR bstrValue = nullptr;
		long lLength = 0;
		long nResult = GetListChildItem(lMsgId, _T(","), &bstrValue, &lLength);
		if (nResult < 0) return nResult;

		CString strValue(bstrValue);  // BSTR -> CString
		SysFreeString(bstrValue);
#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strValue);
		std::wstring token;
		while (std::getline(ssValue, token, L','))
		{
			pValueList.Add(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strValue);
		std::string token;
		while (std::getline(ssValue, token, ','))
		{
			pValueList.Add(token.c_str());
		}
#endif
		if (pValueList.GetSize() == nResult - 1)
		{
			pValueList.Add(_T(""));  // 마지막 공백 처리
		}
		return nResult;
	}
	long  GetListChildItem(long lMsgId, std::vector<CString>& valueList)
	{
		BSTR bstrValue = nullptr;
		long lLength = 0;
		long nResult = GetListChildItem(lMsgId, _T(","), &bstrValue, &lLength);
		if (nResult < 0) return nResult;
		CString strValue(bstrValue);
		SysFreeString(bstrValue);
#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strValue);
		std::wstring token;
		while (std::getline(ssValue, token, L','))
		{
			valueList.emplace_back(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strValue);
		std::string token;
		while (std::getline(ssValue, token, ','))
		{
			valueList.emplace_back(token.c_str());
		}
#endif
		if (valueList.size() == static_cast<size_t>(nResult - 1))
		{
			valueList.emplace_back(_T(""));
		}
		return nResult;
	}
	long  GetNameValueListItem(long lMsgId, LPCTSTR sDelimiter, BSTR *psNameList, BSTR *psValueList, long *plCount) { return EZGEM_GetNameValueListItem(pGEM, lMsgId, sDelimiter, psNameList, psValueList, plCount); }
	long  GetNameValueListItem(long lMsgId, CStringArray* pNameList, CStringArray* pValueList)
	{
		BSTR bstrName, bstrVal;
		long lCount = 0;
		long nResult = GetNameValueListItem(lMsgId, _T(","), &bstrName, &bstrVal, &lCount);
		if (nResult < 0) return nResult;

		CString strName(bstrName);
		CString strVal(bstrVal);
		SysFreeString(bstrName);
		SysFreeString(bstrVal);
#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strName);
		std::wstringstream ssValue((LPCTSTR)strVal);
		std::wstring token;

		while (std::getline(ssName, token, L',')) 
		{
			pNameList->Add(token.c_str());
		}
		while (std::getline(ssValue, token, L',')) 
		{
			pValueList->Add(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strName);
		std::stringstream ssValue((LPCTSTR)strVal);
		std::string token;

		while (std::getline(ssName, token, ',')) 
		{
			pNameList->Add(token.c_str());
		}
		while (std::getline(ssValue, token, ',')) 
		{
			pValueList->Add(token.c_str());
		}
#endif
		if (pValueList->GetSize() == pNameList->GetSize() - 1) 
		{
			pValueList->Add(_T(""));
		}
		return lCount;
	}
	long  GetNameValueListItem(long lMsgId, CStringArray& pNameList, CStringArray& pValueList)
	{
		BSTR bstrName = nullptr, bstrVal = nullptr;
		long lCount = 0;

		long nResult = GetNameValueListItem(lMsgId, _T(","), &bstrName, &bstrVal, &lCount);
		if (nResult < 0)
			return nResult;

		CString strName(bstrName);
		CString strVal(bstrVal);
		SysFreeString(bstrName);
		SysFreeString(bstrVal);

#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strName);
		std::wstringstream ssValue((LPCTSTR)strVal);
		std::wstring token;

		while (std::getline(ssName, token, L','))
		{
			pNameList.Add(token.c_str());
		}

		while (std::getline(ssValue, token, L','))
		{
			pValueList.Add(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strName);
		std::stringstream ssValue((LPCTSTR)strVal);
		std::string token;

		while (std::getline(ssName, token, ','))
		{
			pNameList.Add(token.c_str());
		}

		while (std::getline(ssValue, token, ','))
		{
			pValueList.Add(token.c_str());
		}
#endif
		if (pValueList.GetSize() == pNameList.GetSize() - 1)
		{
			pValueList.Add(_T(""));
		}
		return lCount;
	}
	long  GetNameValueListItem(long lMsgId, std::vector<CString>& nameList, std::vector<CString>& valueList)
	{
		BSTR bstrName = nullptr;
		BSTR bstrVal = nullptr;
		long lCount = 0;
		long nResult = GetNameValueListItem(lMsgId, _T(","), &bstrName, &bstrVal, &lCount);
		if (nResult < 0) return nResult;
		CString strName(bstrName);
		CString strVal(bstrVal);
		SysFreeString(bstrName);
		SysFreeString(bstrVal);
#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strName);
		std::wstringstream ssValue((LPCTSTR)strVal);
		std::wstring token;
		while (std::getline(ssName, token, L','))
		{
			nameList.emplace_back(token.c_str());
		}
		while (std::getline(ssValue, token, L','))
		{
			valueList.emplace_back(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strName);
		std::stringstream ssValue((LPCTSTR)strVal);
		std::string token;
		while (std::getline(ssName, token, ','))
		{
			nameList.emplace_back(token.c_str());
		}
		while (std::getline(ssValue, token, ','))
		{
			valueList.emplace_back(token.c_str());
		}
#endif
		if (valueList.size() == nameList.size() - 1)
		{
			valueList.emplace_back(_T(""));
		}
		return lCount;
	}
	long  SendS9F3(long lMsgId) { return EZGEM_SendS9F3(pGEM, lMsgId); }
	long  SendS9F5(long lMsgId) { return EZGEM_SendS9F5(pGEM, lMsgId); }
	long  SendS9F7(long lMsgId) { return EZGEM_SendS9F7(pGEM, lMsgId); }
	long  SendS9F11(long lMsgId) { return EZGEM_SendS9F11(pGEM, lMsgId); }
	void  GetVersionInfo(BSTR *psVersionInfo) { EZGEM_GetVersionInfo(pGEM, psVersionInfo); }
	void  GetVersionInfo(CString *psVersion)
	{
		BSTR bsVersion = nullptr;
		EZGEM_GetVersionInfo(pGEM, &bsVersion);
		*psVersion = (CString)bsVersion;
		SysFreeString(bsVersion);
	}
	void  GetVersionInfo(CString& pstrVersionInfo)
	{
		BSTR bstrVersionInfo = nullptr;
		EZGEM_GetVersionInfo(pGEM, &bstrVersionInfo);
		pstrVersionInfo = CString(bstrVersionInfo);
		SysFreeString(bstrVersionInfo);
	}
	long  GetItemInfo(long lMsgId, LPCTSTR sPos, short *pnFormat, long *plCount)	{	return EZGEM_GetItemInfo(pGEM, lMsgId, sPos, pnFormat, plCount);	}
	long  GetItemValue(long lMsgId, LPCTSTR sPos, BSTR *pbstrValue)	{	return EZGEM_GetItemValue(pGEM, lMsgId, sPos, pbstrValue);	}
	long  GetItemValue(long lMsgId, LPCTSTR sPos, CString *psValue)
	{
		BSTR bstrVal = nullptr;
		long nRet = EZGEM_GetItemValue(pGEM, lMsgId, sPos, &bstrVal);
		if (nRet < 0) return nRet;
		*psValue = (CString)bstrVal;
		SysFreeString(bstrVal);
		return nRet;
	}
	long  GetItemValue(long lMsgId, LPCTSTR sPos, CString& psValue)
	{
		BSTR bstrVal = nullptr;
		long nRet = EZGEM_GetItemValue(pGEM, lMsgId, sPos, &bstrVal);
		if (nRet < 0) return nRet;
		psValue = CString(bstrVal);
		SysFreeString(bstrVal);
		return nRet;
	}
	long  SetOption(LPCTSTR sOptionName, int nOptionVal){	return EZGEM_SetOption(pGEM, sOptionName, nOptionVal);}
	//--------------------- END OF EZNET FUNCTION ---------------------------
	void  SetEstablishCommTimer(short nCommReqTimeOut) { EZGEM_SetCommRequestTime(pGEM, nCommReqTimeOut); }
	short GetEstablishCommTimer() { return EZGEM_GetCommRequestTime(pGEM); }
	void  SetModelName(const char *lpszModelName) { EZGEM_SetModelName(pGEM, lpszModelName); }
	void  SetSoftRev(const char *lpszSoftRev) { EZGEM_SetSoftRev(pGEM, lpszSoftRev); }
	void  GoOffline() { EZGEM_GoOffline(pGEM); }
	void  GoOnlineLocal() { EZGEM_GoOnlineLocal(pGEM); }
	void  GoOnlineRemote() { EZGEM_GoOnlineRemote(pGEM); }
	long  AddCEID(long CEID, const char *pszName, const char *pszDescription) { return EZGEM_AddCEID(pGEM, CEID, pszName, pszDescription); }
	long  AddSVID(long SVID, const char *pszName, const char *pszFormat, const char *pszUnit) { return EZGEM_AddSVID(pGEM, SVID, pszName, pszFormat, pszUnit); }
	long  AddDVID(long DVID, const char *pszName, const char *pszFormat) { return EZGEM_AddDVID(pGEM, DVID, pszName, pszFormat); }
	long  AddALID(long ALID, const char *pszName, const char *pszALCD) { return EZGEM_AddALID(pGEM, ALID, pszName, pszALCD); }
	long  AddECID(long ECID, const char *pszName, const char *pszUnit, const char *pszFormat) { return EZGEM_AddECID(pGEM, ECID, pszName, pszUnit, pszFormat); }
	long  AddRemoteCommand(const char *pszCommand) { return EZGEM_AddRemoteCommand(pGEM, pszCommand); }
	short GetRemoteCommand(long lMsgId, BSTR  *pstrCommandName) { return EZGEM_GetRemoteCommand(pGEM, lMsgId, pstrCommandName); }
	short GetRemoteCommand(long lMsgId, CString* strCommandName)
	{
		BSTR bstrCommandName = nullptr;
		short nResult = EZGEM_GetRemoteCommand(pGEM, lMsgId, &bstrCommandName);
		if (nResult < 0) return nResult;
		*strCommandName = CString(bstrCommandName);
		::SysFreeString(bstrCommandName);
		return nResult;
	}
	short GetRemoteCommand(long lMsgId, CString& strCommandName)
	{
		BSTR bstrCommandName = nullptr;
		short nResult = EZGEM_GetRemoteCommand(pGEM, lMsgId, &bstrCommandName);
		if (nResult < 0) return nResult;
		strCommandName = CString(bstrCommandName);
		::SysFreeString(bstrCommandName);
		return nResult;
	}
	short GetRemoteCommandParam(long lMsgId, short nIndex, BSTR  *pstrName, BSTR  *pstrValue, short *pnFormat) { return EZGEM_GetRemoteCommandParam(pGEM, lMsgId, nIndex, pstrName, pstrValue, pnFormat); }
	short GetRemoteCommandParam(long lMsgId, short nIndex, CString* strName, CString* strValue, short* pnFormat)
	{
		BSTR pstrName = 0;
		BSTR pstrValue = 0;
		short nAck = EZGEM_GetRemoteCommandParam(pGEM, lMsgId, nIndex, &pstrName, &pstrValue, pnFormat);
		if (nAck < 0) return nAck;
		*strName = (CString)pstrName;
		*strValue = (CString)pstrValue;

		SysFreeString(pstrName);
		SysFreeString(pstrValue);

		return  nAck;
	}
	short GetRemoteCommandParam(long lMsgId, short nIndex, CString& strName, CString& strValue, short* pnFormat)
	{
		BSTR bstrName = nullptr;
		BSTR bstrValue = nullptr;
		short nResult = EZGEM_GetRemoteCommandParam(pGEM, lMsgId, nIndex, &bstrName, &bstrValue, pnFormat);
		if (nResult < 0) return nResult;
		if (bstrName)
		{
			strName = CString(bstrName);
			::SysFreeString(bstrName);
		}
		else
		{
			strName.Empty();
		}
		if (bstrValue)
		{
			strValue = CString(bstrValue);
			::SysFreeString(bstrValue);
		}
		else
		{
			strValue.Empty();
		}
		return nResult;
	}
	short ReplyRemoteCommand(long lMsgId, short HCACK) { return EZGEM_ReplyRemoteCommand(pGEM, lMsgId, HCACK); }
	short SendEventReport(long CEID) { return EZGEM_SendEventReport(pGEM, CEID); }
	short SendEventReportEx(long CEID, long nTransactionID) { return EZGEM_SendEventReportEx(pGEM, CEID, nTransactionID); }
	short SendAlarmReport(long ALID, short ALCD) { return EZGEM_SendAlarmReport(pGEM, ALID, ALCD); }
	short SendAlarmReportEx(long ALID, short ALCD, short nMode) { return EZGEM_SendAlarmReportEx(pGEM, ALID, ALCD, nMode); }
	long  DisableAutoReply(short nStream, short nFunction) { return EZGEM_DisableAutoReply(pGEM, nStream, nFunction); }
	long  EnableAutoReply(short nStream, short nFunction) { return EZGEM_EnableAutoReply(pGEM, nStream, nFunction); }
	long  SetSVIDValue(long SVID, const char *pszValue) { return EZGEM_SetSVIDValue(pGEM, SVID, pszValue); }
	long  SetVIDValue(long VID, const char *pszValue) { return EZGEM_SetVIDValue(pGEM, VID, pszValue); }
	short GetSVIDValue(long SVID, BSTR  *pstrCurrentValue) { return EZGEM_GetSVIDValue(pGEM, SVID, pstrCurrentValue); }
	short GetSVIDValue(long SVID, CString* strCurrentValue)
	{
		short nAck = 0;
		BSTR bstCurrentValue = 0;
		nAck = EZGEM_GetSVIDValue(pGEM, SVID, &bstCurrentValue);
		if (nAck < 0) return nAck;
		*strCurrentValue = (CString)bstCurrentValue;
		SysFreeString(bstCurrentValue);
		return  nAck;
	}
	short GetSVIDValue(long SVID, CString& strCurrentValue)
	{
		BSTR bstrCurrentValue = nullptr;
		short nResult = EZGEM_GetSVIDValue(pGEM, SVID, &bstrCurrentValue);
		if (nResult < 0) return nResult;
		strCurrentValue = CString(bstrCurrentValue);
		::SysFreeString(bstrCurrentValue);
		return nResult;
	}
	long  GetSVID(long SVID, short  *pnFormat, BSTR  *pstrName) { return EZGEM_GetSVID(pGEM, SVID, pnFormat, pstrName); }
	long  GetSVID(long SVID, short* pnFormat, CString* strName)
	{
		long lAck = 0;
		BSTR bstName = 0;
		lAck = EZGEM_GetSVID(pGEM, SVID, pnFormat, &bstName);
		if (lAck < 0) return lAck;
		*strName = (CString)bstName;
		SysFreeString(bstName);
		return lAck;
	}
	long  GetSVID(long SVID, short* pnFormat, CString& strName)
	{
		BSTR bstrName = nullptr;
		long nResult = EZGEM_GetSVID(pGEM, SVID, pnFormat, &bstrName);
		if (nResult < 0) return nResult;
		strName = CString(bstrName);
		::SysFreeString(bstrName);
		return nResult;
	}
	short GetHostSetECID(long lMsgId, long *lpECID, BSTR *pstrNewValue) { return EZGEM_GetHostSetECID(pGEM, lMsgId, lpECID, pstrNewValue); }
	short GetHostSetECID(long lMsgId, long* lpECID, CString* strNewValue)
	{
		short nAck = 0;
		BSTR bstNewValue = 0;
		nAck = EZGEM_GetHostSetECID(pGEM, lMsgId, lpECID, &bstNewValue);
		if (nAck < 0) return nAck;
		*strNewValue = (CString)bstNewValue;
		SysFreeString(bstNewValue);
		return nAck;
	}
	short GetHostSetECID(long lMsgId, long* lpECID, CString& strNewValue)
	{
		BSTR bstrNewValue = nullptr;
		short nResult = EZGEM_GetHostSetECID(pGEM, lMsgId, lpECID, &bstrNewValue);
		if (nResult < 0) return nResult;
		strNewValue = CString(bstrNewValue);
		::SysFreeString(bstrNewValue);
		return nResult;
	}
	short SetECValue(long ECID, const char *pszValue) { return EZGEM_SetECValue(pGEM, ECID, pszValue); }
	long  GetECValue(long ECID, BSTR  *pstrValue) { return EZGEM_GetECValue(pGEM, ECID, pstrValue); }
	long  GetECValue(long ECID, CString* strValue)
	{
		long lAck = 0;
		BSTR bstValue = 0;
		lAck = EZGEM_GetECValue(pGEM, ECID, &bstValue);
		if (lAck < 0) return lAck;
		*strValue = (CString)bstValue;
		SysFreeString(bstValue);
		return lAck;
	}
	long  GetECValue(long ECID, CString& strValue)
	{
		BSTR bstrValue = nullptr;
		long nResult = EZGEM_GetECValue(pGEM, ECID, &bstrValue);
		if (nResult < 0) return nResult;
		strValue = CString(bstrValue);
		::SysFreeString(bstrValue);
		return nResult;
	}
	short SetECRange(long ECID, const char *pszMinValue, const char *pszMaxValue) { return EZGEM_SetECRange(pGEM, ECID, pszMinValue, pszMaxValue); }
	short ReplyHostSetECID(long lMsgId, short EAC) { return EZGEM_ReplyHostSetECID(pGEM, lMsgId, EAC); }
	void  EnableSpooling() { EZGEM_EnableSpooling(pGEM); }
	void  DisableSpooling() { EZGEM_DisableSpooling(pGEM); }
	long  GetSpoolCount() { return EZGEM_GetSpoolCount(pGEM); }
	void  SetMaxSpoolCount(UINT nMaxSpoolCount) { EZGEM_SetMaxSpoolCount(pGEM, nMaxSpoolCount); }
	long  GetMaxSpoolCount() { return EZGEM_GetMaxSpoolCount(pGEM); }
	void  SetMaxSpoolTransmitCount(UINT nMaxSpoolTransmit) { EZGEM_SetMaxSpoolTransmitCount(pGEM, nMaxSpoolTransmit); }
	long  GetMaxSpoolTransmitCount() { return EZGEM_GetMaxSpoolTransmitCount(pGEM); }
	void  EnableSpoolOverwrite() { EZGEM_EnableSpoolOverwrite(pGEM); }
	void  DisableSpoolOverwrite() { EZGEM_DisableSpoolOverwrite(pGEM); }
	long  GetTerminalMsg(long lMsgId, short *pnTID, BSTR *pstrMsg) { return EZGEM_GetTerminalMsg(pGEM, lMsgId, pnTID, pstrMsg); }
	long  GetTerminalMsg(long lMsgId, short* pnTID, CString* strMsg)
	{
		long lAck = 0;
		BSTR bstMsg = 0;
		lAck = EZGEM_GetTerminalMsg(pGEM, lMsgId, pnTID, &bstMsg);
		if (lAck < 0) return lAck;
		*strMsg = (CString)bstMsg;
		SysFreeString(bstMsg);
		return lAck;
	}
	long  GetTerminalMsg(long lMsgId, short* pnTID, CString& strMsg)
	{
		BSTR bstrMsg = nullptr;
		long nResult = EZGEM_GetTerminalMsg(pGEM, lMsgId, pnTID, &bstrMsg);
		if (nResult < 0) return nResult;
		strMsg = CString(bstrMsg);
		::SysFreeString(bstrMsg);
		return nResult;
	}
	void  SetReportFilePath(const char *pszFilePath) { EZGEM_SetReportFilePath(pGEM, pszFilePath); }
	long  AddStatusValueToMsg(long lMsgId, long SVID) { return EZGEM_AddStatusValueToMsg(pGEM, lMsgId, SVID); }
	long  SetTimeFormat(short nTimeFormat) { return EZGEM_SetTimeFormat(pGEM, nTimeFormat); }
	short SetFormatCode(const char *szItemName, const char *szFormatCode) { return EZGEM_SetFormatCode(pGEM, szItemName, szFormatCode); }
	void  GetSpoolTime(BSTR  *pstrStartTime, BSTR  *pstrFullTime) { EZGEM_GetSpoolTime(pGEM, pstrStartTime, pstrFullTime); }
	void  GetSpoolTime(CString& strStartTime, CString& strFullTime)
	{
		BSTR bstrStartTime = nullptr;
		BSTR bstrFullTime = nullptr;
		EZGEM_GetSpoolTime(pGEM, &bstrStartTime, &bstrFullTime);
		if (bstrStartTime != nullptr)
		{
			strStartTime = CString(bstrStartTime);
			::SysFreeString(bstrStartTime);
		}
		else
		{
			strStartTime.Empty();
		}
		if (bstrFullTime != nullptr)
		{
			strFullTime = CString(bstrFullTime);
			::SysFreeString(bstrFullTime);
		}
		else
		{
			strFullTime.Empty();
		}
	}
	void  GetSpoolTime(CString* pStrStartTime, CString* pStrFullTime)
	{
		BSTR bstrStartTime = nullptr;
		BSTR bstrFullTime = nullptr;
		EZGEM_GetSpoolTime(pGEM, &bstrStartTime, &bstrFullTime);

		if (bstrStartTime != nullptr) 
		{
			if (pStrStartTime) *pStrStartTime = CString(bstrStartTime);
			::SysFreeString(bstrStartTime);
		}
		else 
		{
			if (pStrStartTime) pStrStartTime->Empty();
		}
		if (bstrFullTime != nullptr) 
		{
			if (pStrFullTime) *pStrFullTime = CString(bstrFullTime);
			::SysFreeString(bstrFullTime);
		}
		else 
		{
			if (pStrFullTime) pStrFullTime->Empty();
		}
	}
	long  GetAlarmInfo(long ALID, short  *pnALCD, BSTR  *pstrText) { return EZGEM_GetAlarmInfo(pGEM, ALID, pnALCD, pstrText); }
	long  GetAlarmInfo(long ALID, short *pnALCD, CString* strText)
	{
		long lAck = 0;
		BSTR pstrText = 0;
		lAck = EZGEM_GetAlarmInfo(pGEM, ALID, pnALCD, &pstrText);
		if (lAck < 0) return lAck;
		*strText = (CString)pstrText;
		SysFreeString(pstrText);
		return lAck;
	}
	long  GetAlarmInfo(long ALID, short* pnALCD, CString& strText)
	{
		BSTR bstrText = nullptr;
		long nResult = EZGEM_GetAlarmInfo(pGEM, ALID, pnALCD, &bstrText);
		if (nResult < 0) return nResult;
		strText = CString(bstrText);
		::SysFreeString(bstrText);
		return nResult;
	}
	BSTR  GetAlarmText(long ALID) { return EZGEM_GetAlarmText(pGEM, ALID); }
	short GetAlarmCode(long ALID) { return EZGEM_GetAlarmCode(pGEM, ALID); }
	long  GetAlarmState(long ALID) { return EZGEM_GetAlarmState(pGEM, ALID); }
	void  SetRemoteCommandErrorCode(long lMsgId, LPCTSTR szCommand, short nParamIndex, short nErrorCode) { EZGEM_SetRemoteCommandErrorCode(pGEM, lMsgId, szCommand, nParamIndex, nErrorCode); }
	long  ResetMsgReceived(long lMsgId) { return EZGEM_ResetMsgReceived(pGEM, lMsgId); }
	long  WriteEZGemStatus() { return EZGEM_WriteEZGemStatus(pGEM); }
	long  GetReport(long RPTID, long *plSVID) { return EZGEM_GetReport(pGEM, RPTID, plSVID);}
	long  GetEventReport(long CEID, long *plRPTID) { return EZGEM_GetEventReport(pGEM, CEID, plRPTID); }
	long  GetTraceInfo(long TRID, long *plSampleCount, long *plVidCount, BSTR *pstrVidList, BSTR *pstrPeriod)	{return EZGEM_GetTraceInfo(pGEM, TRID, plSampleCount, plVidCount, pstrVidList, pstrPeriod);}
	long  GetTraceInfo(long TRID, long *plSampleCount, long *plVidCount, CString* pstrVidList, CString* pstrPeriod)
	{
		BSTR bstrVidList = nullptr;
		BSTR bstrPeriod = nullptr;
		long nResult = EZGEM_GetTraceInfo(pGEM, TRID, plSampleCount, plVidCount, &bstrVidList, &bstrPeriod);
		if (nResult < 0) return nResult;
		*pstrVidList = CString(bstrVidList);
		*pstrPeriod = CString(bstrPeriod);
		::SysFreeString(bstrVidList);
		::SysFreeString(bstrPeriod);
		return nResult;
	}
	long  GetTraceInfo(long TRID, long* plSampleCount, long* plVidCount, CString& strVidList, CString& strPeriod)
	{
		BSTR bstrVidList = nullptr;
		BSTR bstrPeriod = nullptr;
		long nResult = EZGEM_GetTraceInfo(pGEM, TRID, plSampleCount, plVidCount, &bstrVidList, &bstrPeriod);
		if (nResult < 0) return nResult;
		if (bstrVidList != nullptr)
		{
			strVidList = CString(bstrVidList);
			::SysFreeString(bstrVidList);
		}
		else
		{
			strVidList.Empty();
		}
		if (bstrPeriod != nullptr)
		{
			strPeriod = CString(bstrPeriod);
			::SysFreeString(bstrPeriod);
		}
		else
		{
			strPeriod.Empty();
		}
		return nResult;
	}
	//----------------------------------------------------------------------------
	//	GEM300 API
	long Set300IniFile(LPCTSTR szFileName) { return EZGEM_Set300IniFile(pGEM, szFileName); }
	//  CMS
	long SetLoadPort(int nPortID, int nTransferState, int nAccessMode, LPCTSTR strLocationName, LPCTSTR strCarrierID) { return EZGEM_SetLoadPort(pGEM, nPortID, nTransferState, nAccessMode, strLocationName, strCarrierID); }
	long SetTransferState(int nPortID, int nTransferState) { return EZGEM_SetTransferState(pGEM, nPortID, nTransferState); }
	long SetCarrierArrived(int nPortID) { return EZGEM_SetCarrierArrived(pGEM, nPortID); }
	long SetCarrierRemoved(int nPortID) { return EZGEM_SetCarrierRemoved(pGEM, nPortID); }
	long SetDoorState(int nPortID, int nState) { return EZGEM_SetDoorState(pGEM, nPortID, nState); }
	long SetDockState(int nPortID, int nState) { return EZGEM_SetDockState(pGEM, nPortID, nState); }
	long SetClampState(int nPortID, int nState) { return EZGEM_SetClampState(pGEM, nPortID, nState); }
	long SetLoadPortAccessMode(int nPortID, int nMode) { return EZGEM_SetLoadPortAccessMode(pGEM, nPortID, nMode); }
	long SetCarrierAccessState(int nPortID, int nState, LPCTSTR strCarrierID) { return EZGEM_SetCarrierAccessState(pGEM, nPortID, nState, strCarrierID); }
	long SetCarrierIDRead(int nPortID, LPCTSTR strCarrierID, int nResult) { return EZGEM_SetCarrierIDRead(pGEM, nPortID, strCarrierID, nResult); }
	long SetCarrierIDStatus(int nPortID, LPCTSTR strCarrierID, int nStatus) { return EZGEM_SetCarrierIDStatus(pGEM, nPortID, strCarrierID, nStatus); }
	long SetSlotMapRead(int nPortID, LPCTSTR strCarrierID, LPCTSTR strSlotMap, int nResult) { return EZGEM_SetSlotMapRead(pGEM, nPortID, strCarrierID, strSlotMap, nResult); }
	long SetSlotMapStatus(int nPortID, LPCTSTR strCarrierID, int nStatus) { return EZGEM_SetSlotMapStatus(pGEM, nPortID, strCarrierID, nStatus); }
	long GetCarrierActionInfo(long lMsgId, int *pnPortID, BSTR *pstrCarrierID, int *pnContentMapCount, int *pnSlotMapCount) { return EZGEM_GetCarrierActionInfo(pGEM, lMsgId, pnPortID, pstrCarrierID, pnContentMapCount, pnSlotMapCount); }
	long GetCarrierActionInfo(long lMsgId, int* pnPortID, CString* pstrCarrierID, int* pnContentMapCount, int* pnSlotMapCount)
	{
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierActionInfo(pGEM, lMsgId, pnPortID, &bstrCarrierID, pnContentMapCount, pnSlotMapCount);
		if (nResult < 0) return nResult;
		*pstrCarrierID = CString(bstrCarrierID);
		SysFreeString(bstrCarrierID);
		return nResult;
	}
	long GetCarrierActionInfo(long lMsgId, int* pnPortID, CString& strCarrierID, int* pnContentMapCount, int* pnSlotMapCount)
	{
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierActionInfo(pGEM, lMsgId, pnPortID, &bstrCarrierID, pnContentMapCount, pnSlotMapCount);
		if (nResult < 0) return nResult;
		strCarrierID = CString(bstrCarrierID);
		SysFreeString(bstrCarrierID);
		return nResult;
	}
	long GetContentMapInfo(long lMsgId, int nIndex, BSTR *pstrContentMap) { return EZGEM_GetContentMapInfo(pGEM, lMsgId, nIndex, pstrContentMap); }
	long GetContentMapInfo(long lMsgId, int nIndex, CString* pstrContentMap)
	{
		BSTR bstrContentMap = nullptr;
		long nResult = EZGEM_GetContentMapInfo(pGEM, lMsgId, nIndex, &bstrContentMap);
		if (nResult < 0) return nResult;
		*pstrContentMap = CString(bstrContentMap);
		SysFreeString(bstrContentMap);
		return nResult;
	}
	long GetContentMapInfo(long lMsgId, int nIndex, CString& strContentMap)
	{
		BSTR bstrContentMap = nullptr;
		long nResult = EZGEM_GetContentMapInfo(pGEM, lMsgId, nIndex, &bstrContentMap);
		if (nResult < 0) return nResult;
		strContentMap = CString(bstrContentMap);
		SysFreeString(bstrContentMap);
		return nResult;
	}
	long GetSlotMapInfo(long lMsgId, BSTR *pstrSlotMap) { return EZGEM_GetSlotMapInfo(pGEM, lMsgId, pstrSlotMap); }
	long GetSlotMapInfo(long lMsgId, CString* pstrSlotMap)
	{
		BSTR bstrSlotMap = nullptr;
		long nResult = EZGEM_GetSlotMapInfo(pGEM, lMsgId, &bstrSlotMap);
		if (nResult < 0) return nResult;
		*pstrSlotMap = CString(bstrSlotMap);
		SysFreeString(bstrSlotMap);
		return nResult;
	}
	long GetSlotMapInfo(long lMsgId, CString& strSlotMap)
	{
		BSTR bstrSlotMap = nullptr;
		long nResult = EZGEM_GetSlotMapInfo(pGEM, lMsgId, &bstrSlotMap);
		if (nResult < 0) return nResult;
		strSlotMap = CString(bstrSlotMap);
		SysFreeString(bstrSlotMap);
		return nResult;
	}
	long GetHostSetLoadPortAccessMode(long lMsgId, int *pnAccessMode, BSTR *pstrPortList) { return EZGEM_GetHostSetLoadPortAccessMode(pGEM,lMsgId,pnAccessMode,pstrPortList); }
	long GetHostSetLoadPortAccessMode(long lMsgId, int* pnAccessMode, CString* pstrPortList)
	{
		BSTR bstrPortList = nullptr;
		long nResult = EZGEM_GetHostSetLoadPortAccessMode(pGEM, lMsgId, pnAccessMode, &bstrPortList);
		if (nResult < 0) return nResult;
		*pstrPortList = CString(bstrPortList);
		SysFreeString(bstrPortList);
		return nResult;
	}
	long GetHostSetLoadPortAccessMode(long lMsgId, int* pnAccessMode, CString& strPortList)
	{
		BSTR bstrPortList = nullptr;
		long nResult = EZGEM_GetHostSetLoadPortAccessMode(pGEM, lMsgId, pnAccessMode, &bstrPortList);
		if (nResult < 0) return nResult;
		strPortList = CString(bstrPortList);
		SysFreeString(bstrPortList);
		return nResult;
	}
	long GetHostSetLoadPortServiceMode(long lMsgId, int *pnServiceMode, BSTR *pstrPortList) { return EZGEM_GetHostSetLoadPortServiceMode(pGEM,lMsgId,pnServiceMode,pstrPortList); }
	long GetHostSetLoadPortServiceMode(long lMsgId, int* pnServiceMode, CString* pstrPortList)
	{
		BSTR bstrPortList = nullptr;
		long nResult = EZGEM_GetHostSetLoadPortServiceMode(pGEM, lMsgId, pnServiceMode, &bstrPortList);
		if (nResult < 0) return nResult;
		*pstrPortList = CString(bstrPortList);
		SysFreeString(bstrPortList);
		return nResult;
	}
	long GetHostSetLoadPortServiceMode(long lMsgId, int* pnServiceMode, CString& strPortList)
	{
		BSTR bstrPortList = nullptr;
		long nResult = EZGEM_GetHostSetLoadPortServiceMode(pGEM, lMsgId, pnServiceMode, &bstrPortList);
		if (nResult < 0) return nResult;
		strPortList = CString(bstrPortList);
		SysFreeString(bstrPortList);
		return nResult;
	}
	long ReplyCarrierAction(long lMsgId, int CAACK) { return EZGEM_ReplyCarrierAction(pGEM, lMsgId, CAACK); }
	long SetCarrierActionErrorCode(long lMsgId, int nErrorCode, LPCTSTR strErrorText) { return EZGEM_SetCarrierActionErrorCode(pGEM, lMsgId, nErrorCode, strErrorText); }
	long DeleteCarrier(LPCTSTR sCarrierID) { return EZGEM_DeleteCarrier(pGEM, sCarrierID); }
	long DeleteAllCarrier() { return EZGEM_DeleteAllCarrier(pGEM); }
	long GetLoadPortInfo(int nPortID, BSTR *psLocID, BSTR *psCarrierID, int *pnAccessMode, int *pnTransferState, int *pnReservState, int *pnAssocState)	{	return EZGEM_GetLoadPortInfo(pGEM,nPortID,psLocID,psCarrierID,pnAccessMode,pnTransferState,pnReservState,pnAssocState);	}
	long GetLoadPortInfo(int nPortID, CString* psLocID, CString* psCarrierID, int* pnAccessMode, int* pnTransferState, int* pnReservState, int* pnAssocState)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetLoadPortInfo(pGEM, nPortID, &bstrLocID, &bstrCarrierID,	pnAccessMode, pnTransferState, pnReservState, pnAssocState);
		if (nResult < 0) return nResult;
		if (psLocID && bstrLocID)
		{
			*psLocID = CString(bstrLocID);
			SysFreeString(bstrLocID);
		}
		else if (psLocID)
		{
			psLocID->Empty();
		}
		if (psCarrierID && bstrCarrierID)
		{
			*psCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else if (psCarrierID)
		{
			psCarrierID->Empty();
		}
		return nResult;
	}
	long GetLoadPortInfo(int nPortID, CString& strLocID,CString& strCarrierID,int* pnAccessMode, int* pnTransferState, int* pnReservState, int* pnAssocState)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetLoadPortInfo(pGEM, nPortID, &bstrLocID, &bstrCarrierID,	pnAccessMode, pnTransferState, pnReservState, pnAssocState);
		if (nResult < 0) return nResult;
		if (bstrLocID)
		{
			strLocID = CString(bstrLocID);
			SysFreeString(bstrLocID);
		}
		else
		{
			strLocID.Empty();
		}
			if (bstrCarrierID)
		{
			strCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else
		{
			strCarrierID.Empty();
		}
		return nResult;
	}
	long GetCarrierInfo(LPCTSTR szCarrierID, BSTR *psLocID, int *pnIDStatus, int *pnSlotMapStatus, int *pnAccessStatus, BSTR *pstrSlotMap, BSTR *psUsage){	return EZGEM_GetCarrierInfo(pGEM,szCarrierID,psLocID,pnIDStatus,pnSlotMapStatus,pnAccessStatus,pstrSlotMap,psUsage);}
	long GetCarrierInfo(LPCTSTR szCarrierID, CString* psLocID,int* pnIDStatus,int* pnSlotMapStatus,int* pnAccessStatus,	CString* pstrSlotMap,CString* psUsage)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrSlotMap = nullptr;
		BSTR bstrUsage = nullptr;
		long nResult = EZGEM_GetCarrierInfo(pGEM, szCarrierID, &bstrLocID, pnIDStatus, pnSlotMapStatus, pnAccessStatus, &bstrSlotMap, &bstrUsage);
		if (nResult < 0) return nResult;
		if (psLocID && bstrLocID)
		{
			*psLocID = CString(bstrLocID);
			SysFreeString(bstrLocID);
		}
		if (pstrSlotMap && bstrSlotMap)
		{
			*pstrSlotMap = CString(bstrSlotMap);
			SysFreeString(bstrSlotMap);
		}
		if (psUsage && bstrUsage)
		{
			*psUsage = CString(bstrUsage);
			SysFreeString(bstrUsage);
		}
		return nResult;
	}
	long GetCarrierInfo(LPCTSTR szCarrierID, CString& strLocID,int* pnIDStatus,int* pnSlotMapStatus,int* pnAccessStatus,CString& strSlotMap,CString& strUsage)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrSlotMap = nullptr;
		BSTR bstrUsage = nullptr;
		long nResult = EZGEM_GetCarrierInfo(pGEM, szCarrierID, &bstrLocID, pnIDStatus,pnSlotMapStatus, pnAccessStatus, &bstrSlotMap, &bstrUsage);
		if (nResult < 0) return nResult;
		if (bstrLocID)
		{
			strLocID = CString(bstrLocID);
			SysFreeString(bstrLocID);
		}
		else
		{
			strLocID.Empty();
		}
		if (bstrSlotMap)
		{
			strSlotMap = CString(bstrSlotMap);
			SysFreeString(bstrSlotMap);
		}
		else
		{
			strSlotMap.Empty();
		}
		if (bstrUsage)
		{
			strUsage = CString(bstrUsage);
			SysFreeString(bstrUsage);
		}
		else
		{
			strUsage.Empty();
		}
		return nResult;
	}
	long GetSlotInfo(LPCTSTR szCarrierID, int nSlotNo, int *pnSlotType, BSTR *psLotID, BSTR *psSubstID){return EZGEM_GetSlotInfo(pGEM,szCarrierID,nSlotNo,pnSlotType,psLotID,psSubstID);}
	long GetSlotInfo(LPCTSTR szCarrierID, int nSlotNo, int* pnSlotType,	CString* psLotID, CString* psSubstID)	
	{
		BSTR bstrLotID = nullptr;
		BSTR bstrSubstID = nullptr;
		long nResult = EZGEM_GetSlotInfo(pGEM, szCarrierID, nSlotNo, pnSlotType, &bstrLotID, &bstrSubstID);
		if (nResult < 0) return nResult;
		if (psLotID && bstrLotID)
		{
			*psLotID = CString(bstrLotID);
			SysFreeString(bstrLotID);
		}
		else if (psLotID)
		{
			psLotID->Empty();
		}
		if (psSubstID && bstrSubstID)
		{
			*psSubstID = CString(bstrSubstID);
			SysFreeString(bstrSubstID);
		}
		else if (psSubstID)
		{
			psSubstID->Empty();
		}
		return nResult;
	}
	long GetSlotInfo(LPCTSTR szCarrierID, int nSlotNo, int* pnSlotType, CString& sLotID,  CString& sSubstID)
	{
		BSTR bstrLotID = nullptr;
		BSTR bstrSubstID = nullptr;
		long nResult = EZGEM_GetSlotInfo(pGEM, szCarrierID, nSlotNo, pnSlotType, &bstrLotID, &bstrSubstID);
		if (nResult < 0) return nResult;
		if (bstrLotID)
		{
			sLotID = CString(bstrLotID);
			SysFreeString(bstrLotID);
		}
		if (bstrSubstID)
		{
			sSubstID = CString(bstrSubstID);
			SysFreeString(bstrSubstID);
		}
		return nResult;
	}
	long CreateCarrierLoc(LPCTSTR szLocationID){	return EZGEM_CreateCarrierLoc(pGEM,szLocationID);	}
	long SetCarrierLocInfo(LPCTSTR szLocationID, LPCTSTR szCarrierID){	return EZGEM_SetCarrierLocInfo(pGEM,szLocationID,szCarrierID);}
	long GetCarrierLocInfo(LPCTSTR szLocationID, BSTR *psCarrierID){	return EZGEM_GetCarrierLocInfo(pGEM,szLocationID,psCarrierID);}
	long GetCarrierLocInfo(LPCTSTR szLocationID, CString* psCarrierID)
	{
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierLocInfo(pGEM, szLocationID, &bstrCarrierID);
		if (nResult < 0) return nResult;
		if (psCarrierID && bstrCarrierID)
		{
			*psCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else if (psCarrierID)
		{
			psCarrierID->Empty();
		}
		return nResult;
	}
	long GetCarrierLocInfo(LPCTSTR szLocationID, CString& strCarrierID)
	{
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierLocInfo(pGEM, szLocationID, &bstrCarrierID);
		if (nResult < 0) return nResult;
		if (bstrCarrierID)
		{
			strCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else
		{
			strCarrierID.Empty();
		}
		return nResult;
	}
	long GetCarrierLocation(LPCTSTR szCarrierID, BSTR *psLocationID){	return EZGEM_GetCarrierLocation(pGEM,szCarrierID,psLocationID);}
	long SetCarrierMove(LPCTSTR szCarrierID, LPCTSTR szLocationID){return EZGEM_SetCarrierMove(pGEM,szCarrierID,szLocationID);}
	long GetCarrierCount(){	return EZGEM_GetCarrierCount(pGEM);}
	long GetCarrierList(long nIndex, BSTR *psCarrierID, BSTR *psLocID){	return EZGEM_GetCarrierList(pGEM,nIndex,psCarrierID,psLocID);}
	long GetCarrierList(long nIndex, CString* psCarrierID, CString* psLocID)
	{
		BSTR bstrCarrierID = nullptr;
		BSTR bstrLocID = nullptr;
		long nResult = EZGEM_GetCarrierList(pGEM, nIndex, &bstrCarrierID, &bstrLocID);
		if (nResult < 0) return nResult;
		if (psCarrierID)
		{
			if (bstrCarrierID)
			{
				*psCarrierID = CString(bstrCarrierID);
				SysFreeString(bstrCarrierID);
			}
			else
			{
				psCarrierID->Empty();
			}
		}
		if (psLocID)
		{
			if (bstrLocID)
			{
				*psLocID = CString(bstrLocID);
				SysFreeString(bstrLocID);
			}
			else
			{
				psLocID->Empty();
			}
		}
		return nResult;
	}
	long GetCarrierList(long nIndex, CString& strCarrierID, CString& strLocID)
	{
		BSTR bstrCarrierID = nullptr;
		BSTR bstrLocID = nullptr;
		long nResult = EZGEM_GetCarrierList(pGEM, nIndex, &bstrCarrierID, &bstrLocID);
		if (nResult < 0) return nResult;
		if (bstrCarrierID)
		{
			strCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else
		{
			strCarrierID.Empty();
		}
		if (bstrLocID)
		{
			strLocID = CString(bstrLocID);
			SysFreeString(bstrLocID);
		}
		else
		{
			strLocID.Empty();
		}
		return nResult;
	}
	long GetCarrierLocCount(){return EZGEM_GetCarrierLocCount(pGEM);}
	long GetCarrierLocList(long nIndex, BSTR *psLocationID, BSTR *psCarrierID){	return EZGEM_GetCarrierLocList(pGEM,nIndex,psLocationID,psCarrierID);}
	long GetCarrierLocList(long nIndex, CString* psLocationID, CString* psCarrierID)
	{
		BSTR bstrLocationID = nullptr;
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierLocList(pGEM, nIndex, &bstrLocationID, &bstrCarrierID);
		if (nResult < 0) return nResult;
		if (psLocationID)
		{
			if (bstrLocationID)
			{
				*psLocationID = CString(bstrLocationID);
				SysFreeString(bstrLocationID);
			}
			else
			{
				psLocationID->Empty();
			}
		}
		if (psCarrierID)
		{
			if (bstrCarrierID)
			{
				*psCarrierID = CString(bstrCarrierID);
				SysFreeString(bstrCarrierID);
			}
			else
			{
				psCarrierID->Empty();
			}
		}
		return nResult;
	}
	long GetCarrierLocList(long nIndex, CString& strLocationID, CString& strCarrierID)
	{
		BSTR bstrLocationID = nullptr;
		BSTR bstrCarrierID = nullptr;
		long nResult = EZGEM_GetCarrierLocList(pGEM, nIndex, &bstrLocationID, &bstrCarrierID);
		if (nResult < 0) return nResult;
		if (bstrLocationID)
		{
			strLocationID = CString(bstrLocationID);
			SysFreeString(bstrLocationID);
		}
		else
		{
			strLocationID.Empty();
		}
		if (bstrCarrierID)
		{
			strCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else
		{
			strCarrierID.Empty();
		}
		return nResult;
	}
	long SetCarrierInternalBufferMode(int nMode){	return EZGEM_SetCarrierInternalBufferMode(pGEM,nMode);}

	// PJM
	long GetHostSetPrJobCount(long lMsgId) { return EZGEM_GetHostSetPrJobCount(pGEM, lMsgId); }
	long GetHostSetPrJob(long lMsgId, int nIndex, BSTR *pstrPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount)	{		return EZGEM_GetHostSetPrJob(pGEM, lMsgId, nIndex, pstrPrJobID, pstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);	}
	long GetHostSetPrJob(long lMsgId, int nIndex, CString* pstrPrJobID, CString* pstrPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetHostSetPrJob(pGEM, lMsgId, nIndex, &bstrPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (pstrPrJobID)
		{
			if (bstrPrJobID)
			{
				*pstrPrJobID = CString(bstrPrJobID);
				SysFreeString(bstrPrJobID);
			}
			else
			{
				pstrPrJobID->Empty();
			}
		}
		if (pstrPPID)
		{
			if (bstrPPID)
			{
				*pstrPPID = CString(bstrPPID);
				SysFreeString(bstrPPID);
			}
			else
			{
				pstrPPID->Empty();
			}
		}
		return nResult;
	}
	long GetHostSetPrJob(long lMsgId, int nIndex, CString& strPrJobID, CString& strPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetHostSetPrJob(pGEM, lMsgId, nIndex, &bstrPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (bstrPrJobID)
		{
			strPrJobID = CString(bstrPrJobID);
			SysFreeString(bstrPrJobID);
		}
		else
		{
			strPrJobID.Empty();
		}
		if (bstrPPID)
		{
			strPPID = CString(bstrPPID);
			SysFreeString(bstrPPID);
		}
		else
		{
			strPPID.Empty();
		}
		return nResult;
	}
	long GetHostSetPrJobStartMethod(long lMsgId, int *pnPrJobCount, BSTR *pstrPrJobList, int *pnStartMethod)	{		return EZGEM_GetHostSetPrJobStartMethod(pGEM,lMsgId,pnPrJobCount,pstrPrJobList,pnStartMethod);	}
	long GetHostSetPrJobStartMethod(long lMsgId, int* pnPrJobCount, CString* pstrPrJobList, int* pnStartMethod) 
	{
		BSTR bstrPrJobList = nullptr;
		long lRet = EZGEM_GetHostSetPrJobStartMethod(pGEM, lMsgId, pnPrJobCount, &bstrPrJobList, pnStartMethod);
		if (SUCCEEDED(lRet) && bstrPrJobList != nullptr) 
		{
			*pstrPrJobList = CString(bstrPrJobList);
			::SysFreeString(bstrPrJobList);
		}
		else 
		{
			pstrPrJobList->Empty();
		}
		return lRet;
	}
	long GetHostSetPrJobStartMethod(long lMsgId, int* pnPrJobCount, CString& strPrJobList, int* pnStartMethod) 
	{
		BSTR bstrPrJobList = nullptr;
		long lRet = EZGEM_GetHostSetPrJobStartMethod(pGEM, lMsgId, pnPrJobCount, &bstrPrJobList, pnStartMethod);
		if (SUCCEEDED(lRet) && bstrPrJobList != nullptr) 
		{
			strPrJobList = CString(bstrPrJobList);
			::SysFreeString(bstrPrJobList);
		}
		else 
		{
			strPrJobList.Empty();
		}
		return lRet;
	}

	long GetHostSetPrJobParam(long lMsgId, BSTR *pstrPrJob, int *pnParamCount){		return EZGEM_GetHostSetPrJobParam(pGEM, lMsgId, pstrPrJob, pnParamCount);	}
	long GetHostSetPrJobParam(long lMsgId, CString* pstrPrJob, int* pnParamCount)
	{
		BSTR bstrPrJob = nullptr;
		long nResult = EZGEM_GetHostSetPrJobParam(pGEM, lMsgId, &bstrPrJob, pnParamCount);
		if (nResult < 0) return nResult;
		if (pstrPrJob)
		{
			if (bstrPrJob)
			{
				*pstrPrJob = CString(bstrPrJob);
				SysFreeString(bstrPrJob);
			}
			else
			{
				pstrPrJob->Empty();
			}
		}
		return nResult;
	}
	long GetHostSetPrJobParam(long lMsgId, CString& strPrJob, int* pnParamCount)
	{
		BSTR bstrPrJob = nullptr;
		long nResult = EZGEM_GetHostSetPrJobParam(pGEM, lMsgId, &bstrPrJob, pnParamCount);
		if (nResult < 0) return nResult;
		if (bstrPrJob)
		{
			strPrJob = CString(bstrPrJob);
			SysFreeString(bstrPrJob);
		}
		else
		{
			strPrJob.Empty();
		}
		return nResult;
	}
	long GetPrJobCarrier(LPCTSTR szPrJobID, int nIndex, BSTR *pstrCarrierID, BSTR *pstrSlotList)	{		return EZGEM_GetPrJobCarrier(pGEM, szPrJobID, nIndex, pstrCarrierID, pstrSlotList);	}
	long GetPrJobCarrier(LPCTSTR szPrJobID, int nIndex, CString* pstrCarrierID, CString* pstrSlotList)
	{
		BSTR bstrCarrierID = nullptr;
		BSTR bstrSlotList = nullptr;
		long nResult = EZGEM_GetPrJobCarrier(pGEM, szPrJobID, nIndex, &bstrCarrierID, &bstrSlotList);
		if (nResult < 0) return nResult;
		if (pstrCarrierID)
		{
			if (bstrCarrierID)
			{
				*pstrCarrierID = CString(bstrCarrierID);
				SysFreeString(bstrCarrierID);
			}
			else
			{
				pstrCarrierID->Empty();
			}
		}
		if (pstrSlotList)
		{
			if (bstrSlotList)
			{
				*pstrSlotList = CString(bstrSlotList);
				SysFreeString(bstrSlotList);
			}
			else
			{
				pstrSlotList->Empty();
			}
		}
		return nResult;
	}
	long GetPrJobCarrier(LPCTSTR szPrJobID, int nIndex, CString& strCarrierID, CString& strSlotList)
	{
		BSTR bstrCarrierID = nullptr;
		BSTR bstrSlotList = nullptr;
		long nResult = EZGEM_GetPrJobCarrier(pGEM, szPrJobID, nIndex, &bstrCarrierID, &bstrSlotList);
		if (nResult < 0) return nResult;
		if (bstrCarrierID)
		{
			strCarrierID = CString(bstrCarrierID);
			SysFreeString(bstrCarrierID);
		}
		else
		{
			strCarrierID.Empty();
		}
		if (bstrSlotList)
		{
			strSlotList = CString(bstrSlotList);
			SysFreeString(bstrSlotList);
		}
		else
		{
			strSlotList.Empty();
		}
		return nResult;
	}
	long GetPrJobParam(LPCTSTR szPrJobID, int nIndex, BSTR *pstrParamName, BSTR *pstrParamVal) { 	return EZGEM_GetPrJobParam(pGEM, szPrJobID, nIndex, pstrParamName, pstrParamVal); 	}
	long GetPrJobParam(LPCTSTR szPrJobID, int nIndex, CString* pstrParamName, CString* pstrParamVal)
	{
		BSTR bstrParamName = nullptr;
		BSTR bstrParamVal = nullptr;
		long nResult = EZGEM_GetPrJobParam(pGEM, szPrJobID, nIndex, &bstrParamName, &bstrParamVal);
		if (nResult < 0) return nResult;
		if (pstrParamName)
		{
			if (bstrParamName)
			{
				*pstrParamName = CString(bstrParamName);
				SysFreeString(bstrParamName);
			}
			else
			{
				pstrParamName->Empty();
			}
		}
		if (pstrParamVal)
		{
			if (bstrParamVal)
			{
				*pstrParamVal = CString(bstrParamVal);
				SysFreeString(bstrParamVal);
			}
			else
			{
				pstrParamVal->Empty();
			}
		}
		return nResult;
	}
	long GetPrJobParam(LPCTSTR szPrJobID, int nIndex, CString& strParamName,  CString& strParamVal)
	{
		BSTR bstrParamName = nullptr;
		BSTR bstrParamVal = nullptr;
		long nResult = EZGEM_GetPrJobParam(pGEM, szPrJobID, nIndex, &bstrParamName, &bstrParamVal);
		if (nResult < 0) return nResult;
		if (bstrParamName)
		{
			strParamName = CString(bstrParamName);
			SysFreeString(bstrParamName);
		}
		else
		{
			strParamName.Empty();
		}
		if (bstrParamVal)
		{
			strParamVal = CString(bstrParamVal);
			SysFreeString(bstrParamVal);
		}
		else
		{
			strParamVal.Empty();
		}
		return nResult;
	}
	long GetPrJobRecipeMethod(LPCTSTR szPrJobID, int *pnRecipeMethod) { return EZGEM_GetPrJobRecipeMethod(pGEM, szPrJobID, pnRecipeMethod); }
	long GetPrJobCommand(long lMsgId, BSTR *pstrPrJobID, BSTR *pstrCommand) { return EZGEM_GetPrJobCommand(pGEM, lMsgId, pstrPrJobID, pstrCommand); }
	long GetPrJobCommand(long lMsgId, CString* pstrPrJobID, CString* pstrCommand)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrCommand = nullptr;
		long nResult = EZGEM_GetPrJobCommand(pGEM, lMsgId, &bstrPrJobID, &bstrCommand);		
		if (nResult < 0) return nResult;
		if (pstrPrJobID)
		{
			if (bstrPrJobID)
			{
				*pstrPrJobID = CString(bstrPrJobID);
				SysFreeString(bstrPrJobID);
			}
			else
			{
				pstrPrJobID->Empty();
			}
		}
		if (pstrCommand)
		{
			if (bstrCommand)
			{
				*pstrCommand = CString(bstrCommand);
				SysFreeString(bstrCommand);
			}
			else
			{
				pstrCommand->Empty();
			}
		}
		return nResult;
	}
	long GetPrJobCommand(long lMsgId, CString& strPrJobID,  CString& strCommand)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrCommand = nullptr;
		long nResult = EZGEM_GetPrJobCommand(pGEM, lMsgId, &bstrPrJobID, &bstrCommand);
		if (nResult < 0) return nResult;
		if (bstrPrJobID)
		{
			strPrJobID = CString(bstrPrJobID);
			SysFreeString(bstrPrJobID);
		}
		else
		{
			strPrJobID.Empty();
		}
		if (bstrCommand)
		{
			strCommand = CString(bstrCommand);
			SysFreeString(bstrCommand);
		}
		else
		{
			strCommand.Empty();
		}
		return nResult;
	}
	long SetPrJobErrorCode(long lMsgId, LPCTSTR szPrJobID, int nErrorCode, LPCTSTR szErrorText)	{	return EZGEM_SetPrJobErrorCode(pGEM, lMsgId, szPrJobID, nErrorCode, szErrorText);	}
	long ReplyHostSetPrJob(long lMsgId)	{	return EZGEM_ReplyHostSetPrJob(pGEM, lMsgId);}
	long ReplyPrJobCommand(long lMsgId) {	return EZGEM_ReplyPrJobCommand(pGEM, lMsgId);}
	long GetPrJobCount() { return EZGEM_GetPrJobCount(pGEM); }
	long GetPrJobSpace() { return EZGEM_GetPrJobSpace(pGEM); }
	long GetPrJob(long nIndex, BSTR *pstrPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount)	{	return EZGEM_GetPrJob(pGEM, nIndex, pstrPrJobID, pstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);	}
	long GetPrJob(long nIndex, CString* pstrPrJobID, CString* pstrPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetPrJob(pGEM, nIndex, &bstrPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (pstrPrJobID)
		{
			if (bstrPrJobID)
			{
				*pstrPrJobID = CString(bstrPrJobID);
				SysFreeString(bstrPrJobID);
			}
			else
			{
				pstrPrJobID->Empty();
			}
		}
		if (pstrPPID)
		{
			if (bstrPPID)
			{
				*pstrPPID = CString(bstrPPID);
				SysFreeString(bstrPPID);
			}
			else
			{
				pstrPPID->Empty();
			}
		}
		return nResult;
	}
	long GetPrJob(long nIndex, CString& strPrJobID, CString& strPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPrJobID = nullptr;
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetPrJob(pGEM, nIndex, &bstrPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (bstrPrJobID)
		{
			strPrJobID = CString(bstrPrJobID);
			SysFreeString(bstrPrJobID);
		}
		else
		{
			strPrJobID.Empty();
		}
		if (bstrPPID)
		{
			strPPID = CString(bstrPPID);
			SysFreeString(bstrPPID);
		}
		else
		{
			strPPID.Empty();
		}
		return nResult;
	}
	long GetPrJobInfo(LPCTSTR szPrJobID, BSTR *pstrPPID, int *pnCarrierCount, int *pnAutoStart, int *pnParamCount)	{	return EZGEM_GetPrJobInfo(pGEM, szPrJobID, pstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);	}
	long GetPrJobInfo(LPCTSTR szPrJobID, CString* pstrPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetPrJobInfo(pGEM, szPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (pstrPPID)
		{
			if (bstrPPID)
			{
				*pstrPPID = CString(bstrPPID);
				SysFreeString(bstrPPID);
			}
			else
			{
				pstrPPID->Empty();
			}
		}
		return nResult;
	}
	long GetPrJobInfo(LPCTSTR szPrJobID, CString& strPPID, int* pnCarrierCount, int* pnAutoStart, int* pnParamCount)
	{
		BSTR bstrPPID = nullptr;
		long nResult = EZGEM_GetPrJobInfo(pGEM, szPrJobID, &bstrPPID, pnCarrierCount, pnAutoStart, pnParamCount);
		if (nResult < 0) return nResult;
		if (bstrPPID)
		{
			strPPID = CString(bstrPPID);
			SysFreeString(bstrPPID);
		}
		else
		{
			strPPID.Empty();
		}
		return nResult;
	}
	long GetPrJobDeleted(BSTR *pstrPrJobID) { return EZGEM_GetPrJobDeleted(pGEM, pstrPrJobID); }
	long GetPrJobDeleted(CString* pstrPrJobID) 
	{
		BSTR bstrPrJobID = nullptr;
		long nResult = EZGEM_GetPrJobDeleted(pGEM, &bstrPrJobID);
		if (nResult < 0) return nResult;
		if (pstrPrJobID) 
		{
			if (bstrPrJobID) 
			{
				*pstrPrJobID = CString(bstrPrJobID);
				SysFreeString(bstrPrJobID);
			}
			else 
			{
				pstrPrJobID->Empty();
			}
		}
		return nResult;
	}
	long GetPrJobDeleted(CString& strPrJobID) 
	{
		BSTR bstrPrJobID = nullptr;
		long nResult = EZGEM_GetPrJobDeleted(pGEM, &bstrPrJobID);
		if (nResult < 0) return nResult;
		if (bstrPrJobID) 
		{
			strPrJobID = CString(bstrPrJobID);
			SysFreeString(bstrPrJobID);
		}
		else 
		{
			strPrJobID.Empty();
		}
		return nResult;
	}
	long DeletePrJob(LPCTSTR szPrJobID)	{	return EZGEM_DeletePrJob(pGEM, szPrJobID);	}
	long DeleteAllPrJob()	{	return EZGEM_DeleteAllPrJob(pGEM);	}
	long GetPrJobState(LPCTSTR szPrJobID, int *pnPrJobState)	{ return EZGEM_GetPrJobState(pGEM, szPrJobID, pnPrJobState);	}
	long SetPrJobState(LPCTSTR szPrJobID, int nPrJobState)	{	return EZGEM_SetPrJobState(pGEM, szPrJobID, nPrJobState);	}
	long CreatePrJob(LPCTSTR sPrJobID, int nAutoStart, LPCTSTR sCarrierList, LPCTSTR sSlotList, LPCTSTR sPPID)	{		return EZGEM_CreatePrJob(pGEM, sPrJobID, nAutoStart, sCarrierList, sSlotList, sPPID);	}
	long CreatePrJob(LPCTSTR sPrJobID, int nAutoStart, LPCTSTR sSubstrateList, LPCTSTR sPPID)	{		return EZGEM_CreatePrJobSubst(pGEM, sPrJobID, nAutoStart, sSubstrateList, sPPID);	}
	long GetPrJobMaterialFormatCode(LPCTSTR sPrJobID) { return EZGEM_GetPrJobMaterialFormatCode(pGEM, sPrJobID); }
	long AddPrJobParam(LPCTSTR sPrJobID, LPCTSTR sParamName, LPCTSTR sParamVal) { return EZGEM_AddPrJobParam(pGEM,sPrJobID,sParamName,sParamVal); }
	// CJM
	long GetHostSetCtrlJob(long lMsgId, BSTR *pstrCtrlJobID, int *pnPrJobCount, int *pnAutoStart)	{	return EZGEM_GetHostSetCtrlJob(pGEM, lMsgId, pstrCtrlJobID, pnPrJobCount, pnAutoStart);	}
	long GetHostSetCtrlJob(long lMsgId, CString* pstrCtrlJobID, int* pnPrJobCount, int* pnAutoStart)
	{
		BSTR bstrCtrlJobID = nullptr;
		long lResult = EZGEM_GetHostSetCtrlJob(pGEM, lMsgId, &bstrCtrlJobID, pnPrJobCount, pnAutoStart);
		if (lResult < 0) return lResult;
		*pstrCtrlJobID = CString(bstrCtrlJobID);
		::SysFreeString(bstrCtrlJobID);
		return lResult;
	}
	long GetHostSetCtrlJob(long lMsgId, CString& strCtrlJobID, int* pnPrJobCount, int* pnAutoStart)
	{
		BSTR bstrCtrlJobID = nullptr;
		long lResult = EZGEM_GetHostSetCtrlJob(pGEM, lMsgId, &bstrCtrlJobID, pnPrJobCount, pnAutoStart);
		if (lResult < 0) return lResult;
		strCtrlJobID = CString(bstrCtrlJobID);
		::SysFreeString(bstrCtrlJobID);
		return lResult;
	}
	long GetCtrlJob(long nIndex, BSTR *pstrCtrlJobID, int *pnPrJobCount, int *pnAutoStart)	{	return EZGEM_GetCtrlJob(pGEM, nIndex, pstrCtrlJobID, pnPrJobCount, pnAutoStart);	}
	long GetCtrlJob(long nIndex, CString* pstrCtrlJobID, int* pnPrJobCount, int* pnAutoStart)
	{
		BSTR bstrCtrlJobID = nullptr;
		long lResult = EZGEM_GetCtrlJob(pGEM, nIndex, &bstrCtrlJobID, pnPrJobCount, pnAutoStart);
		if (lResult < 0) return lResult;
		*pstrCtrlJobID = CString(bstrCtrlJobID);
		::SysFreeString(bstrCtrlJobID);
		return lResult;
	}
	long GetCtrlJob(long nIndex, CString& strCtrlJobID, int* pnPrJobCount, int* pnAutoStart)
	{
		BSTR bstrCtrlJobID = nullptr;
		long lResult = EZGEM_GetCtrlJob(pGEM, nIndex, &bstrCtrlJobID, pnPrJobCount, pnAutoStart);
		if (lResult < 0) return lResult;
		strCtrlJobID = CString(bstrCtrlJobID);
		::SysFreeString(bstrCtrlJobID);
		return lResult;
	}
	long GetCtrlJobInfo(LPCTSTR szCtrlJobID, int *pnPrJobCount, int *pnAutoStart)	{	return EZGEM_GetCtrlJobInfo(pGEM, szCtrlJobID, pnPrJobCount, pnAutoStart);	}
	long GetCtrlJobMtrlOutMapCount(LPCTSTR szCtrlJobID, int *pnMtrlOutMapCount)	{		return EZGEM_GetCtrlJobMtrlOutMapCount(pGEM, szCtrlJobID, pnMtrlOutMapCount);	}
	long GetCtrlJobMtrlOutInfo(LPCTSTR szCtrlJobID, int nMapIndex, BSTR *pstrSrcCarrier, BSTR *pstrSrcSlotList, BSTR *pstrDestCarrier, BSTR *pstrDestSlotList)	{		return EZGEM_GetCtrlJobMtrlOutInfo(pGEM, szCtrlJobID, nMapIndex, pstrSrcCarrier, pstrSrcSlotList, pstrDestCarrier, pstrDestSlotList);	}
	long GetCtrlJobMtrlOutInfo(LPCTSTR szCtrlJobID, int nMapIndex, CString* pstrSrcCarrier, CString* pstrSrcSlotList, CString* pstrDestCarrier, CString* pstrDestSlotList)
	{
		BSTR bstrSrcCarrier = nullptr;
		BSTR bstrSrcSlotList = nullptr;
		BSTR bstrDestCarrier = nullptr;
		BSTR bstrDestSlotList = nullptr;
		long lResult = EZGEM_GetCtrlJobMtrlOutInfo(pGEM, szCtrlJobID, nMapIndex, &bstrSrcCarrier, &bstrSrcSlotList, &bstrDestCarrier, &bstrDestSlotList);
		if (lResult < 0) return lResult;
		if (bstrSrcCarrier)
		{
			*pstrSrcCarrier = CString(bstrSrcCarrier);
			::SysFreeString(bstrSrcCarrier);
		}
		if (bstrSrcSlotList)
		{
			*pstrSrcSlotList = CString(bstrSrcSlotList);
			::SysFreeString(bstrSrcSlotList);
		}
		if (bstrDestCarrier)
		{
			*pstrDestCarrier = CString(bstrDestCarrier);
			::SysFreeString(bstrDestCarrier);
		}
		if (bstrDestSlotList)
		{
			*pstrDestSlotList = CString(bstrDestSlotList);
			::SysFreeString(bstrDestSlotList);
		}
		return lResult;
	}
	long GetCtrlJobMtrlOutInfo(LPCTSTR szCtrlJobID,	int nMapIndex, CString& strSrcCarrier, 	CString& strSrcSlotList,  CString& strDestCarrier,	CString& strDestSlotList)
	{
		BSTR bstrSrcCarrier = nullptr;
		BSTR bstrSrcSlotList = nullptr;
		BSTR bstrDestCarrier = nullptr;
		BSTR bstrDestSlotList = nullptr;
		long lResult = EZGEM_GetCtrlJobMtrlOutInfo(pGEM,szCtrlJobID,nMapIndex,&bstrSrcCarrier,&bstrSrcSlotList,&bstrDestCarrier,&bstrDestSlotList);
		if (lResult < 0) return lResult;
		if (bstrSrcCarrier)
		{
			strSrcCarrier = CString(bstrSrcCarrier);
			::SysFreeString(bstrSrcCarrier);
		}
		if (bstrSrcSlotList)
		{
			strSrcSlotList = CString(bstrSrcSlotList);
			::SysFreeString(bstrSrcSlotList);
		}
		if (bstrDestCarrier)
		{
			strDestCarrier = CString(bstrDestCarrier);
			::SysFreeString(bstrDestCarrier);
		}
		if (bstrDestSlotList)
		{
			strDestSlotList = CString(bstrDestSlotList);
			::SysFreeString(bstrDestSlotList);
		}
		return lResult;
	}
	long GetPrJobInCtrlJob(LPCTSTR szCtrlJobID, int nIndex, BSTR *pstrPrJobID)	{	return EZGEM_GetPrJobInCtrlJob(pGEM, szCtrlJobID, nIndex, pstrPrJobID);	}
	long GetPrJobInCtrlJob(LPCTSTR szCtrlJobID, int nIndex, CString* pstrPrJobID)
	{
		BSTR bstrPrJobID = nullptr;
		long lResult = EZGEM_GetPrJobInCtrlJob(pGEM, szCtrlJobID, nIndex, &bstrPrJobID);
		if (lResult < 0) return lResult;
		*pstrPrJobID = CString(bstrPrJobID);
		::SysFreeString(bstrPrJobID);
		return lResult;
	}
	long GetPrJobInCtrlJob(LPCTSTR szCtrlJobID, int nIndex, CString& strPrJobID)
	{
		BSTR bstrPrJobID = nullptr;
		long lResult = EZGEM_GetPrJobInCtrlJob(pGEM, szCtrlJobID, nIndex, &bstrPrJobID);
		if (lResult < 0) return lResult;
		strPrJobID = CString(bstrPrJobID);
		::SysFreeString(bstrPrJobID);
		return lResult;
	}
	long GetCtrlJobCount()	{	return EZGEM_GetCtrlJobCount(pGEM);	}
	long GetCtrlJobSpace()	{	return EZGEM_GetCtrlJobSpace(pGEM);	}
	long GetCtrlJobCommand(long lMsgId, BSTR *pstrCJobID, int *pnCommand) { return EZGEM_GetCtrlJobCommand(pGEM, lMsgId, pstrCJobID, pnCommand); }
	long GetCtrlJobCommand(long lMsgId, CString* pstrCJobID, int* pnCommand)
	{
		BSTR bstrCJobID = nullptr;
		long lResult = EZGEM_GetCtrlJobCommand(pGEM, lMsgId, &bstrCJobID, pnCommand);
		if (lResult < 0) return lResult;
		*pstrCJobID = CString(bstrCJobID);
		::SysFreeString(bstrCJobID);
		return lResult;
	}
	long GetCtrlJobCommand(long lMsgId, CString& strCJobID, int* pnCommand)
	{
		BSTR bstrCJobID = nullptr;
		long lResult = EZGEM_GetCtrlJobCommand(pGEM, lMsgId, &bstrCJobID, pnCommand);
		if (lResult < 0) return lResult;
		strCJobID = CString(bstrCJobID);
		::SysFreeString(bstrCJobID);
		return lResult;
	}
	long GetCtrlJobDeleted(BSTR *pstrCJobID) { return EZGEM_GetCtrlJobDeleted(pGEM, pstrCJobID); }
	long GetCtrlJobDeleted(CString* pstrCJobID)
	{
		BSTR bstrCJobID = nullptr;
		long lResult = EZGEM_GetCtrlJobDeleted(pGEM, &bstrCJobID);
		if (lResult < 0) return lResult;
		*pstrCJobID = CString(bstrCJobID);
		::SysFreeString(bstrCJobID);
		return lResult;
	}
	long GetCtrlJobDeleted(CString& strCJobID)
	{
		BSTR bstrCJobID = nullptr;
		long lResult = EZGEM_GetCtrlJobDeleted(pGEM, &bstrCJobID);
		if (lResult < 0) return lResult;
		strCJobID = CString(bstrCJobID);
		::SysFreeString(bstrCJobID);
		return lResult;
	}
	long ReplyCtrlJob(long lMsgId)	{	return EZGEM_ReplyCtrlJob(pGEM, lMsgId);	}
	long ReplyCtrlJobCommand(long lMsgId) { return EZGEM_ReplyCtrlJobCommand(pGEM, lMsgId); }
	long SetCtrlJobErrorCode(long lMsgId, int nErrorCode, LPCTSTR szErrorText)	{	return EZGEM_SetCtrlJobErrorCode(pGEM, lMsgId, nErrorCode, szErrorText);	}
	long DeleteCtrlJob(LPCTSTR szCtrlJobID)	{	return EZGEM_DeleteCtrlJob(pGEM, szCtrlJobID);	}
	long DeleteAllCtrlJob()	{	return EZGEM_DeleteAllCtrlJob(pGEM);	}
	long SetCtrlJobState(LPCTSTR szCtrlJobID, int nState)	{	return EZGEM_SetCtrlJobState(pGEM, szCtrlJobID, nState);	}
	long GetCtrlJobState(LPCTSTR szCtrlJobID, int *pnState)	{	return EZGEM_GetCtrlJobState(pGEM, szCtrlJobID, pnState);	}
	long CreateCtrlJob(LPCTSTR sCtrlJobID, LPCTSTR sPrJobList, int nAutoStat)	{		return EZGEM_CreateCtrlJob(pGEM,sCtrlJobID,sPrJobList,nAutoStat);	}
	long AddCtrlJobCarrierInputSpec(LPCTSTR szCtrlJobID, LPCTSTR szCarrierID)	{		return EZGEM_AddCtrlJobCarrierInputSpec(pGEM, szCtrlJobID, szCarrierID);	}
	long AddCtrlJobMtrlOutSpec(LPCTSTR szCtrlJobID, LPCTSTR szSrcCarrierID, LPCTSTR szSrcSlotList, LPCTSTR szDestCarrierID, LPCTSTR szDestSlotList)	{		return EZGEM_AddCtrlJobMtrlOutSpec(pGEM, szCtrlJobID, szSrcCarrierID, szSrcSlotList, szDestCarrierID, szDestSlotList);	}
	long GetCtrlJobCarrierInputSpec(LPCTSTR szCtrlJobID, BSTR *bstrCarrerList)	{		return EZGEM_GetCtrlJobCarrierInputSpec(pGEM, szCtrlJobID, bstrCarrerList);	}
	long GetCtrlJobCarrierInputSpec(LPCTSTR szCtrlJobID, CStringArray *pCarrerList)
	{		
		BSTR bstrCarrierList;
		long nResult = EZGEM_GetCtrlJobCarrierInputSpec(pGEM, szCtrlJobID, &bstrCarrierList);
		if (nResult < 0) return nResult;
		CString strCarrierList(bstrCarrierList);// BSTR -> CString
		SysFreeString(bstrCarrierList);
#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strCarrierList);
		std::wstring token;
		while (std::getline(ssValue, token, L',')) 
		{
			pCarrerList->Add(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strCarrierList);
		std::string token;
		while (std::getline(ssValue, token, ',')) 
		{
			pCarrerList->Add(token.c_str());
		}
#endif
		if (pCarrerList->GetSize() == nResult - 1) 
		{
			pCarrerList->Add(_T(""));  // 마지막 공백 처리
		}
		return nResult;
	}
	long GetCtrlJobCarrierInputSpec(LPCTSTR szCtrlJobID, CStringArray& carrerList)
	{
		BSTR bstrCarrierList;
		long nResult = EZGEM_GetCtrlJobCarrierInputSpec(pGEM, szCtrlJobID, &bstrCarrierList);
		if (nResult < 0) return nResult;
		CString strCarrierList(bstrCarrierList); // BSTR -> CString
		SysFreeString(bstrCarrierList);
#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strCarrierList);
		std::wstring token;
		while (std::getline(ssValue, token, L','))
		{
			carrerList.Add(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strCarrierList);
		std::string token;
		while (std::getline(ssValue, token, ','))
		{
			carrerList.Add(token.c_str());
		}
#endif
		if (carrerList.GetSize() == nResult - 1)
		{
			carrerList.Add(_T(""));  // 마지막 공백 처리
		}

		return nResult;
	}
	long GetCtrlJobCarrierInputSpec(LPCTSTR szCtrlJobID, std::vector<CString>& carrierList)
	{
		BSTR bstrCarrierList = nullptr;
		long nResult = EZGEM_GetCtrlJobCarrierInputSpec(pGEM, szCtrlJobID, &bstrCarrierList);
		if (nResult < 0) return nResult;

		CString strCarrierList(bstrCarrierList); // BSTR -> CString
		SysFreeString(bstrCarrierList);

#if defined(_UNICODE)
		std::wstringstream ssValue((LPCTSTR)strCarrierList);
		std::wstring token;
		while (std::getline(ssValue, token, L','))
		{
			carrierList.emplace_back(token.c_str());
		}
#else
		std::stringstream ssValue((LPCTSTR)strCarrierList);
		std::string token;
		while (std::getline(ssValue, token, ','))
		{
			carrierList.emplace_back(token.c_str());
		}
#endif
		if ((int)carrierList.size() == nResult - 1)
		{
			carrierList.emplace_back(_T(""));  // 마지막 공백 처리
		}
		return nResult;
	}
	// STS
	long CreateSubstLoc(LPCTSTR sLocID)	{		return EZGEM_CreateSubstLoc(pGEM, sLocID);	}
	long CreateSubstBatchLoc(LPCTSTR sBatchLocID)	{		return EZGEM_CreateSubstBatchLoc(pGEM, sBatchLocID);	}
	long CreateSubstrate(LPCTSTR sSubstID)	{		return EZGEM_CreateSubstrate(pGEM, sSubstID);	}
	long SetSubstLocInfo(LPCTSTR sLocID, LPCTSTR sSubstID)	{		return EZGEM_SetSubstLocInfo(pGEM, sLocID, sSubstID);	}
	long SetSubstBatchLocInfo(LPCTSTR sBatchLocID, int nPosInBatch, LPCTSTR sSubstID)	{		return EZGEM_SetSubstBatchLocInfo(pGEM, sBatchLocID, nPosInBatch, sSubstID);	}
	long GetSubstLocCount()	{		return EZGEM_GetSubstLocCount(pGEM);	}
	long GetSubstBatchLocCount()	{		return EZGEM_GetSubstBatchLocCount(pGEM);	}
	long GetSubstrateCount()	{		return	EZGEM_GetSubstrateCount(pGEM);	}
	long GetSubstrate(long nIndex, BSTR *psSubstID, BSTR *psCurrentLoc)	{		return EZGEM_GetSubstrate(pGEM, nIndex, psSubstID, psCurrentLoc);	}
	long GetSubstrate(long nIndex, CString* pSubstID, CString* pCurrentLoc)
	{
		BSTR bstrSubstID = nullptr;
		BSTR bstrCurrentLoc = nullptr;
		long lResult = EZGEM_GetSubstrate(pGEM, nIndex, &bstrSubstID, &bstrCurrentLoc);
		if (lResult < 0) return lResult;
		if (bstrSubstID)
		{
			*pSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		if (bstrCurrentLoc)
		{
			*pCurrentLoc = CString(bstrCurrentLoc);
			::SysFreeString(bstrCurrentLoc);
		}
		return lResult;
	}
	long GetSubstrate(long nIndex, CString& strSubstID, CString& strCurrentLoc)
	{
		BSTR bstrSubstID = nullptr;
		BSTR bstrCurrentLoc = nullptr;
		long lResult = EZGEM_GetSubstrate(pGEM, nIndex, &bstrSubstID, &bstrCurrentLoc);
		if (lResult < 0) return lResult;
		if (bstrSubstID)
		{
			strSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		if (bstrCurrentLoc)
		{
			strCurrentLoc = CString(bstrCurrentLoc);
			::SysFreeString(bstrCurrentLoc);
		}
		return lResult;
	}
	long GetSubstrateState(LPCTSTR sSubstID, int *pnTranState, int *pnProcState, int *pnReadState)	{		return EZGEM_GetSubstrateState(pGEM, sSubstID, pnTranState, pnProcState, pnReadState);	}
	long GetSubstLocation(long nIndex, BSTR *psLocID, BSTR *psSubstID, int *pnLocState)	{		return EZGEM_GetSubstLocation(pGEM, nIndex, psLocID, psSubstID, pnLocState);	}
	long GetSubstLocation(long nIndex, CString* pLocID, CString* pSubstID, int* pnLocState)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrSubstID = nullptr;
		long lResult = EZGEM_GetSubstLocation(pGEM, nIndex, &bstrLocID, &bstrSubstID, pnLocState);
		if (lResult < 0) return lResult;
		if (bstrLocID)
		{
			*pLocID = CString(bstrLocID);
			::SysFreeString(bstrLocID);
		}
		if (bstrSubstID)
		{
			*pSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		return lResult;
	}
	long GetSubstLocation(long nIndex, CString& strLocID, CString& strSubstID, int* pnLocState)
	{
		BSTR bstrLocID = nullptr;
		BSTR bstrSubstID = nullptr;
		long lResult = EZGEM_GetSubstLocation(pGEM, nIndex, &bstrLocID, &bstrSubstID, pnLocState);
		if (lResult < 0) return lResult;
		if (bstrLocID)
		{
			strLocID = CString(bstrLocID);
			::SysFreeString(bstrLocID);
		}
		if (bstrSubstID)
		{
			strSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		return lResult;
	}
	long GetSubstBatchLoc(long nIndex, CString *psBatchLocID, int *pnSubstCount, CStringArray *paSubstList)
	{	
		BSTR bstrBatchLocID;
		char *psSubstList[SLOTMAP_MAXSLOT];
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++) psSubstList[i] = new char[0xFF];
		long nResult = EZGEM_GetSubstBatchLoc(pGEM, nIndex, &bstrBatchLocID, pnSubstCount, psSubstList);
		if (nResult >= 0)
		{
			for (int i = 0; i < *pnSubstCount; i++) paSubstList->Add((CString)psSubstList[i]);
		}
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++) delete[]psSubstList[i];
		*psBatchLocID = (CString)bstrBatchLocID;
		SysFreeString(bstrBatchLocID);
		return nResult;
	}
	long GetSubstBatchLoc(long nIndex, CString* psBatchLocID, int* pnSubstCount, CStringArray& paSubstList)
	{
		BSTR bstrBatchLocID;
		char* psSubstList[SLOTMAP_MAXSLOT];
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++) psSubstList[i] = new char[0xFF];
		long nResult = EZGEM_GetSubstBatchLoc(pGEM, nIndex, &bstrBatchLocID, pnSubstCount, psSubstList);
		if (nResult >= 0)
		{
			for (int i = 0; i < *pnSubstCount; i++)
				paSubstList.Add((CString)psSubstList[i]);
		}
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++)
			delete[] psSubstList[i];
		*psBatchLocID = (CString)bstrBatchLocID;
		SysFreeString(bstrBatchLocID);
		return nResult;
	}
	long GetSubstBatchLoc(long nIndex, CString* psBatchLocID, int* pnSubstCount, std::vector<CString>& paSubstList)
	{
		BSTR bstrBatchLocID = nullptr;
		char* psSubstList[SLOTMAP_MAXSLOT];
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++)
			psSubstList[i] = new char[0xFF];
		long nResult = EZGEM_GetSubstBatchLoc(pGEM, nIndex, &bstrBatchLocID, pnSubstCount, psSubstList);
		if (nResult >= 0)
		{
			for (int i = 0; i < *pnSubstCount; i++)
				paSubstList.emplace_back(psSubstList[i]);
		}
		for (int i = 0; i < SLOTMAP_MAXSLOT; i++)
			delete[] psSubstList[i];
		if (bstrBatchLocID)
		{
			*psBatchLocID = CString(bstrBatchLocID);
			::SysFreeString(bstrBatchLocID);
		}
		return nResult;
	}
	long GetSubstHostCommand(long lMsgId, int *pnCommand, BSTR *psSubstID, BSTR *psLocID)	{		return EZGEM_GetSubstHostCommand(pGEM, lMsgId, pnCommand, psSubstID, psLocID);	}
	long GetSubstHostCommand(long lMsgId, int* pnCommand, CString* pSubstID, CString* pLocID)
	{
		BSTR bstrSubstID = nullptr;
		BSTR bstrLocID = nullptr;
		long lResult = EZGEM_GetSubstHostCommand(pGEM, lMsgId, pnCommand, &bstrSubstID, &bstrLocID);
		if (lResult < 0) return lResult;
		if (bstrSubstID)
		{
			*pSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		if (bstrLocID)
		{
			*pLocID = CString(bstrLocID);
			::SysFreeString(bstrLocID);
		}
		return lResult;
	}
	long GetSubstHostCommand(long lMsgId, int* pnCommand, CString& strSubstID, CString& strLocID)
	{
		BSTR bstrSubstID = nullptr;
		BSTR bstrLocID = nullptr;
		long lResult = EZGEM_GetSubstHostCommand(pGEM, lMsgId, pnCommand, &bstrSubstID, &bstrLocID);
		if (lResult < 0) return lResult;
		if (bstrSubstID)
		{
			strSubstID = CString(bstrSubstID);
			::SysFreeString(bstrSubstID);
		}
		if (bstrLocID)
		{
			strLocID = CString(bstrLocID);
			::SysFreeString(bstrLocID);
		}
		return lResult;
	}
	long DeleteAllSubstrate()	{		return EZGEM_DeleteAllSubstrate(pGEM);	}
	long DeleteSubstrate(LPCTSTR sSubstID)	{		return EZGEM_DeleteSubstrate(pGEM, sSubstID);	}
	long SetSubstrateMove(LPCTSTR sSubstID, LPCTSTR sToLocID, int nTransferState) {		return EZGEM_SetSubstrateMove(pGEM, sSubstID, sToLocID, nTransferState);	}
	long SetSubstBatchMove(int nCount, CStringArray *psaSubstList, LPCTSTR sBatchLocID, int nStartPosInBatch, int nTransState)
	{
		BSTR *bstrSubstList = NULL;
		if (nCount > 0) bstrSubstList = new BSTR[nCount];
		for (int i = 0; i < nCount; i++) bstrSubstList[i] = (psaSubstList->GetAt(i)).AllocSysString();
		long nResult = EZGEM_SetSubstBatchMove(pGEM, nCount, bstrSubstList, sBatchLocID, nStartPosInBatch, nTransState);
		for (int i = 0; i < nCount; i++) SysFreeString(bstrSubstList[i]);
		delete[] bstrSubstList; bstrSubstList = NULL;
		return nResult;
	}
	long SetSubstBatchMove(int nCount, CStringArray& psaSubstList, LPCTSTR sBatchLocID, int nStartPosInBatch, int nTransState)
	{
		BSTR* bstrSubstList = nullptr;
		if (nCount > 0)
			bstrSubstList = new BSTR[nCount];
		for (int i = 0; i < nCount; i++)
			bstrSubstList[i] = (psaSubstList.GetAt(i)).AllocSysString();
		long nResult = EZGEM_SetSubstBatchMove(pGEM, nCount, bstrSubstList, sBatchLocID, nStartPosInBatch, nTransState);
		for (int i = 0; i < nCount; i++)
			::SysFreeString(bstrSubstList[i]);
		delete[] bstrSubstList;
		return nResult;
	}
	long SetSubstBatchMove(int nCount, std::vector<CString>& psaSubstList, LPCTSTR sBatchLocID, int nStartPosInBatch, int nTransState)
	{
		BSTR* bstrSubstList = nullptr;
		if (nCount > 0)
			bstrSubstList = new BSTR[nCount];
		for (int i = 0; i < nCount; i++)
			bstrSubstList[i] = psaSubstList[i].AllocSysString();
		long nResult = EZGEM_SetSubstBatchMove(pGEM, nCount, bstrSubstList, sBatchLocID, nStartPosInBatch, nTransState);
		for (int i = 0; i < nCount; i++)
			::SysFreeString(bstrSubstList[i]);
		delete[] bstrSubstList;
		return nResult;
	}
	long SetSubstTranState(LPCTSTR sSubstID, int nTranState){return EZGEM_SetSubstTranState(pGEM, sSubstID, nTranState);}
	long SetSubstProcState(LPCTSTR sSubstID, int nProcState){return EZGEM_SetSubstProcState(pGEM, sSubstID, nProcState);}
	long SetSubstReadState(LPCTSTR sSubstID, int nReadState){return EZGEM_SetSubstReadState(pGEM, sSubstID, nReadState);}
	long SetSubstIdRead(LPCTSTR sSubstID, LPCTSTR sReadID, int nReadResult) { return EZGEM_SetSubstIDRead(pGEM, sSubstID, sReadID, nReadResult); }
	long ReplySubstAction(long lMsgId, int nRetCode, int nErrCode, LPCTSTR szErrText){ return EZGEM_ReplySubstAction(pGEM, lMsgId, nRetCode, nErrCode, szErrText); }
	long SetSubstLocState(LPCTSTR sLocID, int nLocState) { return EZGEM_SetSubstLocState(pGEM,sLocID,nLocState); }
	// OSS
	long GetAttrName(LPCTSTR sObjType, BSTR *psAttrNameList){return EZGEM_GetAttrName(pGEM, sObjType, psAttrNameList);}
	long GetAttrName(LPCTSTR sObjType, CStringArray* pAttrNameList)
	{
		BSTR bstrNameList;
		long nResult = GetAttrName(sObjType, &bstrNameList);
		if (nResult < 0) return nResult;

		CString strNameList(bstrNameList);
		SysFreeString(bstrNameList);

#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strNameList);
		std::wstring token;
		while (std::getline(ssName, token, L',')) 
		{
			pAttrNameList->Add(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strNameList);
		std::string token;
		while (std::getline(ssName, token, ',')) {
			pAttrNameList->Add(token.c_str());
		}
#endif
		return nResult;
	}
	long GetAttrName(LPCTSTR sObjType, CStringArray& attrNameList)
	{
		BSTR bstrNameList = nullptr;
		long nResult = GetAttrName(sObjType, &bstrNameList);
		if (nResult < 0)
			return nResult;
		CString strNameList(bstrNameList);
		::SysFreeString(bstrNameList);
#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strNameList);
		std::wstring token;
		while (std::getline(ssName, token, L','))
		{
			attrNameList.Add(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strNameList);
		std::string token;
		while (std::getline(ssName, token, ','))
		{
			attrNameList.Add(token.c_str());
		}
#endif
		return nResult;
	}
	long GetAttrName(LPCTSTR sObjType, std::vector<CString>& attrNameList)
	{
		BSTR bstrNameList = nullptr;
		long nResult = GetAttrName(sObjType, &bstrNameList);
		if (nResult < 0) return nResult;
		CString strNameList(bstrNameList);
		::SysFreeString(bstrNameList);
#if defined(_UNICODE)
		std::wstringstream ssName((LPCTSTR)strNameList);
		std::wstring token;
		while (std::getline(ssName, token, L','))
		{
			attrNameList.emplace_back(token.c_str());
		}
#else
		std::stringstream ssName((LPCTSTR)strNameList);
		std::string token;
		while (std::getline(ssName, token, ','))
		{
			attrNameList.emplace_back(token.c_str());
		}
#endif
		return nResult;
	}

	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, BSTR *psAttrData) { return EZGEM_GetAttrData(pGEM, sObjType, sObjID, sAttrName, psAttrData);}
	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, CString* psAttrData) 
	{
		BSTR bstrAttrData = nullptr;
		long lRet = EZGEM_GetAttrData(pGEM, sObjType, sObjID, sAttrName, &bstrAttrData);

		if (SUCCEEDED(lRet) && bstrAttrData != nullptr) 
		{
			*psAttrData = CString(bstrAttrData);
			::SysFreeString(bstrAttrData);
		}
		else 
		{
			psAttrData->Empty();
		}
		return lRet;
	}
	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, CString& sAttrData)
	{
		BSTR bstrAttrData = nullptr;
		long lRet = EZGEM_GetAttrData(pGEM, sObjType, sObjID, sAttrName, &bstrAttrData);

		if (SUCCEEDED(lRet) && bstrAttrData != nullptr)
		{
			sAttrData = CString(bstrAttrData);
			::SysFreeString(bstrAttrData);
		}
		else
		{
			sAttrData.Empty();
		}
		return lRet;
	}
	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, CStringArray* pAttrData)
	{
		BSTR bstrAttrData;
		long nResult = GetAttrData(sObjType, sObjID, sAttrName, &bstrAttrData);
		if (nResult < 0) return nResult;

		CString strAttrData(bstrAttrData);
		SysFreeString(bstrAttrData);

#if defined(_UNICODE)
		std::wstringstream ssAttr((LPCTSTR)strAttrData);
		std::wstring token;
		while (std::getline(ssAttr, token, L',')) 
		{
			pAttrData->Add(token.c_str());
		}
#else
		std::stringstream ssAttr((LPCTSTR)strAttrData);
		std::string token;
		while (std::getline(ssAttr, token, ',')) {
			pAttrData->Add(token.c_str());
		}
#endif
		while (pAttrData->GetCount() < nResult) 
		{
			pAttrData->Add(_T(""));
		}
		return nResult;
	}
	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, CStringArray& attrData)
	{
		BSTR bstrAttrData = nullptr;
		long nResult = GetAttrData(sObjType, sObjID, sAttrName, &bstrAttrData);
		if (nResult < 0) return nResult;

		CString strAttrData(bstrAttrData);
		::SysFreeString(bstrAttrData);

#if defined(_UNICODE)
		std::wstringstream ssAttr((LPCTSTR)strAttrData);
		std::wstring token;
		while (std::getline(ssAttr, token, L','))
		{
			attrData.Add(token.c_str());
		}
#else
		std::stringstream ssAttr((LPCTSTR)strAttrData);
		std::string token;
		while (std::getline(ssAttr, token, ','))
		{
			attrData.Add(token.c_str());
		}
#endif
		while (attrData.GetCount() < nResult)
		{
			attrData.Add(_T(""));
		}
		return nResult;
	}
	long GetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, std::vector<CString>& attrData)
	{
		BSTR bstrAttrData = nullptr;
		long nResult = GetAttrData(sObjType, sObjID, sAttrName, &bstrAttrData);
		if (nResult < 0) return nResult;

		CString strAttrData(bstrAttrData);
		::SysFreeString(bstrAttrData);
#if defined(_UNICODE)
		std::wstringstream ssAttr((LPCTSTR)strAttrData);
		std::wstring token;
		while (std::getline(ssAttr, token, L','))
		{
			attrData.emplace_back(token.c_str());
		}
#else
		std::stringstream ssAttr((LPCTSTR)strAttrData);
		std::string token;
		while (std::getline(ssAttr, token, ','))
		{
			attrData.emplace_back(token.c_str());
		}
#endif
		while (static_cast<int>(attrData.size()) < nResult)
		{
			attrData.emplace_back(_T(""));
		}
		return nResult;
	}

	long SetAttrData(LPCTSTR sObjType, LPCTSTR sObjID, LPCTSTR sAttrName, LPCTSTR sNewVal)	{		return EZGEM_SetAttrData(pGEM, sObjType, sObjID, sAttrName, sNewVal);	}
	long GetObjectList(LPCTSTR sObjType, BSTR *psObjList) { return EZGEM_GetObjectList(pGEM, sObjType, psObjList); }
	long GetObjectList(LPCTSTR sObjType, CStringArray* pObjList)
	{
		BSTR bstrObjList;
		long nResult = GetObjectList(sObjType, &bstrObjList);
		if (nResult < 0) return nResult;

		CString strObjList(bstrObjList);
		SysFreeString(bstrObjList);

#if defined(_UNICODE)
		std::wstringstream ssList((LPCTSTR)strObjList);
		std::wstring token;
		while (std::getline(ssList, token, L',')) 
		{
			pObjList->Add(token.c_str());
		}
#else
		std::stringstream ssList((LPCTSTR)strObjList);
		std::string token;
		while (std::getline(ssList, token, ',')) 
		{
			pObjList->Add(token.c_str());
		}
#endif
		while (pObjList->GetCount() < nResult) 
		{
			pObjList->Add(_T(""));
		}
		return nResult;
	}
	long GetObjectList(LPCTSTR sObjType, CStringArray& objList)
	{
		BSTR bstrObjList = nullptr;
		long nResult = GetObjectList(sObjType, &bstrObjList);
		if (nResult < 0) return nResult;
		CString strObjList(bstrObjList);
		::SysFreeString(bstrObjList);
#if defined(_UNICODE)
		std::wstringstream ssList((LPCTSTR)strObjList);
		std::wstring token;
		while (std::getline(ssList, token, L','))
		{
			objList.Add(token.c_str());
		}
#else
		std::stringstream ssList((LPCTSTR)strObjList);
		std::string token;
		while (std::getline(ssList, token, ','))
		{
			objList.Add(token.c_str());
		}
#endif
		while (objList.GetCount() < nResult)
		{
			objList.Add(_T(""));
		}
		return nResult;
	}
	long GetObjectList(LPCTSTR sObjType, std::vector<CString>& objList)
	{
		BSTR bstrObjList = nullptr;
		long nResult = GetObjectList(sObjType, &bstrObjList);
		if (nResult < 0) return nResult;

		CString strObjList(bstrObjList);
		::SysFreeString(bstrObjList);

#if defined(_UNICODE)
		std::wstringstream ssList((LPCTSTR)strObjList);
		std::wstring token;
		while (std::getline(ssList, token, L','))
		{
			objList.emplace_back(token.c_str());
		}
#else
		std::stringstream ssList((LPCTSTR)strObjList);
		std::string token;
		while (std::getline(ssList, token, ','))
		{
			objList.emplace_back(token.c_str());
		}
#endif
		while (static_cast<int>(objList.size()) < nResult)
		{
			objList.emplace_back(_T(""));
		}
		return nResult;
	}
};
