Changes between Version 27 and Version 28 of CodeStyle


Ignore:
Timestamp:
05/30/21 20:09:47 (3 years ago)
Author:
Selva Nair
Comment:

Add a section on Windows and Unicode

Legend:

Unmodified
Added
Removed
Modified
  • CodeStyle

    v27 v28  
    9595  gettimeofday(&now, NULL);                                                                                                                                                                                   
    9696  printf("%"PRIi64".%06ld\n", (int64_t)now.tv_sec, (long)now.tv_usec);
     97}}}
     98
     99= Windows specific =
     100
     101OpenVPN core uses UTF-8 encoding for strings. These may be converted to and from UTF-16 used in Windows as required. Declare all strings explicitly as char * or wchar_t *. Use of TCHAR is not allowed. Call Windows API functions using their explicit ANSI or wide character variants: e.g., {{{CreateFileW}}} or {{{CreateFileA}}} instead of {{{CreateFile}}}. The core executable for Windows is built without -DUNICODE and -D_UNICODE.
     102
     103Sources for Windows-only executables and libraries such as openvpnserv.exe, tapctl.exe and openvpnmscia.dll partially depend on UNICODE (and in some cases _UNICODE) defined.  Also there is a widespread use of TCHAR as well as function names that resolve to single-byte or wide character variants depending on whether UNICODE is defined or not.
     104
     105However, in spite of appearances to the contrary, non-unicode builds are no longer supported. In new code declare wide strings as wchar_t * or WHCAR *. One may implicitly assume that all existing TCHAR would evaluate to WCHAR. For runtime and API calls use explicit function names instead of depending on UNICODE and/or _UNICODE are defined or not.
     106
     107In particular, do not use _tprintf family of stdio functions. Instead, use wprintf or printf variants as required. Use "%ls" as the print format specifications for wide strings. For narrow strings, "%s" may be used in printf family of functions, but in wprintf family use "%hs". Do not use "%S".
     108
     109For example, given the existing function,
     110
     111{{{#!c
     112MsgToEventLog(DWORD flags, LPCTSTR lpszMsg, ...);
     113}}}
     114
     115a new code snippet that calls it would be written as
     116
     117{{{#!c
     118const wchar_t *username;
     119const char *config;
     120...
     121MsgtoEvenLog(M_SYSERR, L"Failed to authorize profile <%hs> for user <%ls>", config, username);
    97122}}}
    98123