1 /*---------------------------------------------------------------------------*
2   Project:  Host I/O Interface for HIO2
3   File:     Hio2IfHost.cpp
4 
5   (C)2005 HUDSON SOFT
6 
7   $Header: /home/cvsroot/SDK/build/demos/hio2demo/vc++/HioIf/src/Hio2IfHost.cpp,v 1.4 2007/11/26 13:55:55 iwai_yuma Exp $
8 
9   $NoKeywords: $
10  *---------------------------------------------------------------------------*/
11 
12 // Host I/O API wrapper interface
13 
14 #include "stdafx.h"
15 #include "Hio2IfHost.h"
16 #include <stdarg.h>
17 
18 ///////////////////////////////////////////////////////////////////////////////
19 //
20 // CHiosIf object for callback function reference
21 //
22 
23 static CHio2If*	l_pHio2If = NULL;
24 
25 
26 ///////////////////////////////////////////////////////////////////////////////
27 //
28 // Comparative function from CStatusList to IndexOf
29 //
30 
31 // HIO handle comparison
Hio2IfCompHandle(LPHIO2IF_STATUS pItem,LPVOID pData)32 BOOL	Hio2IfCompHandle(LPHIO2IF_STATUS pItem, LPVOID pData)
33 {
34 	// pData == handle
35 	return (pItem->m_hHIO == pData) ? TRUE : FALSE;
36 }
37 
38 // PC channel comparison
Hio2IfCompPcChan(LPHIO2IF_STATUS pItem,LPVOID pData)39 BOOL	Hio2IfCompPcChan(LPHIO2IF_STATUS pItem, LPVOID pData)
40 {
41 #ifndef	HW0
42 	return (lstrcmp(pItem->m_pPathName, (LPCSTR)pData) == 0) ? TRUE : FALSE;
43 #else	// HW0
44 	return (pItem->m_pPathName == (HIO2DevicePath)pData) ? TRUE : FALSE;
45 #endif	// HW0
46 }
47 
48 ///////////////////////////////////////////////////////////////////////////////
49 //
50 // Error strings
51 //
52 
53 LPCSTR	CHio2If::m_lpszErrorStrings[HIO2IF_ERROR_MAX] =
54 {
55 
56 #include "Hio2IfErr.str"
57 
58 };
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 //
62 // Callback
63 //
64 
65 // HIO2EnumDevices() - callback
66 static
hio2EnumCallback(HIO2DevicePath pathName,void * param)67 BOOL	hio2EnumCallback(HIO2DevicePath pathName, void* param)
68 {
69 	CHio2If* pHio2If = static_cast<CHio2If *>(param);
70 	pHio2If->AddDevicePath(pathName);
71 	return TRUE;
72 }
73 
74 // HIO2Open() - callback
75 static
hio2Callback(HIO2Handle h)76 void	hio2Callback(HIO2Handle h)
77 {
78 	static const HIO2IF_MODE	l_nOpenMode[] =
79 	{
80 		HIO2IF_MODE_WRONLY,	// Send only
81 		HIO2IF_MODE_RDONLY,	// Receive only
82 		HIO2IF_MODE_RDWR		// Send and receive
83 	};
84 
85 	// For multithreading
86 	l_pHio2If->EnterCriticalSection();
87 
88 	HIO2IF_EVENT event;
89 	int id, cmd;
90 	u32 mail = 0;
91 
92 	// Get the CHio2If ID from the HIO handle
93 	id = l_pHio2If->GetIdOfHandle(h);
94 
95 	l_pHio2If->GetDllIf().ReadMailbox(h, &mail);
96 
97 	cmd = HIO2IF_GET_PACKET_CMD(mail);
98 
99 	switch ( cmd )
100 	{
101 	case HIO2IF_CMD_OPEN_RDONLY:
102 	case HIO2IF_CMD_OPEN_WRONLY:
103 	case HIO2IF_CMD_OPEN_RDWR:
104 		// Perform the following and notify NNGC when an open notification arrives from NNGC:
105 		// 1) Establish a connection with the PC
106 		// 2) Open mode settings
107 		//    Settings are opposite (reversed) of NNGC settings for read only and write only
108 		// 3) NNGC EXI channel number
109 		l_pHio2If->SetConnect(id, TRUE);
110 		l_pHio2If->SetOpenMode(id, l_nOpenMode[cmd -1]);
111 		l_pHio2If->SetDeviceType(id, (HIO2DeviceType)HIO2IF_GET_PACKET_CHAN(mail));
112 		l_pHio2If->GetDllIf().WriteMailbox(h,
113             HIO2IF_SET_PACKET(
114 				l_pHio2If->GetPcChan(id),
115 				HIO2IF_CMD_OPEN_RESULT
116 			)
117 		);
118 		event = HIO2IF_EVENT_CONNECT;
119 		break;
120 	case HIO2IF_CMD_SEND:
121 		l_pHio2If->SetReceived(id, TRUE);
122 		event = HIO2IF_EVENT_RECEIVED;
123 		break;
124 	case HIO2IF_CMD_SEND_RESULT:
125 		l_pHio2If->SetSendPossible(id, TRUE);
126 		event = HIO2IF_EVENT_SEND_POSSIBLE;
127 		break;
128 	case HIO2IF_CMD_CLOSE:
129 		// The actual close process must done in the application
130 		l_pHio2If->SetConnect(id, FALSE);
131 		event = HIO2IF_EVENT_DISCONNECT;
132 		break;
133 	default:
134 		event = HIO2IF_EVENT_UNKOWN;
135 		break;
136 	}
137 
138 	// For multithreading
139 	l_pHio2If->LeaveCriticalSection();
140 
141 	l_pHio2If->CallEventCallback(id, event);
142 }
143 
144 // HIOReadAsync() - callback
145 static
hio2ReadAsyncCallback(HIO2Handle h)146 void	hio2ReadAsyncCallback(HIO2Handle h)
147 {
148 	// Get the CHio2If ID from the HIO handle
149 	int id = l_pHio2If->GetIdOfHandle(h);
150 	DWORD async = HIO2IF_ASYNC_READ_MASK(l_pHio2If->GetAsyncMode(id));
151 
152 	// If there is an Async specification from CHio2If::Read, perform a Read completion notification to the connection target
153 	// (CHio2If::ReadFree notification not needed)
154 	if ( async & HIO2IF_ASYNC_READ )
155 	{
156 		// For multithreading
157 		l_pHio2If->EnterCriticalSection();
158 
159 		l_pHio2If->GetDllIf().WriteMailbox(h,
160             HIO2IF_SET_PACKET(
161 				l_pHio2If->GetPcChan(id),
162 				HIO2IF_CMD_SEND_RESULT
163 			)
164 		);
165 
166 		// For multithreading
167 		l_pHio2If->LeaveCriticalSection();
168 	}
169 
170 	l_pHio2If->SetAsyncMode(id, l_pHio2If->GetAsyncMode(id) & ~async);
171 
172 	// Event callback function call
173 	l_pHio2If->CallEventCallback(id, HIO2IF_EVENT_READ_ASYNC_DONE);
174 }
175 
176 // HIOWriteAsync() - callback
177 static
hio2WriteAsyncCallback(HIO2Handle h)178 void	hio2WriteAsyncCallback(HIO2Handle h)
179 {
180 	// Get the CHio2If ID from the HIO handle
181 	int id = l_pHio2If->GetIdOfHandle(h);
182 	DWORD async = HIO2IF_ASYNC_WRITE_MASK(l_pHio2If->GetAsyncMode(id));
183 
184 	// If there is an Async specification from CHio2If::Write, perform a Write notification to the connection target
185 	// (CHio2If::WriteFree notification not needed)
186 	if ( async & HIO2IF_ASYNC_WRITE )
187 	{
188 		// For multithreading
189 		l_pHio2If->EnterCriticalSection();
190 
191 		l_pHio2If->GetDllIf().WriteMailbox(h,
192             HIO2IF_SET_PACKET(
193 				l_pHio2If->GetPcChan(id),
194 				HIO2IF_CMD_SEND
195 			)
196 		);
197 
198 		// For multithreading
199 		l_pHio2If->LeaveCriticalSection();
200 	}
201 
202 	l_pHio2If->SetAsyncMode(id, l_pHio2If->GetAsyncMode(id) & ~async);
203 
204 	// Event callback function call
205 	l_pHio2If->CallEventCallback(id, HIO2IF_EVENT_WRITE_ASYNC_DONE);
206 }
207 
208 ///////////////////////////////////////////////////////////////////////////////
209 //
210 // CHio2If
211 //
212 
213 //-----------------------------------------------------------------------------
CHio2If()214 CHio2If::CHio2If()
215 {
216 	m_szMessage[0]	= '\0';
217 	m_nLastError = HIO2IF_ERROR_NONE;
218 	m_bInitialized = FALSE;
219 	InitializeCriticalSection(&m_csCriticalSection);
220 }
221 
~CHio2If()222 CHio2If::~CHio2If()
223 {
224 	Exit();
225 	DeleteCriticalSection(&m_csCriticalSection);
226 }
227 
228 //-----------------------------------------------------------------------------
Init()229 HIO2IF_RESULT	CHio2If::Init()
230 {
231 	// When initialized, terminate HIO2
232 	if ( m_bInitialized ) m_cHio2Dll.Exit();
233 	else if ( !m_cHio2Dll.Create() ) return SetFatal(HIO2IF_FATAL_LOAD_DLL);
234 
235 	InitInstance();
236 
237 	// HIO initialization
238 	if ( !m_cHio2Dll.Init() )
239 		return SetFatal(HIO2IF_FATAL_INIT, m_cHio2Dll.GetLastError());
240 
241 	// Search for an EXI device
242 	if ( m_cHio2Dll.EnumDevices(hio2EnumCallback, this) == -1 )
243 		return SetFatal(HIO2IF_FATAL_ENUMDEVICES, m_cHio2Dll.GetLastError());
244 
245 	m_bInitialized = TRUE;
246 
247 	return HIO2IF_RESULT_SUCCESS;
248 }
249 
250 //-----------------------------------------------------------------------------
Open(HIO2DevicePath pathName,HIO2IF_EVENT_CALLBACK callback,HIO2IF_ID & id)251 HIO2IF_RESULT	CHio2If::Open(HIO2DevicePath pathName, HIO2IF_EVENT_CALLBACK callback, HIO2IF_ID& id)
252 {
253 	LPHIO2IF_STATUS pStatus = NULL;
254 	int nIndex, nPcChan = 0;
255 
256 #ifndef	HW0
257 	// Use any numbers included in the device path name as a pseudo PC channel number
258 	LPCSTR p = pathName;
259 	while ( *p != '\0' )
260 	{
261 		if ( (*p >= '0') && (*p <= '9') )
262 		{
263 			nPcChan *= 10;
264 			nPcChan += *p - '0';
265 		}
266 		p++;
267 	}
268 #else	// HW0
269 	nPcChan = pathName;
270 #endif	// HW0
271 	nPcChan &= HIO2IF_CMD_MASK;
272 
273 	// When the specified EXI channel is in use
274 	nIndex = m_cHioStatus.IndexOf((LPVOID)pathName, Hio2IfCompPcChan);
275 	if ( nIndex != -1 )
276 	{
277 		pStatus = m_cHioStatus[nIndex];
278 		if ( pStatus->m_hHIO != HIO2IF_INVALID_HANDLE_VALUE )
279 			return SetError(HIO2IF_ERROR_CHAN_ALREADY_OPENED, pathName);
280 	}
281 
282 	HIO2Handle h = m_cHio2Dll.Open(pathName, hio2Callback, NULL, NULL);
283 	if ( h == HIO2_INVALID_HANDLE_VALUE )
284 		return SetFatal(HIO2IF_FATAL_OPEN, pathName, m_cHio2Dll.GetLastError());
285 
286 	// For previously opened (detected) channels
287 	if ( nIndex != -1 )
288 		id = nIndex;
289 	else
290 	{
291 		pStatus = new HIO2IF_STATUS;
292 		id = m_cHioStatus.AddTail(pStatus);
293 	}
294 
295 	// Host I/O interface default settings
296 #ifndef	HW0
297 	pStatus->m_pPathName = new TCHAR [lstrlen(pathName) + 1];
298 	lstrcpy((LPSTR)pStatus->m_pPathName, pathName);
299 #else	// HW0
300 	pStatus->m_pPathName = pathName;
301 #endif	// HW0
302 	pStatus->m_nPcChan		= nPcChan;
303 	pStatus->m_hHIO			= h;
304 	pStatus->m_fncCallback	= callback;
305 
306 	return HIO2IF_RESULT_SUCCESS;
307 }
308 
309 //-----------------------------------------------------------------------------
Read(HIO2IF_ID id,DWORD addr,LPVOID buffer,int size,BOOL async)310 HIO2IF_RESULT	CHio2If::Read(HIO2IF_ID id, DWORD addr, LPVOID buffer, int size, BOOL async)
311 {
312 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
313 
314 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
315 
316 	// For the write-only mode
317 	if ( pStatus->m_nMode == HIO2IF_MODE_WRONLY )
318 		return SetError(HIO2IF_ERROR_WRITE_ONLY, pStatus->m_nPcChan);
319 
320 	// Not connected to the PC
321 	if ( !pStatus->m_bConnect )
322 		return SetError(HIO2IF_ERROR_NOT_CONNECT, pStatus->m_nPcChan);
323 
324 	// When data has not been received
325 	if ( !pStatus->m_bReceived )
326 		return SetError(HIO2IF_ERROR_NOT_RECV_DATA, pStatus->m_nPcChan);
327 
328 	pStatus->m_bReceived = FALSE;
329 
330 	// Synchronous Read
331 	if ( !async )
332 	{
333 		if ( !m_cHio2Dll.Read(pStatus->m_hHIO, addr, buffer, size) )
334 			return SetFatal(HIO2IF_FATAL_READ,
335 							pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
336 
337 		// Notify the connection target that the Read operation is complete
338 		m_cHio2Dll.WriteMailbox(pStatus->m_hHIO,
339 			HIO2IF_SET_PACKET(pStatus->m_nPcChan, HIO2IF_CMD_SEND_RESULT));
340 	}
341 	// Asynchronous Read
342 	else
343 	{
344 		pStatus->m_dwAsyncMode |= HIO2IF_ASYNC_READ;
345 		if ( !m_cHio2Dll.ReadAsync(pStatus->m_hHIO, addr, buffer, size, hio2ReadAsyncCallback) )
346 			return SetFatal(HIO2IF_FATAL_READ,
347 							pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
348 	}
349 
350 	return HIO2IF_RESULT_SUCCESS;
351 }
352 
353 //-----------------------------------------------------------------------------
ReadFree(HIO2IF_ID id,DWORD addr,LPVOID buffer,int size,BOOL async)354 HIO2IF_RESULT	CHio2If::ReadFree(HIO2IF_ID id, DWORD addr, LPVOID buffer, int size, BOOL async)
355 {
356 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
357 
358 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
359 
360 	// For the write-only mode
361 	if ( pStatus->m_nMode == HIO2IF_MODE_WRONLY )
362 		return SetError(HIO2IF_ERROR_WRITE_ONLY, pStatus->m_nPcChan);
363 
364 	// Not connected to the PC
365 	if ( !pStatus->m_bConnect )
366 		return SetError(HIO2IF_ERROR_NOT_CONNECT, pStatus->m_nPcChan);
367 
368 	// Synchronous Read
369 	if ( !async )
370 	{
371 		if ( !m_cHio2Dll.Read(pStatus->m_hHIO, addr, buffer, size) )
372 			return SetFatal(HIO2IF_FATAL_READ,
373 							pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
374 	}
375 	// Asynchronous Read
376 	else
377 	{
378 		// The previous ReadAsync or WriteAsync is not completed
379 		if  ( pStatus->m_dwAsyncMode )
380 			return SetError(HIO2IF_ERROR_BUSY, pStatus->m_nPcChan);
381 
382 		pStatus->m_dwAsyncMode |= HIO2IF_ASYNC_READ_FREE;
383 		if ( !m_cHio2Dll.ReadAsync(pStatus->m_hHIO, addr, buffer, size, hio2ReadAsyncCallback) )
384 			return SetFatal(HIO2IF_FATAL_READ,
385 							pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
386 	}
387 
388 	return HIO2IF_RESULT_SUCCESS;
389 }
390 
391 //-----------------------------------------------------------------------------
Write(HIO2IF_ID id,DWORD addr,LPVOID buffer,int size,BOOL async)392 HIO2IF_RESULT	CHio2If::Write(HIO2IF_ID id, DWORD addr, LPVOID buffer, int size, BOOL async)
393 {
394 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
395 
396 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
397 
398 	// For the read-only mode
399 	if ( pStatus->m_nMode == HIO2IF_MODE_RDONLY )
400 		return SetError(HIO2IF_ERROR_READ_ONLY, pStatus->m_nPcChan);
401 
402 	// Not connected to the PC
403 	if ( !pStatus->m_bConnect )
404 		return SetError(HIO2IF_ERROR_NOT_CONNECT, pStatus->m_nPcChan);
405 
406 	// When it can't be sent (when the target cannot receive data)
407 	if ( !pStatus->m_bSendPossible )
408 		return SetError(HIO2IF_ERROR_CANNOT_SEND_DATA, pStatus->m_nPcChan);
409 
410 	pStatus->m_bSendPossible = FALSE;
411 
412 	// Synchronous Write
413 	if ( !async )
414 	{
415 		if ( !m_cHio2Dll.Write(pStatus->m_hHIO, addr, buffer, size) )
416 			return SetFatal(HIO2IF_FATAL_WRITE,
417 				pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
418 
419 		// Perform a Write notification to the connection target
420 		m_cHio2Dll.WriteMailbox(pStatus->m_hHIO,
421 			HIO2IF_SET_PACKET(pStatus->m_nPcChan, HIO2IF_CMD_SEND));
422 	}
423 	// Asynchronous Write
424 	else
425 	{
426 		pStatus->m_dwAsyncMode |= HIO2IF_ASYNC_WRITE;
427 		if ( !m_cHio2Dll.WriteAsync(pStatus->m_hHIO, addr, buffer, size, hio2WriteAsyncCallback) )
428 			return SetFatal(HIO2IF_FATAL_WRITE,
429 				pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
430 	}
431 
432 	return HIO2IF_RESULT_SUCCESS;
433 }
434 
435 //-----------------------------------------------------------------------------
WriteFree(HIO2IF_ID id,DWORD addr,LPVOID buffer,int size,BOOL async)436 HIO2IF_RESULT	CHio2If::WriteFree(HIO2IF_ID id, DWORD addr, LPVOID buffer, int size, BOOL async)
437 {
438 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
439 
440 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
441 
442 	// For the read-only mode
443 	if ( pStatus->m_nMode == HIO2IF_MODE_RDONLY )
444 		return SetError(HIO2IF_ERROR_READ_ONLY, pStatus->m_nPcChan);
445 
446 	// Not connected to the PC
447 	if ( !pStatus->m_bConnect )
448 		return SetError(HIO2IF_ERROR_NOT_CONNECT, pStatus->m_nPcChan);
449 
450 	// Synchronous Write
451 	if ( !async )
452 	{
453 		if ( !m_cHio2Dll.Write(pStatus->m_hHIO, addr, buffer, size) )
454 			return SetFatal(HIO2IF_FATAL_WRITE,
455 							pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
456 	}
457 	// Asynchronous Write
458 	else
459 	{
460 		// The previous ReadAsync or WriteAsync is not completed
461 		if  ( pStatus->m_dwAsyncMode )
462 			return SetError(HIO2IF_ERROR_BUSY, pStatus->m_nPcChan);
463 
464 		pStatus->m_dwAsyncMode |= HIO2IF_ASYNC_WRITE_FREE;
465 		if ( !m_cHio2Dll.WriteAsync(pStatus->m_hHIO, addr, buffer, size, hio2WriteAsyncCallback) )
466 			return SetFatal(HIO2IF_FATAL_WRITE,
467 				pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
468 	}
469 
470 	return HIO2IF_RESULT_SUCCESS;
471 }
472 
473 //-----------------------------------------------------------------------------
ReadStatus(HIO2IF_ID id,DWORD & status)474 HIO2IF_RESULT	CHio2If::ReadStatus(HIO2IF_ID id, DWORD& status)
475 {
476 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
477 
478 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
479 
480 	// Not connected to the PC
481 	if ( !pStatus->m_bConnect )
482 		return SetError(HIO2IF_ERROR_NOT_CONNECT, pStatus->m_nPcChan);
483 
484 	return m_cHio2Dll.ReadStatus(pStatus->m_hHIO, (u32 *)&status)
485 		? HIO2IF_RESULT_SUCCESS
486 		: SetFatal(HIO2IF_FATAL_READSTATUS,
487 			pStatus->m_nPcChan, m_cHio2Dll.GetLastError());
488 }
489 
490 //-----------------------------------------------------------------------------
Close(HIO2IF_ID id)491 HIO2IF_RESULT	CHio2If::Close(HIO2IF_ID id)
492 {
493 	if ( !IsValidID(id) ) return SetError(HIO2IF_ERROR_INVALID_ID);
494 
495 	LPHIO2IF_STATUS pStatus = m_cHioStatus[id];
496 	int chan = pStatus->m_nPcChan;
497 
498 	// Perform a close notification when connected to the target
499 	if ( pStatus->m_bConnect )
500 	{
501 		pStatus->m_bConnect	= FALSE;
502 		m_cHio2Dll.WriteMailbox(pStatus->m_hHIO,
503 			HIO2IF_SET_PACKET(chan, HIO2IF_CMD_CLOSE));
504 	}
505 
506 	BOOL result = m_cHio2Dll.Close(pStatus->m_hHIO);
507 
508 	// Just initialize, without deleting, given that re-opening might occur
509 	// (keep the channel number)
510 //	pStatus->m_nPcChan			= HIO2IF_INVALID_ID;
511 	pStatus->m_nDevType			= HIO2_DEVICE_INVALID;
512 	pStatus->m_hHIO				= HIO2IF_INVALID_HANDLE_VALUE;
513 	pStatus->m_nMode			= HIO2IF_MODE_NONE;
514 	pStatus->m_bReceived		= FALSE;
515 	pStatus->m_bSendPossible	= TRUE;
516 	pStatus->m_fncCallback		= NULL;
517 
518 	return result ? HIO2IF_RESULT_SUCCESS
519 		: SetFatal(HIO2IF_FATAL_CLOSE, chan, m_cHio2Dll.GetLastError());
520 }
521 
522 //-----------------------------------------------------------------------------
Exit()523 void	CHio2If::Exit()
524 {
525 	if ( !m_bInitialized ) return ;
526 
527 	// Perform a close notification when EXI channel is opened, and connection to the PC is available
528 	for (int i=0; i<m_cHioStatus.GetCount(); i++)
529 	{
530 		if ( m_cHioStatus[i]->m_hHIO != HIO2IF_INVALID_HANDLE_VALUE ) Close(i);
531 	}
532 
533 	// HIO2Exit() force-closes opened channels
534 	m_cHio2Dll.Exit();
535 	m_cHio2Dll.Release();
536 
537 	InitInstance();
538 	m_bInitialized = FALSE;
539 }
540 
541 //-----------------------------------------------------------------------------
AddDevicePath(HIO2DevicePath pathName)542 void	CHio2If::AddDevicePath(HIO2DevicePath pathName)
543 {
544 #ifndef	HW0
545 	LPSTR lpPath = new TCHAR [lstrlen(pathName) + 1];
546 	lstrcpy(lpPath, pathName);
547 	m_cDevices.push_back(lpPath);
548 #else	// HW0
549 	m_cDevices.push_back(pathName);
550 #endif	// HW0
551 }
552 
553 //-----------------------------------------------------------------------------
SetFatal(HIO2IF_ERROR errID,...)554 HIO2IF_RESULT	CHio2If::SetFatal(HIO2IF_ERROR errID, ...)
555 {
556 	va_list argptr;
557 
558 	va_start(argptr, errID);
559 	vsprintf_s( m_szMessage, sizeof( m_szMessage ), (char*)m_lpszErrorStrings[errID], argptr );
560 //	vsprintf( m_szMessage, (char*)m_lpszErrorStrings[errID], argptr );
561 	va_end(argptr);
562 	m_nLastError = errID;
563 
564 	return HIO2IF_RESULT_FATAL;
565 }
566 
567 //-----------------------------------------------------------------------------
SetError(HIO2IF_ERROR errID,...)568 HIO2IF_RESULT	CHio2If::SetError(HIO2IF_ERROR errID, ...)
569 {
570 	va_list argptr;
571 
572 	va_start(argptr, errID);
573 	vsprintf_s( m_szMessage, sizeof( m_szMessage ),(char*)m_lpszErrorStrings[errID], argptr );
574 //	vsprintf( m_szMessage, (char*)m_lpszErrorStrings[errID], argptr );
575 	va_end(argptr);
576 	m_nLastError = errID;
577 
578 	return HIO2IF_RESULT_ERROR;
579 }
580 
581 //-----------------------------------------------------------------------------
InitInstance()582 void	CHio2If::InitInstance()
583 {
584 #ifndef	HW0	// HW0
585 	for (int i=0; i<(int)m_cDevices.size(); i++) delete [] m_cDevices[i];
586 	m_cDevices.clear();
587 #else		// HW0
588 	m_cDevices.clear();
589 #endif
590 	m_cHioStatus.Clear();
591 }
592 
593 ///////////////////////////////////////////////////////////////////////////////
594 //
595 // Create a release Host I/O interface for PC
596 //
597 
Hio2CreateInterface(void)598 CHio2If*	Hio2CreateInterface(void)
599 {
600 	if ( l_pHio2If == NULL ) l_pHio2If = new CHio2If;
601 
602 	return l_pHio2If;
603 }
604 
Hio2ReleaseInterface(CHio2If * pHioIf)605 void	Hio2ReleaseInterface(CHio2If* pHioIf)
606 {
607 	ASSERT(l_pHio2If == pHioIf);
608 
609 	delete static_cast<CHio2If *>(pHioIf);
610 	l_pHio2If = NULL;
611 }
612 
613 // End of HioIfHost.cpp
614