Porting Communications Software to Windows CE by Oliver Diener Listing One vstdio.h #ifndef _VSTDIOH_INCLUDED #define _VSTDIOH_INCLUDED #include extern int sprintf(char *buffer, const char *fmt, ...); extern int sscanf(char *buffer, const char *fmt, ...); extern char *ltoa( long value, char *string, int radix ); _inline unsigned char toupper(unsigned char c) { if (c >= 'a' && c <= 'z') return c-'a'+'A'; return c; } _inline int isdigit(unsigned char c) { if (c >= '0' && c <= '9') return 1; return 0; } _inline int isxdigit(unsigned char c) { if ((c >='0' && c <='9') || (c >='a'&& c <='f') || (c >='A' && c <='F')) return 1; return 0; } #define ansi2unicode(a) \ ( (a) == NULL ? NULL : ( \ _a_len = MultiByteToWideChar(CP_ACP, 0, a, -1, NULL, 0), \ _a_p = (unsigned short*) alloca(_a_len*2+2), \ MultiByteToWideChar(CP_ACP, 0, a, -1, _a_p, _a_len), \ _a_p) ) #define unicode2ansi(a) \ ( (a) == NULL ? NULL : ( \ _a_len = WideCharToMultiByte(CP_ACP, 0, a, -1, NULL, 0, NULL, NULL), \ _a_p = (unsigned short*) alloca(_a_len+1), \ WideCharToMultiByte(CP_ACP, 0, a, -1, (char *)_a_p, _a_len, NULL, NULL), \ (char *)_a_p) ) #endif /* _VSTDIOH_INCLUDED */ vstdio.c #ifdef UNICODE #include #include #include #include #define SMALL 0 #define BIG 1 static char digit[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; static char digitbig[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; static char * fillbuf(char *buf, char *src, int len, int leadnull, int digcount) { int i; if (digcount) { for (i = (digcount - len); i > 0; i--) { if (leadnull) *buf++ = '0'; else *buf++ = ' '; } } for (i = 0; i < len; i++) { *buf++ = *src++; } return buf; } static char * int2str(char *buf, int val, int leadnull, int digcount, int base, int big) { int b; char tmp[1024]; char *p = tmp; if (val < 0) { *p++ = '-'; val *= -1; } if (val == 0) *p++ = '0'; for (b = 1; (val/b) >= base; b *= base); while (val > 0) { if (big == BIG) *p++ = digitbig[(int)(val/b)]; else *p++ = digit[(int)(val/b)]; val = val - b * ((int)(val/b)); b /= base; } while (b >= 1) { *p++ = '0'; b /= base; } return fillbuf(buf, tmp, (p-tmp), leadnull, digcount); } char * str2int(char *buf, int *value, int base) { int val, i = 1; *value = 0; while (*buf == ' ') buf++; while (*buf != ' ' && *buf != '\0') { if (isdigit(*buf)) val = *buf - '0'; else if (isxdigit(*buf)) { toupper(*buf); val = 10 + *buf - 'A'; } *value = *value * i + val; i = base; buf++; } return buf; } int sprintf(char *buffer, const char *fmt, ...) { va_list ap; char tmp; const char *p; char *sval, cval, *q = buffer, *buf = buffer; int leadnull, digcount, first, ival; char tmp_buf[1024]; char *p_buf = tmp_buf; va_start(ap, fmt); /* ap points to first unnamed argument */ for (p = fmt; *p; p++) { if (*p != '%') { *buf++ = *p; continue; } tmp = *++p; leadnull = 0; digcount = 0; first = 1; while (isdigit(tmp)) { if ((tmp - '0') == 0 && first) { leadnull = 1; } else { digcount = (digcount * 10) + (tmp -'0'); } first = 0; tmp = *++p; } switch(tmp) { case 'd': case 'i': ival = va_arg(ap, int); buf = int2str(buf, ival, leadnull, digcount, 10, SMALL); break; case 'x': ival = va_arg(ap, int); buf = int2str(buf, ival, leadnull, digcount, 16, SMALL); break; case 'X': ival = va_arg(ap, int); buf = int2str(buf, ival, leadnull, digcount, 16, BIG); break; case 'c': cval = va_arg(ap, char); *buf++ = cval; break; case 's': for (sval = va_arg(ap, char*); *sval; sval++) *p_buf++ = *sval; buf = fillbuf(buf, tmp_buf, (p_buf-tmp_buf), leadnull, digcount); p_buf = tmp_buf; break; default: *buf++ = *p; break; } } va_end(ap); *buf++ = '\0'; return (buf - q); } int sscanf(char *buffer, const char *fmt, ...) { va_list ap; int rc = 0; const char *p; char tmp; char *buf = buffer; va_start(ap, fmt); /* ap points to first unnamed argument */ for (p = fmt; *p; p++) { if (*p != '%') continue; tmp = *++p; rc++; switch(tmp) { case 'd': case 'i': buf = str2int(buf, *(int **)ap, 10); va_arg(ap, int); break; case 'x': case 'X': buf = str2int(buf, *(int **)ap, 16); va_arg(ap, int); break; } } va_end(ap); return rc; } extern char * ltoa(long value, char *string, int radix) { string = int2str(string, value, 0, 0, radix, SMALL); *string = '\0'; return string; } #endif /* UNICODE */ Listing Two vfcntl.h #ifndef _VFCNTLH_INCLUDED #define _VFCNTLH_INCLUDED #define _O_RDONLY 0x0000 /* open for reading only */ #define _O_WRONLY 0x0001 /* open for writing only */ #define _O_RDWR 0x0002 /* open for reading and writing */ #define _O_APPEND 0x0008 /* writes done at eof */ #define _O_CREAT 0x0100 /* create and open file */ #define _O_TRUNC 0x0200 /* open and truncate */ #define _O_EXCL 0x0400 /* open only if file doesn't already exist */ #define _O_TEXT 0x4000 /* file mode is text (translated) */ #define _O_BINARY 0x8000 /* file mode is binary (untranslated) */ #define O_RDONLY _O_RDONLY #define O_WRONLY _O_WRONLY #define O_RDWR _O_RDWR #define O_APPEND _O_APPEND #define O_CREAT _O_CREAT #define O_TRUNC _O_TRUNC #define O_EXCL _O_EXCL #define O_TEXT _O_TEXT #define O_BINARY _O_BINARY #define O_RAW _O_BINARY #define O_TEMPORARY _O_TEMPORARY #define O_NOINHERIT _O_NOINHERIT #define O_SEQUENTIAL _O_SEQUENTIAL #define O_RANDOM _O_RANDOM #endif /* _VFCNTL_INCLUDED */ vio.h #ifndef _VIOH_INCLUDED #define _VIOH_INCLUDED extern int open( const char *filename, int oflag); extern int write( int handle, const void *buffer, unsigned int count ); extern int close( int handle ); #endif /* _VIOH_INCLUDED */ vio.c #ifdef _WIN32_WCE #include #include #include #include #include int open( const char *filename, int oflag) { V_USES_CONVERSION DWORD access = 0, creation = 0; if (oflag & O_RDONLY) access = GENERIC_READ; else if (oflag & O_WRONLY) access = GENERIC_WRITE; else if (oflag & O_RDWR) access = (GENERIC_WRITE | GENERIC_READ); if ((oflag & O_APPEND) && (oflag & O_CREAT)) creation = OPEN_ALWAYS; else if (oflag & O_APPEND) creation = OPEN_EXISTING; else if (oflag & O_CREAT) creation = CREATE_NEW; return (int) CreateFile(VTEXT(filename), access, 0, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL); } int write( int handle, const void *buffer, unsigned int count ) { DWORD counter; WriteFile((void*) handle, buffer, count, &counter, NULL); return counter; } int close( int handle ) { return CloseHandle((void*) handle); } #endif /* _WIN32_WCE */ Listing Three void CFaxDlg::OnSend() { USES_CONVERSION; // see MSDN TN059 Vport fax; // LUCA port object CString faxno, text, linkid; const char *linkid_ascii, *text_ascii; EditFaxNo.GetWindowText(faxno); // get faxno from edit control EditText.GetWindowText(text); // get message text from edit control linkid = _T("sff/fax/atmodem:") + faxno + _T("/async/com:1,speed=19200,flow=xonxoff"); // LUCA link identifer: use structured fax format converter // (SFF) over class 2 fax transmission (FAX) via Hayes // compatible modem (ATMODEM) connected to COM1 (COM) linkid_ascii = T2CA(linkid); // convert UNICODE to ASCII text_ascii = T2CA(text); fax.Vopen(linkid_ascii); // open LUCA port, start dialing fax.Vctl(V_WTIMEOUT, 60000); // set write timeout fax.Vwrite(text_ascii, strlen(text_ascii)); // send message fax.Vclose(); // close connection, LUCA will wait until // your fax has been sent } 5