[stunnel-users] public domain [PATCH] to stunnel v502 for WCE/W32: WCE port + a few fixes for W32

Pierre DELAAGE delaage.pierre at free.fr
Mon Jun 23 18:48:30 CEST 2014


Dear Michal, Dear All,
Please find enclosed a WCE/win32 patch that fixes various compilation 
and runtime bugs both for WCE and, in a smaller amount, for W32.

The patch is provided BOTH in an incremental version patch2/patch1 since 
my "patch1" W32 only version, and in cumulative form patch2/orig by 
comparison with the original 502 version (as found here: 
https://www.stunnel.org/downloads/stunnel-5.02.tar.gz).


Both patches are given in "diff -cr old new" format,
with old="v502-orig OR patch1" and new=patch2.


COMPILATION Environments :
==========================

To compile for WCE, I use MS EVC4 sp4 (free) + WCE SDK 420 on an XP sp2 
host system.


To compile for Win32, I use VC++ 9.0 (2008) Express Edition on an XP sp2 
host system.


SUMMARY of bugs/fixes :
=======================

For WCE:
========

WCE COMPILATION BUGS :
----------------------

WCE-CC01 (UNICODE version) : The sw simply does not compile because of 
lack fo some W32 specific services on WCE: ShellExecute, 
GetCurrentDirectory ....
See complete list further in that mail.

WCE-CC02 : ANSI support
Many "A" version of some system services are just missing :
CreateFileA,GetModuleFileNameA, GetMessageA,DispatchMessageA, 
CreateEventA, CreateWindowExA,RegisterClassA ,LoadCursorA ,LoadIconA,
PostMessageA, DefWindowProcA,DialogBoxIndirectParamA, FindResourceA, 
SetWindowTextA, SendDlgItemMessageA,SendMessageA, GetSaveFileNameA, 
InsertMenuA , LoadImageA, LoadMenuA, FormatMessageA,MessageBoxA
They can be easily rewritten from WCHAR version,
but I did not have time to do that.
Moreover, as UNICODE version supersedes ANSI version (I mean : "does the 
same and even more"), there is no urgent need for a pure ANSI version 
for WCE.
Anyway, I did my best to have a code, except missing "A" services, that 
compiles for both context.

Note that for W32, the code can be compiled either for ANSI or UNICODE.



WCE RUNTIME BUGS & fixes :
--------------------------

WCE-RT01 : the log window menu is NOT created (by CommandBar_InsermenuBar)
WCE-RT02 : Log Window stays empty : there is no display of the log file 
content
WCE-RT03 : When resizing or Changing the screen orientation (on some 
smartphones) from portrait to landscape and vice/versa, the commandBar 
DOES NOT resize properly to fit the main window size.
WCE-RT04 : When playing with CUSTOM file-icons (with some new code), and 
when A COMMUNICATION SERVICE IS CHANGING in STATUS, the matching ICON 
resources (for taskbar) are automatically deleted from the system memory 
so that, at a time, icons are just disappearing from the TASKBAR.
Note: this is not happening with DEFAULT icons loaded from rc file.
WCE-RT05 : With small screens phones, the main (log window) menu DOES 
NOT display completely on the screen: the menu labels are too large.
WCE-RT06 : conf file CANNOT be opened AND/OR read although there is NO 
security restriction (and while it can be read by older v434 stunnel 
version !): this is due to a change in CreateFile flags.

WCE COMPILATION ADDS  (evc.mak) :
---------------------------------
Removed /MT flags for X86 and emulator targets : that flag is NOT 
supported on WCE although CL.EXE for WCE is EXACTLY the same tool as 
CL.EXE for "VC6.0 for Pentium I/II cpus". Indeed, for WCE targets, there 
is no libcmt nor msvcrt libs on the target systems, for which /MT flags 
(or /MD) are leading the app to be linked to.
Those flags are only meaningful when CL targets a win32-Desktop platform.
Flags replaced for X86/emulator targets by explicit linking to corelibc 
and coredll libs AND "/NODEFAULTLIBS" flag.


For other targets: as "/NODEFAULTLIB  coredll.lib corelibc.lib" is ALSO 
a good lib list for any wce cpu, the option /MC (that means exactly the 
same) is just redundant and I removed it, just to have exactly the same 
LD flags for all WCE targets.



For W32
=======

W32 COMPILATION BUGS :
----------------------
W32-CC01 : "makeW32 clean" DOES NOT clean anything.
CAUSE : it's because of 3 typos in vc.mak: in clean rule the letter "O" 
is missing from the variable names "GUI-O-BJS" and "NOGUI-O-BJS"; also 
there is a BAD "slash" instead of a backslash in the "fd.obj" file name 
in SHAREOBJS list (that slash does not prevent compilation, but prevents 
DEL command working).
FIX : typos corrected.

W32 COMPILATION ADDS (in vc.mak) :
----------------------------------
Added explicit link to comctl32.lib (for InitCommonControls() call that 
I added to win_gui.c).


W32 RUN-TIME BUGS / Improvments :
---------------------------------
W32-RT01 : on classic XP theme, there is no separation between the menu 
of the main window and the client zone, giving the window a poor flat 
look (while usually other apps display a 3D inside border).
FIX : in win-gui.c, replaced CreateWindow by CreateWindowEx, with 
exactly the same parameters except the first, which is a 
WS_EX_STATICEDGE style bit giving 3D border to the client window in the 
log panel :
          edit_handle=CreateWindowEx(WS_EX_STATICEDGE....

W32-RT02 : with large screens, the Help menu is just too far to the 
right when every other command are grouped to the left.
On most of recent apps, the ? button is back to "the rightest" position 
on the ...LEFT menubar, NOT on the rightest position on the app window 
that can be very large.
FIX : removed the HELP flag in resources.rc, as for WCE. and replaced 
the label by just a "?".


W32-RT03 : in win-gui.c, UNICODE printf format specs :
EVERY printf using a TCHAR variable is now using a UNICODE/ANSI FORMAT 
STRING (#define'd) for explicit format specification for TCHAR strings :
because the compiler is NOT able to detect any inconsistency between 
type of data, and format spec, missing this FORMAT SPECS may lead to 
really bad behaviors...(reading a wstrinf as a char * just give a one 
car string...).
Remember : %s is %ls for WCHAR, and in fact %hs for "ansi" in ANSI 
printf. I repeat : for <<ANSI>>-printf that is used intensively even in 
UNICODE version of stunnel.

W32-RT04 : on Win32 Desktop, when Service version is installed, the 
"display name" of the stunnel service in the "Windows Service Control 
Manager" is just a minimalistic lower caps string "stunnel", while it 
could be more explicit.
In ui_win_gui.c I declared another UNICODE string for that, 
SERVICE_DISPLAY_NAME, which is valued to "Stunnel SSL wrapper", and kept 
"stunnel" as an internal service name used as a "key" to identify the 
service in the local service database.


W32-RT05 : on Win32 Desktop, When Service version is installed, it is 
missing some "description" of stunnel service in the "Windows Service 
Control Manager".I think stunnel deserves a more professional 
description: lack of description may lead to think that stunnel service 
may be something un-desireable...
I added one that is CUSTOMIZABLE as a resource in resources.rc.
IDS_SERVICE_DESC "SSL encryption wrapper between local/remote clients 
and local/remote servers"
This can be changed easily, and also localized if needed later...


WISH LIST :
===========
W001 :  the doc should mention, for icon files, that they MUST be ".ico" 
files for W32 version, and ".bmp" files for WCE.(indeed BMP are NOT 
working for W32; adding support for them for w32 would be trivial with 
my fully w32-compatible WCE code, while ".ico" support for WCE would 
require some extra work...).

W002 : CONF LOADING and icon files :
If an icon file is missing and/or in an improper format, stunnel just 
stops ! I consider that it should just log a message and continue with 
default icons...


W003 : In Win_gui.c : "return TRUE" on processed WM_XXXX messages is 
just wrong most of the time.
This should be replaced by "return 0", dixit MSDN.
Yes, I know, this is not logical but it is like this...



********************************************************************

                        DETAILED FIXES description for WCE

********************************************************************

For WCE:
========

WCE COMPILATION BUGS or fixes :
-------------------------------

1/ common.h :
no shfolder.h include file in WCE; (if needed, we will find a workaround 
for ShGetFolderPath in WCE)

2/ client.c :
parse_socket_error : a return is missing at line 933. Strange to note 
that VC++ 2009 did not see that bug, while the old EVC4 compiler can see it.

3/ protocol.c(538)
missing return at the end of imap_server().
	
4/ ui_win_gui.c

lpCmdline type on WCE :
on WCE, lpCmdline is ALWAYS WCHAR, even in <<ANSI>> compilation mode 
that is (hardly) possible on WCE, so that WCE ALWAYS need a "WCHAR to 
STR conversion", but in ANSI mode tstr2str INAPPROPRIATELY here expects 
a char* so that we need another conversion function : "wstr2str", see 
extra source in mywcedefs.c.
The lack of this routine gives a compilation error in WCE-ansi mode 
(WCE-ANSI will require more investigation later ...).

'_tputenv_s' undefined : rewritten for WCE in mywcedefs.c

'InsertMenuItem' undefined : replaced by InsertMenu both for WCE and W32

'MIIM_STRING' : undeclared identifier
'MFS_GRAYED' : undeclared identifier
Although menuiteminfo exists on WCE, some flags DO NOT, and all the code 
using menuiteminfo is useless in WCE by the lack of InsertMenuItem.
Anyway all this menu items insertion code has been replaced by a more 
simple way to insert menuitems, common to W32/WCE, by using traditional 
Win32 syntax (InsertMenuItem replaced by InsertMenu).

   'LR_LOADFROMFILE' : undeclared identifier
Although it is mentioned in MSDN library, this flag does NOT exist in 
WCE winuser.h, and it is USELESS to declare it the same it is in w32 
SDK: this does not work.
Consequently the WCE LoadImage is NOT able to load images <<from 
files>>, so I offer a replacement, built on WCE SHLoadBitmap,
defined in the new WCE companion file "mywcedefs.c": I have called that 
function "wceLoadIconFromFile".
This routine is able to load a 16x16 bitmap file (bmp extension) into an 
HICON win32 object.
Please note that it only supports ".BMP" files, NOT ".ico" files. That 
code can be used on W32 if needed (I tested it : it works).

'ShellExecute' undefined : rewritten for WCE in mywcedefs.c, on top of 
ShellExecuteEx.

'AllocateAndInitializeSid' undefined:
'FreeSid' undefined;
On WCE, the user is always admin, so all the isAdmin() code is useless 
and has been put in #ifndef _WIN32_WCE: on WCE, isAdmin() always returns 
TRUE.
	
	
errno_t and _tputenv_s() undefined :
redefined in mywcedefs.h/.c source file
	
'GetMenuItemCount' undefined:
This call does not exist in WCE.
it is used to test the end of a menu destruction loop:
it is easier and W32/WCE full compatible to just test the result of 
deleteItem(item 0) to stop the destruction loop.


GetCurrentDirectory does not exist in WCE : reimplemented in mywcedefs.c 
on top of GetModuleFileName.

5/ ui_win_cli.c

_tputenv_s needs a WCE implementation : provided by mywcedefs.c

str2tstr expects a LP(C)STR, not a "const char *" : explicit cast is 
necessary from char* to LPSTR.

6/ InterlockedExchange not defined for X86 or Emulator targets :
the CC flag /Dx86 was missing in evc.mak for those targets.


WCE LINKING ERRORS
------------------

options.obj : error LNK2001: unresolved external symbol WSAGetLastError
network.obj : error LNK2001: unresolved external symbol WSAGetLastError
stunnel.obj : error LNK2019: unresolved external symbol WSAGetLastError 
referenc
ed in function daemon_loop
ctx.obj : error LNK2001: unresolved external symbol WSAGetLastError
client.obj : error LNK2001: unresolved external symbol WSAGetLastError
log.obj : error LNK2001: unresolved external symbol WSAGetLastError
log.obj : error LNK2019: unresolved external symbol WSASetLastError 
referenced i
n function s_log
..\bin\ARMV4\stunnel.exe : fatal error LNK1120: 2 unresolved externals
NMAKE : fatal error U1077: 'link' : return code '0x460'
Stop.


FIX : evc.mak : link to winsock2 ws2.lib instead of old winsock.lib (!)


WCE RUNTIME bugs & fixes :
--------------------------

WCE-RT01 : CommandBar_InsermenuBar DOES NOT create the log window menu

At run-time CommandBar_InsermenuBar just fails with this error on WM6 
phones or emulator :

"CommandBar_InsertMenubar: error 120: This function is only valid in 
win32 mode"

After many investigations this message has two causes :
1/ HELP flag on menu resources, although documented in WCE SDK 420, is 
NOT supported on WCE !
2/ On WM6 emulator, the message is ""CommandBar_InsertMenubar: error 
120: This function is only valid in win32 mode"",
BUT on WM6.1.4 emulator the message is different ! it is :
"CommandBar_InsertMenubar: error1004: Invalid flags"
So that I was searching for an explanation in the wrong direction for a 
while..
FIX:
in resources.rc :
suppress the HELP flag, I say the FLAG, in the "&help" menu item of the 
main menu definition in the resources.rc file.
in evc.mak :
modified to define _WIN32_WCE flag for RC compilation, so that we can 
get different codes for WCE than W32 on some menus definition.

WCE-RT02 : Log Window stays empty : there is no display of the log file 
content.

CAUSE : on WCE WM_SHOWINDOW is NOT generated on "ShowWindow" call.
This msg DOES NOT exist in WCE MSDN, and EVEN IF it is really declared 
in include files !,
it is NOT produced on WCE devices/emulators.
FIX: both for W32 and WCE, use WM_WINDOWPOSCHANGED message that is 
generated in the same circumstances.
Nota: some better typing of "visible" as a BOOL is coded, fully 
consistent with MSDN WM_SHOWWINDOW or IsWindowVisible() specs.
Also I use explicitely the IsWindowVisible() function that is more 
reliable than the content of the WM_WINDOWPOSCHANGED msg to detect 
changes in visibility (many tests with that on WCE/W32).


WCE-RT03 : When resizing or Changing the screen orientation (on some WM6 
smartphones with sliding keyboards) from portrait to landscape and 
vice/versa, the commandBar DOES NOT resize properly to fit the main 
window size.

CAUSE : dixit MSDN, commandbars DO NOT resize automatically:
FIX: still dixit MSDN, some explicit TB_AUTOSIZE message must be sent to 
the commandBar on WM_SIZE on the main window, and AddAdornements must 
also be repeated,
to get a good redraw of the commandbar.


WCE-RT04 : When playing with CUSTOM file-icons (with some new code), and 
when A COMMUNICATION SERVICE IS CHANGING STATE, the matching ICON 
resources (for taskbar) are automatically deleted from the system memory 
so that, at a time, icons are just disappearing from the TASKBAR.
Note: this is not happening with DEFAULT icons loaded from rc file.

FIX : for WCE we have to Duplicate an Icon before the system drops it 
down when it replaces it by another icon.
Unfortunately, win32 "DuplicateIcon()" does NOT exist on WCE so...I 
rewrote it, in mywcedefs.c. Shortly speaking : by drawing an old Icon 
with transparency on some bitmap that I can feed to CreateIconIndirect() 
to re-create a duplicate icon.
Also, to be sure of the stability of the icon destruction behavior...I 
PERFORM it myself explicitely before asking the system to replace it !
That code is also compatible with W32 (but I kept it only active for WCE).


WCE-RT05 : With small screens phones, the main menu DOES NOT display 
completely on the screen, and the HELP and CLOSE commands are not 
accessible on the commandbar.

FIX : in resources.rc I changed some menuitem labels to something 
shorter..."HELP" is now "?" which is something quite standard nowadays...

WCE-RT06 : conf file CANNOT be opened AND/OR read while there is NO 
security restriction (and while it can be read by older v434 stunnel 
version !)

CAUSE: in file.c some rewrite of the file_open() function has occurred 
in some revision of the code, using some "SECURITY TOKEN ACCESS" 
"sophisticated" flags instead of the good old GENERIC r/w flags. Those 
new sophisticated flags are just messing things deeply on WCE, and 
possibly on some W32 platforms. Although the file opens with no errors, 
subsequent Read operations are just failing.
FIX : file.c, file_open() has been RESTORED to its good old code with 
GENERIC_READ and GENERIC_WRITE flags.


***************

I hope you will find this W32/WCE patch useful.


Yours sincerely,

Pierre Delaage






-------------- next part --------------
Seulement dans patch2: bin
Seulement dans patch2: obj
diff -cr orig/src/client.c patch2/src/client.c
*** orig/src/client.c	2014-04-12 20:55:57.000000000 +0200
--- patch2/src/client.c	2014-06-10 09:23:03.812500000 +0200
***************
*** 929,934 ****
--- 929,935 ----
      default:
          sockerror(text);
          longjmp(c->err, 1);
+ 		return 1; /* 20140610 pdelaage to avoid warning on W32/WCE */		
      }
  }
  
diff -cr orig/src/common.h patch2/src/common.h
*** orig/src/common.h	2014-04-14 13:40:40.000000000 +0200
--- patch2/src/common.h	2014-06-10 08:49:06.406250000 +0200
***************
*** 222,228 ****
--- 222,230 ----
  #include <windows.h>
  
  #include <process.h>     /* _beginthread */
+ #ifndef _WIN32_WCE /* pdelaage 20140520 : this file does not exist in WCE; if needed, a replacement for SHGetFolderPath will be provided for WCE */
  #include <shfolder.h>    /* SHGetFolderPath */
+ #endif
  #include <tchar.h>
  
  #include "resources.h"
diff -cr orig/src/evc.mak patch2/src/evc.mak
*** orig/src/evc.mak	2013-05-20 07:23:11.000000000 +0200
--- patch2/src/evc.mak	2014-06-21 20:57:18.828125000 +0200
***************
*** 1,8 ****
  # wce.mak for stunnel.exe by Michal Trojnara 2006-2012
  # with help of Pierre Delaage <delaage.pierre at free.fr>
  #
  # DEFAULTLIB management: only 2 are necessary
! # defaultlibS as given for CLxxx in the MS doc ARE WRONG
  
  # !!!!!!!!!!!!!!
  # CUSTOMIZE THIS according to your wcecompat and openssl directories
--- 1,25 ----
  # wce.mak for stunnel.exe by Michal Trojnara 2006-2012
  # with help of Pierre Delaage <delaage.pierre at free.fr>
+ # pdelaage 20140610 : added UNICODE optional FLAG, always ACTIVE on WCE because of poor ANSI support
+ # pdelaage 20140610 : added _WIN32_WCE flag for RC compilation, to preprocess out "HELP" unsupported menu flag on WCE
+ # pdelaage 20140610 : added new source mywcedefs.c for more WCE equivalent to some W32 services
+ # pdelaage 20140610 : ws2 lib is required to get WSAGetLastError routine (absent from winsock lib)
+ # pdelaage 20140610 : /Dx86 flag required for X86/Emulator targets, to get proper definition for InterlockedExchange
+ # pdelaage 20140610 : /MT flag is NON-SENSE for X86-WCE platforms, it is only meaningful for X86-W32-Desktop.
+ #                     for X86-WCE targets, although compiler "cl.exe" is REALLY the same as desktop W32 VS6 C++ compiler,
+ #                     the MT flags relating to LIBCMT is useless BECAUSE LIBCMT does NOT exist on WCE. No msvcrt on WCE either...
+ 
+ # pdelaage 20140610 :  Note on /MC flag 
+ # For other targets than X86/Emulator, /MC flag is redundant with "/nodefaultlib coredll.lib corelibc.lib" LD lib list.
+ # For << X86 / Emulator >> target, as the cl.exe compiler IS the SAME as the standard VS6.0 C++ compiler for Desktop Pentium processor, 
+ # /MC flag is in fact NOT existing, thus requiring an explicit linking with core libs by using : 
+ # /NODEFAULTLIB coredll.lib corelibc.lib,
+ # something that is correct for any WCE target, X86 and other, and leading /MC flag to be useless ALSO for other target than X86.
+ 
+ 
  #
  # DEFAULTLIB management: only 2 are necessary
! # defaultlibS, as given for CLxxx in the MS doc, ARE WRONG
  
  # !!!!!!!!!!!!!!
  # CUSTOMIZE THIS according to your wcecompat and openssl directories
***************
*** 10,19 ****
  
  # Modify this to point to your actual openssl compile directory
  # (You did already compile openssl, didn't you???)
! SSLDIR=C:\Users\standard\Documents\Dvts\Contrib\openssl\v1.0.0a\patched3
  
  # Note that we currently use a multi-target customized version of legacy Essemer/wcecompat lib
! COMPATDIR=C:\Users\standard\Documents\Dvts\Contrib\wcecompat\v12\patchedX86
  
  WCEVER=420
  
--- 27,36 ----
  
  # Modify this to point to your actual openssl compile directory
  # (You did already compile openssl, didn't you???)
! SSLDIR=C:\Users\pdelaage\Dvts\Contrib\openssl\v1.0.2-stable-SNAP-20121213\patch3
  
  # Note that we currently use a multi-target customized version of legacy Essemer/wcecompat lib
! COMPATDIR=C:\Users\pdelaage\Dvts\Contrib\wcecompat\v12\patched3emu
  
  WCEVER=420
  
***************
*** 24,30 ****
  !IF "$(TARGETCPU)"=="X86"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! MORECFLAGS=/MT
  
  # TODO: continue list for other targets : see wcecompat/wcedefs.mak for a good ref.
  # see also openssl/util/pl/vc-32.pl, also link /?
--- 41,48 ----
  !IF "$(TARGETCPU)"=="X86"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! #pdelaage 20140621 /Dx86 for inline defs of InterlockedExchange inline in winbase.h; no more /MT
! MORECFLAGS=/Dx86
  
  # TODO: continue list for other targets : see wcecompat/wcedefs.mak for a good ref.
  # see also openssl/util/pl/vc-32.pl, also link /?
***************
*** 34,50 ****
  !ELSEIF "$(TARGETCPU)"=="emulator"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! MORECFLAGS=/MT
  
  !ELSEIF "$(TARGETCPU)"=="MIPS16" || "$(TARGETCPU)"=="MIPSII" || "$(TARGETCPU)"=="MIPSII_FP" || "$(TARGETCPU)"=="MIPSIV" || "$(TARGETCPU)"=="MIPSIV_FP"
  WCETARGETCPU=_MIPS_
  LDTARGETCPU=MIPS
! MORECFLAGS=/DMIPS /MC
  
  !ELSEIF "$(TARGETCPU)"=="SH3" || "$(TARGETCPU)"=="SH4"
  WCETARGETCPU=SHx
  LDTARGETCPU=$(TARGETCPU)
! MORECFLAGS=/MC
  
  !ELSE
  # default is ARM !
--- 52,71 ----
  !ELSEIF "$(TARGETCPU)"=="emulator"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! #pdelaage 20140621 /Dx86 for inline defs of InterlockedExchange inline in winbase.h; no more /MT
! MORECFLAGS=/Dx86
  
  !ELSEIF "$(TARGETCPU)"=="MIPS16" || "$(TARGETCPU)"=="MIPSII" || "$(TARGETCPU)"=="MIPSII_FP" || "$(TARGETCPU)"=="MIPSIV" || "$(TARGETCPU)"=="MIPSIV_FP"
  WCETARGETCPU=_MIPS_
  LDTARGETCPU=MIPS
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=/DMIPS
  
  !ELSEIF "$(TARGETCPU)"=="SH3" || "$(TARGETCPU)"=="SH4"
  WCETARGETCPU=SHx
  LDTARGETCPU=$(TARGETCPU)
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=
  
  !ELSE
  # default is ARM !
***************
*** 52,59 ****
  # the following flag is required by (eg) winnt.h, and is different from targetcpu (armV4)
  WCETARGETCPU=ARM
  LDTARGETCPU=ARM
! MORECFLAGS=/MC
! 
  !ENDIF
  
  # ceutilsdir probably useless (nb : were tools from essemer; but ms delivers a cecopy anyway, see ms dld site)
--- 73,80 ----
  # the following flag is required by (eg) winnt.h, and is different from targetcpu (armV4)
  WCETARGETCPU=ARM
  LDTARGETCPU=ARM
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=
  !ENDIF
  
  # ceutilsdir probably useless (nb : were tools from essemer; but ms delivers a cecopy anyway, see ms dld site)
***************
*** 65,76 ****
  INCLUDES=-I$(SSLDIR)\inc32 -I$(COMPATDIR)\include -I"$(SDKDIR)\include\$(TARGETCPU)"
  # for X86 and other it appears that /MC or /ML flags are absurd,
  # we always have to override runtime lib list to coredll and corelibc
! LIBS=/NODEFAULTLIB winsock.lib wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
  
  DEFINES=/DHOST=\"$(TARGETCPU)-WCE-eVC-$(WCEVER)\"
  # /O1 /Oi more correct vs MS doc
! CFLAGS=/nologo $(MORECFLAGS) /O1 /Oi /W3 /WX /GF /Gy $(DEFINES) /D$(WCETARGETCPU) /D$(TARGETCPU) /DUNDER_CE=$(WCEVER) /D_WIN32_WCE=$(WCEVER) /DUNICODE -D_UNICODE $(INCLUDES)
! RFLAGS=$(DEFINES) $(INCLUDES)
  # LDFLAGS: since openssl >> 098a (eg 098h) out32dll is out32dll_targetCPU for WCE
  # delaage added $(TARGETCPU) in legacy Essemer/wcecompat libpath
  # to ease multitarget compilation without recompiling everything
--- 86,102 ----
  INCLUDES=-I$(SSLDIR)\inc32 -I$(COMPATDIR)\include -I"$(SDKDIR)\include\$(TARGETCPU)"
  # for X86 and other it appears that /MC or /ML flags are absurd,
  # we always have to override runtime lib list to coredll and corelibc
! #LIBS=/NODEFAULTLIB winsock.lib wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
! LIBS=/NODEFAULTLIB ws2.lib      wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
  
  DEFINES=/DHOST=\"$(TARGETCPU)-WCE-eVC-$(WCEVER)\"
+ # pdelaage 20140610 added unicode flag : ALWAYS ACTIVE on WCE, because of poor ANSI support by the MS SDK
+ UNICODEFLAGS=/DUNICODE -D_UNICODE
  # /O1 /Oi more correct vs MS doc
! CFLAGS=/nologo $(MORECFLAGS) /O1 /Oi /W3 /WX /GF /Gy $(DEFINES) /D$(WCETARGETCPU) /D$(TARGETCPU) /DUNDER_CE=$(WCEVER) /D_WIN32_WCE=$(WCEVER) $(UNICODEFLAGS) $(INCLUDES)
! # pdelaage 20140610 : RC compilation requires D_WIN32_WCE flag to comment out unsupported "HELP" flag in menu definition, in resources.rc file
! RFLAGS=$(DEFINES) /D_WIN32_WCE=$(WCEVER) $(INCLUDES)
! 
  # LDFLAGS: since openssl >> 098a (eg 098h) out32dll is out32dll_targetCPU for WCE
  # delaage added $(TARGETCPU) in legacy Essemer/wcecompat libpath
  # to ease multitarget compilation without recompiling everything
***************
*** 90,96 ****
  OBJS=$(OBJ)\stunnel.obj $(OBJ)\ssl.obj $(OBJ)\ctx.obj $(OBJ)\verify.obj \
  	$(OBJ)\file.obj $(OBJ)\client.obj $(OBJ)\protocol.obj $(OBJ)\sthreads.obj \
  	$(OBJ)\log.obj $(OBJ)\options.obj $(OBJ)\network.obj \
! 	$(OBJ)\resolver.obj $(OBJ)\str.obj $(OBJ)\fd.obj
  
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
--- 116,122 ----
  OBJS=$(OBJ)\stunnel.obj $(OBJ)\ssl.obj $(OBJ)\ctx.obj $(OBJ)\verify.obj \
  	$(OBJ)\file.obj $(OBJ)\client.obj $(OBJ)\protocol.obj $(OBJ)\sthreads.obj \
  	$(OBJ)\log.obj $(OBJ)\options.obj $(OBJ)\network.obj \
! 	$(OBJ)\resolver.obj $(OBJ)\str.obj $(OBJ)\fd.obj $(OBJ)\mywcedefs.obj
  
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
diff -cr orig/src/file.c patch2/src/file.c
*** orig/src/file.c	2014-03-06 00:25:33.000000000 +0100
--- patch2/src/file.c	2014-06-12 09:21:45.875000000 +0200
***************
*** 49,65 ****
      /* open file */
      switch(mode) {
      case FILE_MODE_READ:
!         desired_access=FILE_READ_DATA;
          creation_disposition=OPEN_EXISTING;
          break;
      case FILE_MODE_APPEND:
!         desired_access=FILE_APPEND_DATA;
!         creation_disposition=OPEN_ALWAYS;
          break;
      case FILE_MODE_OVERWRITE:
!         desired_access=FILE_WRITE_DATA;
          creation_disposition=CREATE_ALWAYS;
!         break;
      default: /* invalid mode */
          return NULL;
      }
--- 49,66 ----
      /* open file */
      switch(mode) {
      case FILE_MODE_READ:
!         desired_access=GENERIC_READ;/* pdelaage 20140610 WCE: good old flags supported on w32/WCE, while FILE_READ_DATA is FAILING on WCE; 
! 		this FILE_READ_DATA flag PREVENTS read from various folders on WCE phones such as \stunnel\ or \Storage card\, or on WCE emulator \stunnel\.... where we find stunnel.conf file sometimes...*/
          creation_disposition=OPEN_EXISTING;
          break;
      case FILE_MODE_APPEND:
!         desired_access=GENERIC_WRITE; /* pdelaage 20140610: FILE_APPEND_DATA; back to old code W32/WCE compatible */
!         creation_disposition=OPEN_ALWAYS;/* pdelaage 20140610 : I disagree with OPEN_ALWAYS that creates the file if not existing. I suggest : OPEN_EXISTING */
          break;
      case FILE_MODE_OVERWRITE:
!         desired_access=GENERIC_WRITE; /* pdelaage 20140610:FILE_WRITE_DATA; back to old code W32/WCE compatible */
          creation_disposition=CREATE_ALWAYS;
!         break;	
      default: /* invalid mode */
          return NULL;
      }
diff -cr orig/src/makew32.bat patch2/src/makew32.bat
*** orig/src/makew32.bat	2010-11-17 21:20:14.000000000 +0100
--- patch2/src/makew32.bat	2014-06-09 15:49:25.546875000 +0200
***************
*** 2,7 ****
--- 2,8 ----
  TITLE W32 STUNNEL 
  ::pdelaage 20101026: for use with MS VCexpress 2008 (v9)
  ::some trick to avoid re-pollution of env vars as much as possible
+ ::pdelaage 20140609: makew32 "UNICODESUPPORT=" to compile a UNICODE version
  
  :: In multitarget compilation environment, it is better to open a new cmd.exe window
  :: to avoid pollution of PATH from, eg, some previous WCE compilation attempts.
Seulement dans patch2/src: mywcedefs.c
Seulement dans patch2/src: mywcedefs.h
diff -cr orig/src/protocol.c patch2/src/protocol.c
*** orig/src/protocol.c	2014-04-13 13:15:21.000000000 +0200
--- patch2/src/protocol.c	2014-06-10 09:29:17.406250000 +0200
***************
*** 535,540 ****
--- 535,542 ----
      }
      str_free(line);
      longjmp(c->err, 2); /* don't reset */
+ 
+ 	return NULL; /* pdelaage 20140610 : just to avoid compilation warning on W32/WCE */
  }
  
  /**************************************** nntp */
diff -cr orig/src/resolver.c patch2/src/resolver.c
*** orig/src/resolver.c	2014-04-11 09:44:10.000000000 +0200
--- patch2/src/resolver.c	2014-06-09 15:57:21.406250000 +0200
***************
*** 92,98 ****
  #if defined(USE_WIN32) && !defined(_WIN32_WCE)
      HINSTANCE handle;
  
!     handle=LoadLibrary("ws2_32.dll"); /* IPv6 in Windows XP or higher */
      if(handle) {
          s_getaddrinfo=(GETADDRINFO)GetProcAddress(handle, "getaddrinfo");
          s_freeaddrinfo=(FREEADDRINFO)GetProcAddress(handle, "freeaddrinfo");
--- 92,98 ----
  #if defined(USE_WIN32) && !defined(_WIN32_WCE)
      HINSTANCE handle;
  
!     handle=LoadLibrary(TEXT("ws2_32.dll")); /* IPv6 in Windows XP or higher *//* pdelaage 20140529...unicode ! */
      if(handle) {
          s_getaddrinfo=(GETADDRINFO)GetProcAddress(handle, "getaddrinfo");
          s_freeaddrinfo=(FREEADDRINFO)GetProcAddress(handle, "freeaddrinfo");
***************
*** 101,107 ****
              return; /* IPv6 detected -> OK */
          FreeLibrary(handle);
      }
!     handle=LoadLibrary("wship6.dll"); /* experimental IPv6 for Windows 2000 */
      if(handle) {
          s_getaddrinfo=(GETADDRINFO)GetProcAddress(handle, "getaddrinfo");
          s_freeaddrinfo=(FREEADDRINFO)GetProcAddress(handle, "freeaddrinfo");
--- 101,107 ----
              return; /* IPv6 detected -> OK */
          FreeLibrary(handle);
      }
!     handle=LoadLibrary(TEXT("wship6.dll")); /* experimental IPv6 for Windows 2000 *//* pdelaage 20140609...unicode ! */
      if(handle) {
          s_getaddrinfo=(GETADDRINFO)GetProcAddress(handle, "getaddrinfo");
          s_freeaddrinfo=(FREEADDRINFO)GetProcAddress(handle, "freeaddrinfo");
diff -cr orig/src/resources.h patch2/src/resources.h
*** orig/src/resources.h	2014-01-02 09:13:37.000000000 +0100
--- patch2/src/resources.h	2014-06-23 16:37:20.562500000 +0200
***************
*** 31,33 ****
--- 31,35 ----
  #define IDM_HOMEPAGE        52
  
  #define IDM_PEER_MENU       60
+ 
+ #define IDS_SERVICE_DESC    70 /* pdelaage 20140623 : added description for Win32 Service Manager */
diff -cr orig/src/resources.rc patch2/src/resources.rc
*** orig/src/resources.rc	2014-03-06 00:27:52.000000000 +0100
--- patch2/src/resources.rc	2014-06-23 16:39:47.156250000 +0200
***************
*** 45,60 ****
          MENUITEM SEPARATOR
          MENUITEM "&Close",                  IDM_CLOSE
      END
      POPUP "&Configuration"
      BEGIN
          MENUITEM "&Edit Configuration",      IDM_EDIT_CONFIG
          MENUITEM "&Reload Configuration",    IDM_RELOAD_CONFIG
      END
      POPUP "&Save Peer Certificate"
      BEGIN
          MENUITEM "dummy",                   0, GRAYED
      END
!     POPUP "&Help",                          HELP
      BEGIN
          MENUITEM "&About",                  IDM_ABOUT
          MENUITEM SEPARATOR
--- 45,73 ----
          MENUITEM SEPARATOR
          MENUITEM "&Close",                  IDM_CLOSE
      END
+    /* pdelaage 20140610: in WCE, this menu is too large for smart phones */
+ #ifdef _WIN32_WCE
+     POPUP "&Config."
+ #else
      POPUP "&Configuration"
+ #endif	
      BEGIN
          MENUITEM "&Edit Configuration",      IDM_EDIT_CONFIG
          MENUITEM "&Reload Configuration",    IDM_RELOAD_CONFIG
      END
+    /* pdelaage 20140610: in WCE, this menu is too large for smart phones */	
+ #ifdef _WIN32_WCE
+     POPUP "&Save Peer Certs."
+ #else
      POPUP "&Save Peer Certificate"
+ #endif		
+ 
      BEGIN
          MENUITEM "dummy",                   0, GRAYED
      END
!    /* pdelaage 20140610: in WCE, the HELP flag, although documented, is NOT SUPPORTED, use addornements instead ? */
!    /* pdelaage 20140610: in W32, the HELP flag is nowadays useless : with wide screens, it is painful to go the right end to get help */
! 	POPUP "&?"    /* pdelaage 20140610: both to fit space on WCE phones, and for "standard" look and feel on W32, ? replaces "Help" */
      BEGIN
          MENUITEM "&About",                  IDM_ABOUT
          MENUITEM SEPARATOR
***************
*** 89,94 ****
--- 102,109 ----
  ABOUTBOX DIALOG DISCARDABLE  0, 0, 140, 68
  STYLE DS_MODALFRAME|DS_CENTER|WS_POPUP|WS_CAPTION|WS_SYSMENU
  CAPTION "About stunnel"
+ /* pdelaage 20140609 : no more ugly font a la windows 3.1...stunnel deserves to look more "smart" */
+ FONT 8, "MS Sans Serif"
  BEGIN
      ICON            IDI_STUNNEL_MAIN, -1,                        9,  8,  18, 20
      LTEXT           "stunnel version", -1,                      30,  4,  52,  8
***************
*** 103,108 ****
--- 118,125 ----
  PASSBOX DIALOG DISCARDABLE 0, 0, 158, 51
  STYLE DS_MODALFRAME|DS_CENTER|WS_POPUP|WS_CAPTION|WS_SYSMENU
  CAPTION ""
+ /* pdelaage 20140609 : no more ugly font a la windows 3.1...stunnel deserves to look more "smart" */
+ FONT 8, "MS Sans Serif"
  BEGIN
      ICON            IDI_STUNNEL_MAIN, -1,     8,  6, 18, 20
      LTEXT           "Pass phrase:", -1,      33,  9, 50,  8
***************
*** 122,124 ****
--- 139,145 ----
      PUSHBUTTON      "Cancel",IDCANCEL,      101, 30, 50, 14
  END
  
+ STRINGTABLE
+ {
+ IDS_SERVICE_DESC	"SSL encryption wrapper between local/remote clients and local/remote servers"
+ }
diff -cr orig/src/ui_win_cli.c patch2/src/ui_win_cli.c
*** orig/src/ui_win_cli.c	2014-03-26 18:13:01.000000000 +0100
--- patch2/src/ui_win_cli.c	2014-06-11 00:22:46.343750000 +0200
***************
*** 37,59 ****
  
  #include "common.h"
  #include "prototypes.h"
  
  int main(int argc, char *argv[]) {
      static struct WSAData wsa_state;
!     char *c, stunnel_exe_path[MAX_PATH];
  
      /* set current working directory and engine path */
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
!     c=strrchr(stunnel_exe_path, '\\'); /* last backslash */
      if(c) /* found */
!         c[1]='\0'; /* truncate program name */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
!         fprintf(stderr, "Cannot set directory to %s", stunnel_exe_path);
          return 1;
      }
  #endif
!     _putenv_s("OPENSSL_ENGINES", stunnel_exe_path);
  
      str_init(); /* initialize per-thread string management */
      if(WSAStartup(MAKEWORD(1, 1), &wsa_state))
--- 37,67 ----
  
  #include "common.h"
  #include "prototypes.h"
+ #ifdef _WIN32_WCE
+ #include "mywcedefs.h" /* pdelaage 20140610 for _tputenv_s */
+ #endif
  
  int main(int argc, char *argv[]) {
      static struct WSAData wsa_state;
!     TCHAR *c, stunnel_exe_path[MAX_PATH];/* pdelaage 20140609 UNICODE : TCHAR for both vars, because of GetModuleFileName */
  
      /* set current working directory and engine path */
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
!     c=_tcsrchr(stunnel_exe_path, TEXT('\\')); /* last backslash *//* pdelaage 20140526 UNICODE : strrchr replaced by _tcsrchr */
      if(c) /* found */
!         c[1]=TEXT('\0'); /* truncate program name *//* pdelaage 20140526 UNICODE : strrchr replaced by _tcsrchr, because of SetCurrentDirectory and  stunnel_exe_path */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
! #ifdef UNICODE	/* pdelaage 20140526 QUESTION : shoud'nt we use s_log instead of fprintf ?? */
!         fprintf(stderr, "Cannot set directory to %ls", stunnel_exe_path);/* pdelaage 20140526 UNICODE format spec support */
! #else
!         fprintf(stderr, "Cannot set directory to %hs", stunnel_exe_path);
! #endif
! 		
          return 1;
      }
  #endif
!     _tputenv_s(TEXT("OPENSSL_ENGINES"), stunnel_exe_path);/* pdelaage 20140526 UNICODE *//* pdelaage 20140610 : WCE implementation in mywcedefs.c */
  
      str_init(); /* initialize per-thread string management */
      if(WSAStartup(MAKEWORD(1, 1), &wsa_state))
***************
*** 107,114 ****
      /* log to Windows CE debug output stream */
      LPTSTR tstr;
  
!     tstr=str2tstr(line);
!     RETAILMSG(TRUE, (TEXT("%s\r\n"), tstr));
      str_free(tstr);
  #else
      fputs(line, stderr);
--- 115,122 ----
      /* log to Windows CE debug output stream */
      LPTSTR tstr;
  
!     tstr=str2tstr((LPSTR) line);/* pdelaage 20140610 : str2tstr strictly expects a "const LPSTR" */
!     RETAILMSG(TRUE, (TEXT("%s\r\n"),  tstr));
      str_free(tstr);
  #else
      fputs(line, stderr);
diff -cr orig/src/ui_win_gui.c patch2/src/ui_win_gui.c
*** orig/src/ui_win_gui.c	2014-05-12 08:31:13.000000000 +0200
--- patch2/src/ui_win_gui.c	2014-06-23 18:02:39.828125000 +0200
***************
*** 44,49 ****
--- 44,61 ----
  #endif
  #include "resources.h"
  
+ #ifdef _WIN32_WCE /* pdelaage 20140610 : some ports of win32 services to WCE, or some specific WCE services */
+ #include "mywcedefs.h"
+ #endif
+ 
+ #ifdef UNICODE /* pdelaage 20140623 : TSTR and TCAR ansi-printf format specs : YES ansi-printf can print Wchar strings ...*/
+ #define TCAR_PRINTF_FORMAT "%lc"
+ #define TSTR_PRINTF_FORMAT "%ls"
+ #else
+ #define TCAR_PRINTF_FORMAT "%hc"
+ #define TSTR_PRINTF_FORMAT "%hs"
+ #endif
+ 
  #define LOG_LINES 1000
  
  #ifdef _WIN32_WCE
***************
*** 54,60 ****
  #else /* MSDN claims that _WIN32 is always defined */
  #define STUNNEL_PLATFORM "Win32"
  #endif
! #define SERVICE_NAME "stunnel"
  #endif
  
  /* mingw-Patches-1825044 is missing in Debian Squeeze */
--- 66,74 ----
  #else /* MSDN claims that _WIN32 is always defined */
  #define STUNNEL_PLATFORM "Win32"
  #endif
! 
! #define SERVICE_NAME TEXT("stunnel") /* pdelaage 20140609 UNICODE */
! #define SERVICE_DISPLAY_NAME TEXT("Stunnel SSL wrapper") /* pdelaage 20140623: Nicer name to be displayed in Service Control Manager */
  #endif
  
  /* mingw-Patches-1825044 is missing in Debian Squeeze */
***************
*** 89,95 ****
  /* NT Service related function */
  #ifndef _WIN32_WCE
  NOEXPORT int service_initialize(void);
! NOEXPORT int service_install(LPTSTR);
  NOEXPORT int service_uninstall(void);
  NOEXPORT int service_start(void);
  NOEXPORT int service_stop(void);
--- 103,110 ----
  /* NT Service related function */
  #ifndef _WIN32_WCE
  NOEXPORT int service_initialize(void);
! /* pdelaage 20140609 : wrong prototype, the DEFINITION code further in that file is with LPSTR only, not lpTstr...static int service_install(LPTSTR); */
! NOEXPORT int service_install(LPSTR);
  NOEXPORT int service_uninstall(void);
  NOEXPORT int service_start(void);
  NOEXPORT int service_stop(void);
***************
*** 126,132 ****
  static SERVICE_STATUS_HANDLE serviceStatusHandle=0;
  #endif
  
! static volatile int visible=0;
  static volatile int error_mode=1; /* no valid configuration was ever loaded */
  static HANDLE config_ready=NULL; /* reload without a valid configuration */
  static LONG new_logs=0;
--- 141,148 ----
  static SERVICE_STATUS_HANDLE serviceStatusHandle=0;
  #endif
  
! /* pdelaage 20140610: now visible is more appropriately a BOOL, as stated by MSDN */
! static volatile BOOL visible = FALSE;/* int visible=0; */
  static volatile int error_mode=1; /* no valid configuration was ever loaded */
  static HANDLE config_ready=NULL; /* reload without a valid configuration */
  static LONG new_logs=0;
***************
*** 149,155 ****
  #endif
          int nCmdShow) {
      LPSTR command_line;
!     char *c, stunnel_exe_path[MAX_PATH];
  #ifndef _WIN32_WCE
      char *errmsg;
  #endif
--- 165,172 ----
  #endif
          int nCmdShow) {
      LPSTR command_line;
!  /* 20140609 pdelaage   char *c, stunnel_exe_path[MAX_PATH]; */
!     TCHAR *c, stunnel_exe_path[MAX_PATH];/* 20140609 pdelaage : UNICODE support for GetModuleFileName on W32/WCE */
  #ifndef _WIN32_WCE
      char *errmsg;
  #endif
***************
*** 160,197 ****
      str_init(); /* initialize per-thread string management */
      ghInst=this_instance;
  #ifdef _WIN32_WCE
!     command_line=tstr2str(lpCmdLine);
  #else
!     command_line=lpCmdLine;
  #endif
  
      parse_cmdline(command_line); /* setup global cmdline structure */
  
!     GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
  
  #ifndef _WIN32_WCE
      /* find previous instances of the same executable */
      if(!cmdline.service && !cmdline.install && !cmdline.uninstall &&
              !cmdline.start && !cmdline.stop) {
!         EnumWindows(enum_windows, (LPARAM)stunnel_exe_path);
          if(cmdline.exit)
              return 0; /* in case EnumWindows didn't find a previous instance */
      }
  #endif
  
      /* set current working directory and engine path */
!     c=strrchr(stunnel_exe_path, '\\'); /* last backslash */
      if(c) /* found */
!         c[1]='\0'; /* truncate program name */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
!         errmsg=str_printf("Cannot set directory to %s", stunnel_exe_path);
          message_box(errmsg, MB_ICONERROR);
          str_free(errmsg);
          return 1;
      }
  #endif
!     _putenv_s("OPENSSL_ENGINES", stunnel_exe_path);
  
      if(initialize_winsock())
          return 1;
--- 177,215 ----
      str_init(); /* initialize per-thread string management */
      ghInst=this_instance;
  #ifdef _WIN32_WCE
!     command_line=wstr2str(lpCmdLine);/* pdelaage 20140610 : on WCE, even in <<ANSI>> compilation mode that is ALSO possible on WCE, lpCmdline is ALWAYS WCHAR, so that WCE ALWAYS need a WCHAR to STR conversion, but in ANSI mode tstr2str INAPPROPRIATELY here expects a char* so that we need another conversion function : see extra source in mywcedefs.c */
  #else
!     command_line=lpCmdLine; /* pdelaage 20140610, on win32 lpcmdline is always ANSI string...for the moment.*/
  #endif
  
      parse_cmdline(command_line); /* setup global cmdline structure */
  
!     GetModuleFileName(0, stunnel_exe_path, MAX_PATH);/* 20140609 pdelaage : requires UNICODE strings */
  
  #ifndef _WIN32_WCE
      /* find previous instances of the same executable */
      if(!cmdline.service && !cmdline.install && !cmdline.uninstall &&
              !cmdline.start && !cmdline.stop) {
!         EnumWindows(enum_windows, (LPARAM)stunnel_exe_path);/* 20140609 pdelaage : BE CAREFUL that enum_windows will CORRECTLY CAST to UNICODE ! done by my contribution there ...*/
          if(cmdline.exit)
              return 0; /* in case EnumWindows didn't find a previous instance */
      }
  #endif
  
      /* set current working directory and engine path */
!     c=_tcsrchr(stunnel_exe_path, TEXT('\\')); /* last backslash *//* pdelaage 20140609 unicode */
      if(c) /* found */
!         c[1]=TEXT('\0'); /* truncate program name */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
! 	/*  pdelaage 20140609 : UNICODE in printf format spec */
!         errmsg=str_printf("Cannot set directory to "TSTR_PRINTF_FORMAT, stunnel_exe_path);		
          message_box(errmsg, MB_ICONERROR);
          str_free(errmsg);
          return 1;
      }
  #endif
!     _tputenv_s(TEXT("OPENSSL_ENGINES"), stunnel_exe_path);/*  pdelaage 20140609 : UNICODE */
  
      if(initialize_winsock())
          return 1;
***************
*** 216,224 ****
  NOEXPORT BOOL CALLBACK enum_windows(HWND other_window_handle, LPARAM lParam) {
      DWORD pid;
      HINSTANCE hInstance;
!     char window_exe_path[MAX_PATH];
      HANDLE process_handle;
!     char *stunnel_exe_path=(char *)lParam;
  
      if(!other_window_handle)
          return TRUE;
--- 234,242 ----
  NOEXPORT BOOL CALLBACK enum_windows(HWND other_window_handle, LPARAM lParam) {
      DWORD pid;
      HINSTANCE hInstance;
!     TCHAR window_exe_path[MAX_PATH];/* pdelaage 20140609 UNICODE */
      HANDLE process_handle;
!     TCHAR *stunnel_exe_path=(TCHAR *)lParam;/* pdelaage 20140529 UNICODE */
  
      if(!other_window_handle)
          return TRUE;
***************
*** 235,241 ****
          CloseHandle(process_handle);
          return TRUE;
      }
!     if(strcmp(stunnel_exe_path, window_exe_path)) {
          CloseHandle(process_handle);
          return TRUE;
      }
--- 253,259 ----
          CloseHandle(process_handle);
          return TRUE;
      }
!     if(_tcscmp(stunnel_exe_path, window_exe_path)) { /* pdelaage 20140529 UNICODE */
          CloseHandle(process_handle);
          return TRUE;
      }
***************
*** 315,320 ****
--- 333,341 ----
      MSG msg;
      LPTSTR classname=TEXT("stunnel_main_window_class");
  
+ 	/* Ensure commctrl.dll is loaded *//* pdelaage 20140621 addition, needed -eg- for WCE commandbars ... */
+ 	InitCommonControls(); /* pdelaage 20140621 : Good practice before using common controls, both for WCE and W32 */
+ 
      /* register the class */
  #ifndef _WIN32_WCE
      wc.cbSize=sizeof wc;
***************
*** 383,389 ****
          s_log(LOG_DEBUG, "Window message: %d", message);
  #endif
      switch(message) {
!     case WM_CREATE:
  #ifdef _WIN32_WCE
          /* create command bar */
          command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1);
--- 404,410 ----
          s_log(LOG_DEBUG, "Window message: %d", message);
  #endif
      switch(message) {
!     case WM_CREATE:			
  #ifdef _WIN32_WCE
          /* create command bar */
          command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1);
***************
*** 396,404 ****
  #endif
  
          /* create child edit window */
!         edit_handle=CreateWindow(TEXT("EDIT"), NULL,
!             WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
!             0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL);
  #ifndef _WIN32_WCE
          SendMessage(edit_handle, WM_SETFONT,
              (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
--- 417,426 ----
  #endif
  
          /* create child edit window */
!         edit_handle=CreateWindowEx(WS_EX_STATICEDGE, /* pdelaage 20140610 : for better look and feel, 3D edges to separate from menubar...over Win31 flat style */
! 		TEXT("EDIT"), NULL,
! 		WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
!         0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL);
  #ifndef _WIN32_WCE
          SendMessage(edit_handle, WM_SETFONT,
              (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
***************
*** 413,424 ****
  #ifdef _WIN32_WCE
          MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle),
              rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE);
  #else
          MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE);
  #endif
          UpdateWindow(edit_handle);
          /* CommandBar_Show(command_bar_handle, TRUE); */
!         return TRUE;
  
      case WM_SETFOCUS:
          SetFocus(edit_handle);
--- 435,451 ----
  #ifdef _WIN32_WCE
          MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle),
              rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE);
+ 
+ /* pdelaage 20140610 WCE : dixit MSDN, and indeed, commandbars do not resize automatically unless providing this code, necessary on "sliding-keyboard" OR "auto-rotating screen orientation" smart phones when switching from portrait to landscape display and vice/versa */
+ 		SendMessage(command_bar_handle, TB_AUTOSIZE, 0L, 0L);
+ 		CommandBar_AlignAdornments(command_bar_handle);/* pdelaage 20140610 WCE: MSDN says we have to repeat this for auto-repositioning of Help btn */
+ 			
  #else
          MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE);
  #endif
          UpdateWindow(edit_handle);
          /* CommandBar_Show(command_bar_handle, TRUE); */
!         return TRUE;/* pdelaage 20140621, TODO: both for W32 and WCE, this should be "return 0", not "TRUE"... dixit MSDN. Same remark for most of the msg processing here */
  
      case WM_SETFOCUS:
          SetFocus(edit_handle);
***************
*** 433,446 ****
          ShowWindow(main_window_handle, SW_HIDE);
          return TRUE;
  
!     case WM_SHOWWINDOW:
!         visible=wParam; /* setup global variable */
          if(tray_menu_handle)
              CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG,
                  visible ? MF_CHECKED : MF_UNCHECKED);
          if(visible)
!             update_logs();
!         return TRUE;
  
      case WM_DESTROY:
  #ifdef _WIN32_WCE
--- 460,478 ----
          ShowWindow(main_window_handle, SW_HIDE);
          return TRUE;
  
! /* pdelaage 20140610: I made "visible" a real BOOL, as defined by MSDN doc on WM_SHOWWINDOW...instead of an int between 0 and 1...*/
! /*	case WM_SHOWWINDOW: 
! 		visible= (BOOL) wParam;  *//*  setup global variable 
! */
! /* pdelaage 20140610: WM_SHOWWINDOW does NOT exist on WCE, so replaced by WM_WINDOWPOSCHANGED W32/WCE compatible */
! 	case WM_WINDOWPOSCHANGED :
!         visible = IsWindowVisible(main_window_handle);/* setup global variable *//* pdelaage 20140610: more reliable than msg content */	 
          if(tray_menu_handle)
              CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG,
                  visible ? MF_CHECKED : MF_UNCHECKED);
          if(visible)
!             update_logs();		
! 		break;/* return TRUE;*//* pdelaage 20140610: WM_WINDOWPOSCHANGED MUST go to DefProc to properly refresh window appearance (WM_SIZE/WM_MOVE)*/
  
      case WM_DESTROY:
  #ifdef _WIN32_WCE
***************
*** 895,901 ****
      HMENU tray_peer_list=NULL;
      char *str;
      unsigned int section_number;
!     MENUITEMINFO mii;
  
      /* purge menu peer lists */
  #ifndef _WIN32_WCE
--- 927,934 ----
      HMENU tray_peer_list=NULL;
      char *str;
      unsigned int section_number;
! 
! /* 20140610 pdelaage unsupported on WCE, useless with common code in W32 (and thus generates a compilation warning) :     MENUITEMINFO mii; */
  
      /* purge menu peer lists */
  #ifndef _WIN32_WCE
***************
*** 908,915 ****
      if(tray_menu_handle)
          tray_peer_list=GetSubMenu(GetSubMenu(tray_menu_handle, 0), 2);
      if(tray_peer_list)
!         while(GetMenuItemCount(tray_peer_list)) /* purge old menu */
!             DeleteMenu(tray_peer_list, 0, MF_BYPOSITION);
  
      /* initialize data structures */
      number_of_sections=0;
--- 941,948 ----
      if(tray_menu_handle)
          tray_peer_list=GetSubMenu(GetSubMenu(tray_menu_handle, 0), 2);
      if(tray_peer_list)
! /* pdelaage 20140610 : W32/WCE trick because GetMenuItemCount does not exist on WCE */
!         while (DeleteMenu(tray_peer_list, 0, MF_BYPOSITION) == TRUE) {;}; /* purge old menu */	
  
      /* initialize data structures */
      number_of_sections=0;
***************
*** 942,947 ****
--- 975,981 ----
          section->chain=NULL;
  
          /* insert new menu item */
+ /* pdelaage 20140610 : this code is not supported by WCE, and the same can be achieved by a SHORTER common code for W32/WCE       		
          mii.cbSize=sizeof mii;
          mii.fMask=MIIM_STRING|MIIM_DATA|MIIM_ID|MIIM_STATE;
          mii.fType=MFT_STRING;
***************
*** 957,962 ****
--- 991,1007 ----
          if(tray_peer_list)
              if(!InsertMenuItem(tray_peer_list, section_number, TRUE, &mii))
                  ioerror("InsertMenuItem");
+ */				
+ 	/* pdelaage 20140610, W32/WCE short COMMON code to create menuitems			*/
+ #ifndef _WIN32_WCE
+         if(main_peer_list)
+             if(InsertMenu(main_peer_list, section_number, MF_BYPOSITION | MF_STRING | MF_GRAYED, IDM_PEER_MENU+section_number, section->file) == 0)
+                 ioerror("InsertMenu");
+ #endif
+         if(tray_peer_list)
+             if(InsertMenu(tray_peer_list, section_number, MF_BYPOSITION | MF_STRING | MF_GRAYED, IDM_PEER_MENU+section_number, section->file) == 0)
+                 ioerror("InsertMenu");
+ 				
          ++section_number;
      }
      if(hwnd)
***************
*** 986,995 ****
  ICON_IMAGE load_icon_file(const char *name) {
      LPTSTR tname;
      ICON_IMAGE icon;
! 
      tname=str2tstr((LPSTR)name);
      icon=LoadImage(NULL, tname, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
          GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE);
      str_free(tname);
      return icon;
  }
--- 1031,1044 ----
  ICON_IMAGE load_icon_file(const char *name) {
      LPTSTR tname;
      ICON_IMAGE icon;
! 	
      tname=str2tstr((LPSTR)name);
+ #ifdef _WIN32_WCE /* pdelaage 20140610 : LR_LOADFROMFILE unsupported in WCE, cannot be replaced by SHLoadDIBitmap in this context, but... */
+ 	icon=wceLoadIconFromFile(tname);/* pdelaage 20140610  : ...with some standard W32 coding, an equivalent to loadimage for BMP files  (not ICO) is possible, for WCE...working also for W32 if needed */
+ #else	
      icon=LoadImage(NULL, tname, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
          GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE);
+ #endif		
      str_free(tname);
      return icon;
  }
***************
*** 998,1003 ****
--- 1047,1054 ----
      NOTIFYICONDATA nid;
      static ICON_TYPE previous_icon=ICON_NONE;
      ICON_TYPE current_icon;
+ 	HICON prevIcon_l = (HICON) NULL; /* pdelaage 20140610 WCE */
+ 	BOOL retval_l = FALSE; /* pdelaage 20140610 WCE */
  
      if(!global_options.option.taskbar) { /* save menu resources */
          if(tray_menu_handle) { /* disabled in the new configuration */
***************
*** 1018,1024 ****
      nid.uCallbackMessage=WM_SYSTRAY; /* notification message */
      nid.hWnd=hwnd; /* window to receive notifications */
      if(num<0) {
!         _stprintf(nid.szTip, TEXT("Server is down"));
          current_icon=ICON_ERROR;
      } else if(num>0) {
          _stprintf(nid.szTip, TEXT("%d active session(s)"), num);
--- 1069,1075 ----
      nid.uCallbackMessage=WM_SYSTRAY; /* notification message */
      nid.hWnd=hwnd; /* window to receive notifications */
      if(num<0) {
!         _stprintf(nid.szTip, TEXT("Server is down"));/* pdelaage 20140621 : Be careful that on WCE, szTip is ALWAYS WCHAR. Anyway ANSI version of stunnel for WCE, although possible with some port effort, is of no practical interest since UNICODE covers ANSI... */
          current_icon=ICON_ERROR;
      } else if(num>0) {
          _stprintf(nid.szTip, TEXT("%d active session(s)"), num);
***************
*** 1029,1038 ****
      }
      nid.hIcon=global_options.icon[current_icon];
      if(current_icon!=previous_icon) {
!         nid.uFlags|=NIF_ICON;
!         previous_icon=current_icon;
!     }
!     if(Shell_NotifyIcon(NIM_MODIFY, &nid)) /* modify tooltip */
          return; /* OK: taskbar icon exists */
      /* tooltip update failed - try to create the icon */
      nid.uFlags|=NIF_ICON;
--- 1080,1097 ----
      }
      nid.hIcon=global_options.icon[current_icon];
      if(current_icon!=previous_icon) {
! #ifdef _WIN32_WCE /* pdelaage 20140610 : on WCE, the replaced Icon will be DELETED and LOST from the system resources, so that we have to duplicate it before losing it, and in the objective to restore it later. */
! 		if (previous_icon != ICON_NONE) 
! 		{
! 		prevIcon_l = global_options.icon[previous_icon];
! 		global_options.icon[previous_icon] = DuplicateIcon((HINSTANCE) NULL, prevIcon_l);
! 		DestroyIcon(prevIcon_l);/* pdelaage 20140610: ok, the WCE system will do that, but it is better to do it explicitely, either if one day WCE doesn't do it anymore AND/OR if this code is reused in W32: something absolutely possible ...*/
! 		}
! #endif		
!         nid.uFlags|=NIF_ICON;		
!         previous_icon=current_icon;		
!     }	
! 	if(Shell_NotifyIcon(NIM_MODIFY, &nid)) /* modify tooltip */
          return; /* OK: taskbar icon exists */
      /* tooltip update failed - try to create the icon */
      nid.uFlags|=NIF_ICON;
***************
*** 1083,1110 ****
  }
  
  NOEXPORT void edit_config(HWND main_window_handle) {
!     char cwd[MAX_PATH], *conf_path;
! 
      /* TODO: port it to WCE */
      if(is_admin()) {
!         ShellExecute(main_window_handle, TEXT("open"),
!             TEXT("notepad.exe"), configuration_file,
              NULL, SW_SHOWNORMAL);
      } else { /* UAC workaround */
          if(strchr(configuration_file, '\\')) {
              conf_path=str_dup(configuration_file);
          } else {
!             GetCurrentDirectory(MAX_PATH, cwd);
!             conf_path=str_printf("%s\\%s", cwd, configuration_file);
          }
          ShellExecute(main_window_handle, TEXT("runas"),
!             TEXT("notepad.exe"), conf_path,
!             NULL, SW_SHOWNORMAL);
          str_free(conf_path);
      }
  }
  
  NOEXPORT BOOL is_admin(void) {
      SID_IDENTIFIER_AUTHORITY NtAuthority={SECURITY_NT_AUTHORITY};
      PSID admin_group;
      BOOL retval;
--- 1142,1186 ----
  }
  
  NOEXPORT void edit_config(HWND main_window_handle) {
!     TCHAR cwd[MAX_PATH];/* pdelaage 20140609 : unicode because of GetCurrentDirectory */
!     char *conf_path;
! 	TCHAR *conf_string; /* pdelaage 20140609 : needed for UNICODE ShellExecute, because "configuration_file" is JUST ASCII !! */
! 	
      /* TODO: port it to WCE */
+ 	/* pdelaage 20140610 : DONE ! for ShellExecute in mywcedefs.c */
      if(is_admin()) {
! 		conf_string = str2tstr(configuration_file);
! 	
!         ShellExecute(main_window_handle, TEXT("open"), /* pdelaage 20140610 : reimplemenred for WCE, see mywcedefs.c */
!             TEXT("notepad.exe"), conf_string,/* pdelaage 20140609 : now UNICODE correct */
! /* pdelaage 20140610 : TODO : notepad is NOT available on CE, we have to find/suggest a free replacement: some exist. */			
              NULL, SW_SHOWNORMAL);
+ 
+ 		str_free(conf_string);	
+ 		
      } else { /* UAC workaround */
          if(strchr(configuration_file, '\\')) {
              conf_path=str_dup(configuration_file);
          } else {
!             GetCurrentDirectory(MAX_PATH, cwd);/* pdelaage 20140610 : reimplemenred for WCE, see mywcedefs.c */
! 			/*  pdelaage 20140621 : UNICODE in printf format spec */
!             conf_path=str_printf(TSTR_PRINTF_FORMAT"\\%s", cwd, configuration_file);
          }
+ 		
+ 		conf_string = str2tstr(conf_path);
+ 				
          ShellExecute(main_window_handle, TEXT("runas"),
!             TEXT("notepad.exe"), conf_string, /* pdelaage 20140609 : now UNICODE correct */
! /* pdelaage 20140610 : TODO : notepad is NOT available on CE, we have to find/suggest a free replacement: some exist. */					
!             NULL, SW_SHOWNORMAL);	
! 			
!  		str_free(conf_string);				
          str_free(conf_path);
      }
  }
  
  NOEXPORT BOOL is_admin(void) {
+ #ifndef _WIN32_WCE
      SID_IDENTIFIER_AUTHORITY NtAuthority={SECURITY_NT_AUTHORITY};
      PSID admin_group;
      BOOL retval;
***************
*** 1118,1123 ****
--- 1194,1202 ----
          FreeSid(admin_group);
      }
      return retval;
+ #else
+ 	return TRUE; /* pdelaage 20140610 :on WCE, user is always admin */
+ #endif		
  }
  
  /**************************************** windows service */
***************
*** 1127,1133 ****
  NOEXPORT int service_initialize(void) {
      SERVICE_TABLE_ENTRY serviceTable[]={{0, 0}, {0, 0}};
  
!     serviceTable[0].lpServiceName=SERVICE_NAME;
      serviceTable[0].lpServiceProc=service_main;
      global_options.option.taskbar=0; /* disable taskbar for security */
      if(!StartServiceCtrlDispatcher(serviceTable)) {
--- 1206,1212 ----
  NOEXPORT int service_initialize(void) {
      SERVICE_TABLE_ENTRY serviceTable[]={{0, 0}, {0, 0}};
  
!     serviceTable[0].lpServiceName=SERVICE_NAME;/* pdelaage 20140525 : UNICODE */
      serviceTable[0].lpServiceProc=service_main;
      global_options.option.taskbar=0; /* disable taskbar for security */
      if(!StartServiceCtrlDispatcher(serviceTable)) {
***************
*** 1139,1163 ****
  
  NOEXPORT int service_install(LPSTR command_line) {
      SC_HANDLE scm, service;
!     char stunnel_exe_path[MAX_PATH], *service_path;
! 
      scm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if(!scm) {
          error_box("OpenSCManager");
          return 1;
      }
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
!     service_path=str_printf("\"%s\" -service %s", stunnel_exe_path, command_line);
!     service=CreateService(scm, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS,
          SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
!         SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, service_path,
          NULL, NULL, NULL, NULL, NULL);
      str_free(service_path);
      if(!service) {
          error_box("CreateService");
          CloseServiceHandle(scm);
          return 1;
      }
      message_box("Service installed", MB_ICONINFORMATION);
      CloseServiceHandle(service);
      CloseServiceHandle(scm);
--- 1218,1260 ----
  
  NOEXPORT int service_install(LPSTR command_line) {
      SC_HANDLE scm, service;
!     TCHAR stunnel_exe_path[MAX_PATH], *tservice_path;/* pdelaage 20140609: UNICODE for GetModuleFileName, CreateService */
!     char *service_path;
! 	
! 	TCHAR service_description_string[256];/* pdelaage 20140621: Added service description for Services Manager */
! 	SERVICE_DESCRIPTION service_description;
! 	
      scm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if(!scm) {
          error_box("OpenSCManager");
          return 1;
      }
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
! 	/* pdelaage 20140609 : we CAN mix TCHAR* and char* in printf...provided we use the proper h or l FORMAT SPEC */
!     service_path=str_printf("\""TSTR_PRINTF_FORMAT"\" -service %hs", stunnel_exe_path, command_line);
! 
! 	tservice_path = str2tstr(service_path);
! 	
!     service=CreateService(scm, SERVICE_NAME, SERVICE_DISPLAY_NAME, /* pdelaage 20140623: Added service display-name for Service Manager */
! 		SERVICE_ALL_ACCESS,
          SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
!         SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, tservice_path,
          NULL, NULL, NULL, NULL, NULL);
+     str_free(tservice_path);
      str_free(service_path);
      if(!service) {
          error_box("CreateService");
          CloseServiceHandle(scm);
          return 1;
      }
+ 	
+ 	/* pdelaage 20140623 : set more explicit description for the service, in Windows Service Control Manager */
+ 	if (LoadString(ghInst, IDS_SERVICE_DESC, service_description_string, sizeof(service_description_string)))
+ 	{
+ 	service_description.lpDescription = service_description_string;
+ 	ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &service_description);
+ 	}
+ 	
      message_box("Service installed", MB_ICONINFORMATION);
      CloseServiceHandle(service);
      CloseServiceHandle(scm);
diff -cr orig/src/vc.mak patch2/src/vc.mak
*** orig/src/vc.mak	2014-06-09 01:15:37.000000000 +0200
--- patch2/src/vc.mak	2014-06-21 17:54:40.734375000 +0200
***************
*** 1,6 ****
--- 1,12 ----
  # vc.mak by Michal Trojnara 1998-2014
  # with help of David Gillingham <dgillingham at gmail.com>
  # with help of Pierre Delaage <delaage.pierre at free.fr>
+ # pdelaage 20140609 : added UNICODE optional FLAG
+ # pdelaage 20140609 : added WX (fails on warning) flag to detect subtle error prone cast
+ # pdelaage 20140609 : added _CRT_NON_CONFORMING_SWPRINTFS to explicitely support old fashioned stprintf in ui_win_gui.c
+ # pdelaage 20140610 : BUG FIX : no clean working because of a typo in GUIOBJS and NOGUIOBJS names in clean rule
+ # pdelaage 20140610 : BUG FIX : no clean working because of a typo in SHAREOBJS list ($(OBJ)/fd.obj instead of xx\xx)
+ # pdelaage 20140610 : Explicit link to comctl32.lib for InitCommonControls call
  
  # the compilation requires:
  # - Visual C++ 2005 Express Edition with Platform SDK
***************
*** 8,13 ****
--- 14,21 ----
  # - Visual C++ 2005 Professional Edition
  # - Visual C++ 2008 Express Edition
  
+ 
+ 
  !IF [ml64.exe /help >NUL 2>&1]
  TARGET=win32
  !ELSE
***************
*** 24,30 ****
  #FIPSDIR=$(SSLDIR)\include
  #LIBDIR=$(SSLDIR)\lib
  # or compile one yourself
! SSLDIR=..\..\openssl-1.0.1h-$(TARGET)
  INCDIR=$(SSLDIR)\inc32
  FIPSDIR=$(SSLDIR)\inc32
  LIBDIR=$(SSLDIR)\out32dll
--- 32,39 ----
  #FIPSDIR=$(SSLDIR)\include
  #LIBDIR=$(SSLDIR)\lib
  # or compile one yourself
! # pdelaage 20140609 SSLDIR=..\..\openssl-1.0.1h-$(TARGET)
! SSLDIR=C:\Users\pdelaage\Dvts\Contrib\openssl\v1.0.2-stable-SNAP-20121213\patch1
  INCDIR=$(SSLDIR)\inc32
  FIPSDIR=$(SSLDIR)\inc32
  LIBDIR=$(SSLDIR)\out32dll
***************
*** 44,61 ****
  	$(OBJ)\verify.obj $(OBJ)\file.obj $(OBJ)\client.obj \
  	$(OBJ)\protocol.obj $(OBJ)\sthreads.obj $(OBJ)\log.obj \
  	$(OBJ)\options.obj $(OBJ)\network.obj $(OBJ)\resolver.obj \
!  	$(OBJ)\str.obj $(OBJ)/fd.obj
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
  	
  CC=cl
  LINK=link
  
! CFLAGS=/MD /W3 /O2 /nologo /I"$(INCDIR)" /I"$(FIPSDIR)"
  LDFLAGS=/NOLOGO
  
  SHAREDLIBS=ws2_32.lib user32.lib shell32.lib
! GUILIBS=advapi32.lib comdlg32.lib crypt32.lib gdi32.lib psapi.lib
  NOGUILIBS=
  SSLLIBS=/LIBPATH:"$(LIBDIR)" libeay32.lib ssleay32.lib
  # static linking:
--- 53,79 ----
  	$(OBJ)\verify.obj $(OBJ)\file.obj $(OBJ)\client.obj \
  	$(OBJ)\protocol.obj $(OBJ)\sthreads.obj $(OBJ)\log.obj \
  	$(OBJ)\options.obj $(OBJ)\network.obj $(OBJ)\resolver.obj \
!  	$(OBJ)\str.obj $(OBJ)\fd.obj
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
  	
  CC=cl
  LINK=link
  
! # pdelaage 20140529 added unicode flag : because w32 unicode version helps to debug...W32/WCE ansi/unicode version...
! !ifdef UNICODESUPPORT
! UNICODEFLAGS=/DUNICODE -D_UNICODE
! !else
! UNICODEFLAGS=
! !endif 
! 
! # pdelaage 20140609 WX warning as error to detect subtle cast problems in ansi/unicode management.
! MORECFLAGS=/WX $(UNICODEFLAGS) /D_CRT_NON_CONFORMING_SWPRINTFS
! CFLAGS=/MD /W3 /O2 /nologo  $(MORECFLAGS) /I"$(INCDIR)" /I"$(FIPSDIR)"
  LDFLAGS=/NOLOGO
  
  SHAREDLIBS=ws2_32.lib user32.lib shell32.lib
! GUILIBS=advapi32.lib comctl32.lib comdlg32.lib crypt32.lib gdi32.lib psapi.lib
  NOGUILIBS=
  SSLLIBS=/LIBPATH:"$(LIBDIR)" libeay32.lib ssleay32.lib
  # static linking:
***************
*** 73,80 ****
  
  clean:
  	-@ del $(SHAREDOBJS) >NUL 2>&1
! 	-@ del $(GUIBJS) >NUL 2>&1
! 	-@ del $(NOGUIBJS) >NUL 2>&1
  #	-@ del *.manifest >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe.manifest >NUL 2>&1
--- 91,98 ----
  
  clean:
  	-@ del $(SHAREDOBJS) >NUL 2>&1
! 	-@ del $(GUIOBJS) >NUL 2>&1
! 	-@ del $(NOGUIOBJS) >NUL 2>&1
  #	-@ del *.manifest >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe.manifest >NUL 2>&1
-------------- next part --------------
Seulement dans patch2/bin: ARMV4
Seulement dans patch2/bin: emulator
Les fichiers patch1/bin/win32/stunnel.exe et patch2/bin/win32/stunnel.exe sont différents.
Les fichiers patch1/bin/win32/stunnel.exp et patch2/bin/win32/stunnel.exp sont différents.
Les fichiers patch1/bin/win32/stunnel.lib et patch2/bin/win32/stunnel.lib sont différents.
Les fichiers patch1/bin/win32/tstunnel.exe et patch2/bin/win32/tstunnel.exe sont différents.
Les fichiers patch1/bin/win32/tstunnel.exp et patch2/bin/win32/tstunnel.exp sont différents.
Les fichiers patch1/bin/win32/tstunnel.lib et patch2/bin/win32/tstunnel.lib sont différents.
Seulement dans patch2/bin: X86
Seulement dans patch2/obj: ARMV4
Seulement dans patch2/obj: emulator
Les fichiers patch1/obj/win32/client.obj et patch2/obj/win32/client.obj sont différents.
Les fichiers patch1/obj/win32/ctx.obj et patch2/obj/win32/ctx.obj sont différents.
Les fichiers patch1/obj/win32/fd.obj et patch2/obj/win32/fd.obj sont différents.
Les fichiers patch1/obj/win32/file.obj et patch2/obj/win32/file.obj sont différents.
Les fichiers patch1/obj/win32/log.obj et patch2/obj/win32/log.obj sont différents.
Les fichiers patch1/obj/win32/network.obj et patch2/obj/win32/network.obj sont différents.
Les fichiers patch1/obj/win32/options.obj et patch2/obj/win32/options.obj sont différents.
Les fichiers patch1/obj/win32/protocol.obj et patch2/obj/win32/protocol.obj sont différents.
Les fichiers patch1/obj/win32/resolver.obj et patch2/obj/win32/resolver.obj sont différents.
Les fichiers patch1/obj/win32/resources.res et patch2/obj/win32/resources.res sont différents.
Les fichiers patch1/obj/win32/ssl.obj et patch2/obj/win32/ssl.obj sont différents.
Les fichiers patch1/obj/win32/sthreads.obj et patch2/obj/win32/sthreads.obj sont différents.
Les fichiers patch1/obj/win32/str.obj et patch2/obj/win32/str.obj sont différents.
Les fichiers patch1/obj/win32/stunnel.obj et patch2/obj/win32/stunnel.obj sont différents.
Les fichiers patch1/obj/win32/ui_win_cli.obj et patch2/obj/win32/ui_win_cli.obj sont différents.
Les fichiers patch1/obj/win32/ui_win_gui.obj et patch2/obj/win32/ui_win_gui.obj sont différents.
Les fichiers patch1/obj/win32/verify.obj et patch2/obj/win32/verify.obj sont différents.
Seulement dans patch2/obj: X86
diff -cr patch1/src/client.c patch2/src/client.c
*** patch1/src/client.c	2014-04-12 20:55:57.000000000 +0200
--- patch2/src/client.c	2014-06-10 09:23:03.812500000 +0200
***************
*** 929,934 ****
--- 929,935 ----
      default:
          sockerror(text);
          longjmp(c->err, 1);
+ 		return 1; /* 20140610 pdelaage to avoid warning on W32/WCE */		
      }
  }
  
diff -cr patch1/src/common.h patch2/src/common.h
*** patch1/src/common.h	2014-04-14 13:40:40.000000000 +0200
--- patch2/src/common.h	2014-06-10 08:49:06.406250000 +0200
***************
*** 222,228 ****
--- 222,230 ----
  #include <windows.h>
  
  #include <process.h>     /* _beginthread */
+ #ifndef _WIN32_WCE /* pdelaage 20140520 : this file does not exist in WCE; if needed, a replacement for SHGetFolderPath will be provided for WCE */
  #include <shfolder.h>    /* SHGetFolderPath */
+ #endif
  #include <tchar.h>
  
  #include "resources.h"
diff -cr patch1/src/evc.mak patch2/src/evc.mak
*** patch1/src/evc.mak	2013-05-20 07:23:11.000000000 +0200
--- patch2/src/evc.mak	2014-06-21 20:57:18.828125000 +0200
***************
*** 1,8 ****
  # wce.mak for stunnel.exe by Michal Trojnara 2006-2012
  # with help of Pierre Delaage <delaage.pierre at free.fr>
  #
  # DEFAULTLIB management: only 2 are necessary
! # defaultlibS as given for CLxxx in the MS doc ARE WRONG
  
  # !!!!!!!!!!!!!!
  # CUSTOMIZE THIS according to your wcecompat and openssl directories
--- 1,25 ----
  # wce.mak for stunnel.exe by Michal Trojnara 2006-2012
  # with help of Pierre Delaage <delaage.pierre at free.fr>
+ # pdelaage 20140610 : added UNICODE optional FLAG, always ACTIVE on WCE because of poor ANSI support
+ # pdelaage 20140610 : added _WIN32_WCE flag for RC compilation, to preprocess out "HELP" unsupported menu flag on WCE
+ # pdelaage 20140610 : added new source mywcedefs.c for more WCE equivalent to some W32 services
+ # pdelaage 20140610 : ws2 lib is required to get WSAGetLastError routine (absent from winsock lib)
+ # pdelaage 20140610 : /Dx86 flag required for X86/Emulator targets, to get proper definition for InterlockedExchange
+ # pdelaage 20140610 : /MT flag is NON-SENSE for X86-WCE platforms, it is only meaningful for X86-W32-Desktop.
+ #                     for X86-WCE targets, although compiler "cl.exe" is REALLY the same as desktop W32 VS6 C++ compiler,
+ #                     the MT flags relating to LIBCMT is useless BECAUSE LIBCMT does NOT exist on WCE. No msvcrt on WCE either...
+ 
+ # pdelaage 20140610 :  Note on /MC flag 
+ # For other targets than X86/Emulator, /MC flag is redundant with "/nodefaultlib coredll.lib corelibc.lib" LD lib list.
+ # For << X86 / Emulator >> target, as the cl.exe compiler IS the SAME as the standard VS6.0 C++ compiler for Desktop Pentium processor, 
+ # /MC flag is in fact NOT existing, thus requiring an explicit linking with core libs by using : 
+ # /NODEFAULTLIB coredll.lib corelibc.lib,
+ # something that is correct for any WCE target, X86 and other, and leading /MC flag to be useless ALSO for other target than X86.
+ 
+ 
  #
  # DEFAULTLIB management: only 2 are necessary
! # defaultlibS, as given for CLxxx in the MS doc, ARE WRONG
  
  # !!!!!!!!!!!!!!
  # CUSTOMIZE THIS according to your wcecompat and openssl directories
***************
*** 10,19 ****
  
  # Modify this to point to your actual openssl compile directory
  # (You did already compile openssl, didn't you???)
! SSLDIR=C:\Users\standard\Documents\Dvts\Contrib\openssl\v1.0.0a\patched3
  
  # Note that we currently use a multi-target customized version of legacy Essemer/wcecompat lib
! COMPATDIR=C:\Users\standard\Documents\Dvts\Contrib\wcecompat\v12\patchedX86
  
  WCEVER=420
  
--- 27,36 ----
  
  # Modify this to point to your actual openssl compile directory
  # (You did already compile openssl, didn't you???)
! SSLDIR=C:\Users\pdelaage\Dvts\Contrib\openssl\v1.0.2-stable-SNAP-20121213\patch3
  
  # Note that we currently use a multi-target customized version of legacy Essemer/wcecompat lib
! COMPATDIR=C:\Users\pdelaage\Dvts\Contrib\wcecompat\v12\patched3emu
  
  WCEVER=420
  
***************
*** 24,30 ****
  !IF "$(TARGETCPU)"=="X86"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! MORECFLAGS=/MT
  
  # TODO: continue list for other targets : see wcecompat/wcedefs.mak for a good ref.
  # see also openssl/util/pl/vc-32.pl, also link /?
--- 41,48 ----
  !IF "$(TARGETCPU)"=="X86"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! #pdelaage 20140621 /Dx86 for inline defs of InterlockedExchange inline in winbase.h; no more /MT
! MORECFLAGS=/Dx86
  
  # TODO: continue list for other targets : see wcecompat/wcedefs.mak for a good ref.
  # see also openssl/util/pl/vc-32.pl, also link /?
***************
*** 34,50 ****
  !ELSEIF "$(TARGETCPU)"=="emulator"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! MORECFLAGS=/MT
  
  !ELSEIF "$(TARGETCPU)"=="MIPS16" || "$(TARGETCPU)"=="MIPSII" || "$(TARGETCPU)"=="MIPSII_FP" || "$(TARGETCPU)"=="MIPSIV" || "$(TARGETCPU)"=="MIPSIV_FP"
  WCETARGETCPU=_MIPS_
  LDTARGETCPU=MIPS
! MORECFLAGS=/DMIPS /MC
  
  !ELSEIF "$(TARGETCPU)"=="SH3" || "$(TARGETCPU)"=="SH4"
  WCETARGETCPU=SHx
  LDTARGETCPU=$(TARGETCPU)
! MORECFLAGS=/MC
  
  !ELSE
  # default is ARM !
--- 52,71 ----
  !ELSEIF "$(TARGETCPU)"=="emulator"
  WCETARGETCPU=_X86_
  LDTARGETCPU=X86
! #pdelaage 20140621 /Dx86 for inline defs of InterlockedExchange inline in winbase.h; no more /MT
! MORECFLAGS=/Dx86
  
  !ELSEIF "$(TARGETCPU)"=="MIPS16" || "$(TARGETCPU)"=="MIPSII" || "$(TARGETCPU)"=="MIPSII_FP" || "$(TARGETCPU)"=="MIPSIV" || "$(TARGETCPU)"=="MIPSIV_FP"
  WCETARGETCPU=_MIPS_
  LDTARGETCPU=MIPS
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=/DMIPS
  
  !ELSEIF "$(TARGETCPU)"=="SH3" || "$(TARGETCPU)"=="SH4"
  WCETARGETCPU=SHx
  LDTARGETCPU=$(TARGETCPU)
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=
  
  !ELSE
  # default is ARM !
***************
*** 52,59 ****
  # the following flag is required by (eg) winnt.h, and is different from targetcpu (armV4)
  WCETARGETCPU=ARM
  LDTARGETCPU=ARM
! MORECFLAGS=/MC
! 
  !ENDIF
  
  # ceutilsdir probably useless (nb : were tools from essemer; but ms delivers a cecopy anyway, see ms dld site)
--- 73,80 ----
  # the following flag is required by (eg) winnt.h, and is different from targetcpu (armV4)
  WCETARGETCPU=ARM
  LDTARGETCPU=ARM
! #pdelaage 20140621  no more /MC required
! MORECFLAGS=
  !ENDIF
  
  # ceutilsdir probably useless (nb : were tools from essemer; but ms delivers a cecopy anyway, see ms dld site)
***************
*** 65,76 ****
  INCLUDES=-I$(SSLDIR)\inc32 -I$(COMPATDIR)\include -I"$(SDKDIR)\include\$(TARGETCPU)"
  # for X86 and other it appears that /MC or /ML flags are absurd,
  # we always have to override runtime lib list to coredll and corelibc
! LIBS=/NODEFAULTLIB winsock.lib wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
  
  DEFINES=/DHOST=\"$(TARGETCPU)-WCE-eVC-$(WCEVER)\"
  # /O1 /Oi more correct vs MS doc
! CFLAGS=/nologo $(MORECFLAGS) /O1 /Oi /W3 /WX /GF /Gy $(DEFINES) /D$(WCETARGETCPU) /D$(TARGETCPU) /DUNDER_CE=$(WCEVER) /D_WIN32_WCE=$(WCEVER) /DUNICODE -D_UNICODE $(INCLUDES)
! RFLAGS=$(DEFINES) $(INCLUDES)
  # LDFLAGS: since openssl >> 098a (eg 098h) out32dll is out32dll_targetCPU for WCE
  # delaage added $(TARGETCPU) in legacy Essemer/wcecompat libpath
  # to ease multitarget compilation without recompiling everything
--- 86,102 ----
  INCLUDES=-I$(SSLDIR)\inc32 -I$(COMPATDIR)\include -I"$(SDKDIR)\include\$(TARGETCPU)"
  # for X86 and other it appears that /MC or /ML flags are absurd,
  # we always have to override runtime lib list to coredll and corelibc
! #LIBS=/NODEFAULTLIB winsock.lib wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
! LIBS=/NODEFAULTLIB ws2.lib      wcecompatex.lib libeay32.lib ssleay32.lib coredll.lib corelibc.lib
  
  DEFINES=/DHOST=\"$(TARGETCPU)-WCE-eVC-$(WCEVER)\"
+ # pdelaage 20140610 added unicode flag : ALWAYS ACTIVE on WCE, because of poor ANSI support by the MS SDK
+ UNICODEFLAGS=/DUNICODE -D_UNICODE
  # /O1 /Oi more correct vs MS doc
! CFLAGS=/nologo $(MORECFLAGS) /O1 /Oi /W3 /WX /GF /Gy $(DEFINES) /D$(WCETARGETCPU) /D$(TARGETCPU) /DUNDER_CE=$(WCEVER) /D_WIN32_WCE=$(WCEVER) $(UNICODEFLAGS) $(INCLUDES)
! # pdelaage 20140610 : RC compilation requires D_WIN32_WCE flag to comment out unsupported "HELP" flag in menu definition, in resources.rc file
! RFLAGS=$(DEFINES) /D_WIN32_WCE=$(WCEVER) $(INCLUDES)
! 
  # LDFLAGS: since openssl >> 098a (eg 098h) out32dll is out32dll_targetCPU for WCE
  # delaage added $(TARGETCPU) in legacy Essemer/wcecompat libpath
  # to ease multitarget compilation without recompiling everything
***************
*** 90,96 ****
  OBJS=$(OBJ)\stunnel.obj $(OBJ)\ssl.obj $(OBJ)\ctx.obj $(OBJ)\verify.obj \
  	$(OBJ)\file.obj $(OBJ)\client.obj $(OBJ)\protocol.obj $(OBJ)\sthreads.obj \
  	$(OBJ)\log.obj $(OBJ)\options.obj $(OBJ)\network.obj \
! 	$(OBJ)\resolver.obj $(OBJ)\str.obj $(OBJ)\fd.obj
  
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
--- 116,122 ----
  OBJS=$(OBJ)\stunnel.obj $(OBJ)\ssl.obj $(OBJ)\ctx.obj $(OBJ)\verify.obj \
  	$(OBJ)\file.obj $(OBJ)\client.obj $(OBJ)\protocol.obj $(OBJ)\sthreads.obj \
  	$(OBJ)\log.obj $(OBJ)\options.obj $(OBJ)\network.obj \
! 	$(OBJ)\resolver.obj $(OBJ)\str.obj $(OBJ)\fd.obj $(OBJ)\mywcedefs.obj
  
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
diff -cr patch1/src/file.c patch2/src/file.c
*** patch1/src/file.c	2014-03-06 00:25:33.000000000 +0100
--- patch2/src/file.c	2014-06-12 09:21:45.875000000 +0200
***************
*** 49,65 ****
      /* open file */
      switch(mode) {
      case FILE_MODE_READ:
!         desired_access=FILE_READ_DATA;
          creation_disposition=OPEN_EXISTING;
          break;
      case FILE_MODE_APPEND:
!         desired_access=FILE_APPEND_DATA;
!         creation_disposition=OPEN_ALWAYS;
          break;
      case FILE_MODE_OVERWRITE:
!         desired_access=FILE_WRITE_DATA;
          creation_disposition=CREATE_ALWAYS;
!         break;
      default: /* invalid mode */
          return NULL;
      }
--- 49,66 ----
      /* open file */
      switch(mode) {
      case FILE_MODE_READ:
!         desired_access=GENERIC_READ;/* pdelaage 20140610 WCE: good old flags supported on w32/WCE, while FILE_READ_DATA is FAILING on WCE; 
! 		this FILE_READ_DATA flag PREVENTS read from various folders on WCE phones such as \stunnel\ or \Storage card\, or on WCE emulator \stunnel\.... where we find stunnel.conf file sometimes...*/
          creation_disposition=OPEN_EXISTING;
          break;
      case FILE_MODE_APPEND:
!         desired_access=GENERIC_WRITE; /* pdelaage 20140610: FILE_APPEND_DATA; back to old code W32/WCE compatible */
!         creation_disposition=OPEN_ALWAYS;/* pdelaage 20140610 : I disagree with OPEN_ALWAYS that creates the file if not existing. I suggest : OPEN_EXISTING */
          break;
      case FILE_MODE_OVERWRITE:
!         desired_access=GENERIC_WRITE; /* pdelaage 20140610:FILE_WRITE_DATA; back to old code W32/WCE compatible */
          creation_disposition=CREATE_ALWAYS;
!         break;	
      default: /* invalid mode */
          return NULL;
      }
Seulement dans patch2/src: mywcedefs.c
Seulement dans patch2/src: mywcedefs.h
diff -cr patch1/src/protocol.c patch2/src/protocol.c
*** patch1/src/protocol.c	2014-04-13 13:15:21.000000000 +0200
--- patch2/src/protocol.c	2014-06-10 09:29:17.406250000 +0200
***************
*** 535,540 ****
--- 535,542 ----
      }
      str_free(line);
      longjmp(c->err, 2); /* don't reset */
+ 
+ 	return NULL; /* pdelaage 20140610 : just to avoid compilation warning on W32/WCE */
  }
  
  /**************************************** nntp */
diff -cr patch1/src/resources.h patch2/src/resources.h
*** patch1/src/resources.h	2014-01-02 09:13:37.000000000 +0100
--- patch2/src/resources.h	2014-06-23 16:37:20.562500000 +0200
***************
*** 31,33 ****
--- 31,35 ----
  #define IDM_HOMEPAGE        52
  
  #define IDM_PEER_MENU       60
+ 
+ #define IDS_SERVICE_DESC    70 /* pdelaage 20140623 : added description for Win32 Service Manager */
diff -cr patch1/src/resources.rc patch2/src/resources.rc
*** patch1/src/resources.rc	2014-06-09 20:56:52.031250000 +0200
--- patch2/src/resources.rc	2014-06-23 16:39:47.156250000 +0200
***************
*** 45,60 ****
          MENUITEM SEPARATOR
          MENUITEM "&Close",                  IDM_CLOSE
      END
      POPUP "&Configuration"
      BEGIN
          MENUITEM "&Edit Configuration",      IDM_EDIT_CONFIG
          MENUITEM "&Reload Configuration",    IDM_RELOAD_CONFIG
      END
      POPUP "&Save Peer Certificate"
      BEGIN
          MENUITEM "dummy",                   0, GRAYED
      END
!     POPUP "&Help",                          HELP
      BEGIN
          MENUITEM "&About",                  IDM_ABOUT
          MENUITEM SEPARATOR
--- 45,73 ----
          MENUITEM SEPARATOR
          MENUITEM "&Close",                  IDM_CLOSE
      END
+    /* pdelaage 20140610: in WCE, this menu is too large for smart phones */
+ #ifdef _WIN32_WCE
+     POPUP "&Config."
+ #else
      POPUP "&Configuration"
+ #endif	
      BEGIN
          MENUITEM "&Edit Configuration",      IDM_EDIT_CONFIG
          MENUITEM "&Reload Configuration",    IDM_RELOAD_CONFIG
      END
+    /* pdelaage 20140610: in WCE, this menu is too large for smart phones */	
+ #ifdef _WIN32_WCE
+     POPUP "&Save Peer Certs."
+ #else
      POPUP "&Save Peer Certificate"
+ #endif		
+ 
      BEGIN
          MENUITEM "dummy",                   0, GRAYED
      END
!    /* pdelaage 20140610: in WCE, the HELP flag, although documented, is NOT SUPPORTED, use addornements instead ? */
!    /* pdelaage 20140610: in W32, the HELP flag is nowadays useless : with wide screens, it is painful to go the right end to get help */
! 	POPUP "&?"    /* pdelaage 20140610: both to fit space on WCE phones, and for "standard" look and feel on W32, ? replaces "Help" */
      BEGIN
          MENUITEM "&About",                  IDM_ABOUT
          MENUITEM SEPARATOR
***************
*** 126,128 ****
--- 139,145 ----
      PUSHBUTTON      "Cancel",IDCANCEL,      101, 30, 50, 14
  END
  
+ STRINGTABLE
+ {
+ IDS_SERVICE_DESC	"SSL encryption wrapper between local/remote clients and local/remote servers"
+ }
diff -cr patch1/src/ui_win_cli.c patch2/src/ui_win_cli.c
*** patch1/src/ui_win_cli.c	2014-06-09 22:15:17.343750000 +0200
--- patch2/src/ui_win_cli.c	2014-06-11 00:22:46.343750000 +0200
***************
*** 37,42 ****
--- 37,45 ----
  
  #include "common.h"
  #include "prototypes.h"
+ #ifdef _WIN32_WCE
+ #include "mywcedefs.h" /* pdelaage 20140610 for _tputenv_s */
+ #endif
  
  int main(int argc, char *argv[]) {
      static struct WSAData wsa_state;
***************
*** 58,64 ****
          return 1;
      }
  #endif
!     _tputenv_s(TEXT("OPENSSL_ENGINES"), stunnel_exe_path);/* pdelaage 20140526 UNICODE */
  
      str_init(); /* initialize per-thread string management */
      if(WSAStartup(MAKEWORD(1, 1), &wsa_state))
--- 61,67 ----
          return 1;
      }
  #endif
!     _tputenv_s(TEXT("OPENSSL_ENGINES"), stunnel_exe_path);/* pdelaage 20140526 UNICODE *//* pdelaage 20140610 : WCE implementation in mywcedefs.c */
  
      str_init(); /* initialize per-thread string management */
      if(WSAStartup(MAKEWORD(1, 1), &wsa_state))
***************
*** 112,119 ****
      /* log to Windows CE debug output stream */
      LPTSTR tstr;
  
!     tstr=str2tstr(line);
!     RETAILMSG(TRUE, (TEXT("%s\r\n"), tstr));
      str_free(tstr);
  #else
      fputs(line, stderr);
--- 115,122 ----
      /* log to Windows CE debug output stream */
      LPTSTR tstr;
  
!     tstr=str2tstr((LPSTR) line);/* pdelaage 20140610 : str2tstr strictly expects a "const LPSTR" */
!     RETAILMSG(TRUE, (TEXT("%s\r\n"),  tstr));
      str_free(tstr);
  #else
      fputs(line, stderr);
diff -cr patch1/src/ui_win_gui.c patch2/src/ui_win_gui.c
*** patch1/src/ui_win_gui.c	2014-06-09 22:26:24.812500000 +0200
--- patch2/src/ui_win_gui.c	2014-06-23 18:02:39.828125000 +0200
***************
*** 44,49 ****
--- 44,61 ----
  #endif
  #include "resources.h"
  
+ #ifdef _WIN32_WCE /* pdelaage 20140610 : some ports of win32 services to WCE, or some specific WCE services */
+ #include "mywcedefs.h"
+ #endif
+ 
+ #ifdef UNICODE /* pdelaage 20140623 : TSTR and TCAR ansi-printf format specs : YES ansi-printf can print Wchar strings ...*/
+ #define TCAR_PRINTF_FORMAT "%lc"
+ #define TSTR_PRINTF_FORMAT "%ls"
+ #else
+ #define TCAR_PRINTF_FORMAT "%hc"
+ #define TSTR_PRINTF_FORMAT "%hs"
+ #endif
+ 
  #define LOG_LINES 1000
  
  #ifdef _WIN32_WCE
***************
*** 56,62 ****
  #endif
  
  #define SERVICE_NAME TEXT("stunnel") /* pdelaage 20140609 UNICODE */
! 
  #endif
  
  /* mingw-Patches-1825044 is missing in Debian Squeeze */
--- 68,74 ----
  #endif
  
  #define SERVICE_NAME TEXT("stunnel") /* pdelaage 20140609 UNICODE */
! #define SERVICE_DISPLAY_NAME TEXT("Stunnel SSL wrapper") /* pdelaage 20140623: Nicer name to be displayed in Service Control Manager */
  #endif
  
  /* mingw-Patches-1825044 is missing in Debian Squeeze */
***************
*** 129,135 ****
  static SERVICE_STATUS_HANDLE serviceStatusHandle=0;
  #endif
  
! static volatile int visible=0;
  static volatile int error_mode=1; /* no valid configuration was ever loaded */
  static HANDLE config_ready=NULL; /* reload without a valid configuration */
  static LONG new_logs=0;
--- 141,148 ----
  static SERVICE_STATUS_HANDLE serviceStatusHandle=0;
  #endif
  
! /* pdelaage 20140610: now visible is more appropriately a BOOL, as stated by MSDN */
! static volatile BOOL visible = FALSE;/* int visible=0; */
  static volatile int error_mode=1; /* no valid configuration was ever loaded */
  static HANDLE config_ready=NULL; /* reload without a valid configuration */
  static LONG new_logs=0;
***************
*** 164,172 ****
      str_init(); /* initialize per-thread string management */
      ghInst=this_instance;
  #ifdef _WIN32_WCE
!     command_line=tstr2str(lpCmdLine);
  #else
!     command_line=lpCmdLine;
  #endif
  
      parse_cmdline(command_line); /* setup global cmdline structure */
--- 177,185 ----
      str_init(); /* initialize per-thread string management */
      ghInst=this_instance;
  #ifdef _WIN32_WCE
!     command_line=wstr2str(lpCmdLine);/* pdelaage 20140610 : on WCE, even in <<ANSI>> compilation mode that is ALSO possible on WCE, lpCmdline is ALWAYS WCHAR, so that WCE ALWAYS need a WCHAR to STR conversion, but in ANSI mode tstr2str INAPPROPRIATELY here expects a char* so that we need another conversion function : see extra source in mywcedefs.c */
  #else
!     command_line=lpCmdLine; /* pdelaage 20140610, on win32 lpcmdline is always ANSI string...for the moment.*/
  #endif
  
      parse_cmdline(command_line); /* setup global cmdline structure */
***************
*** 189,199 ****
          c[1]=TEXT('\0'); /* truncate program name */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
! #ifdef UNICODE	/*  pdelaage 20140609 : UNICODE in printf format spec */
!         errmsg=str_printf("Cannot set directory to %ls", stunnel_exe_path);
! #else
!         errmsg=str_printf("Cannot set directory to %hs", stunnel_exe_path);
! #endif		
          message_box(errmsg, MB_ICONERROR);
          str_free(errmsg);
          return 1;
--- 202,209 ----
          c[1]=TEXT('\0'); /* truncate program name */
  #ifndef _WIN32_WCE
      if(!SetCurrentDirectory(stunnel_exe_path)) {
! 	/*  pdelaage 20140609 : UNICODE in printf format spec */
!         errmsg=str_printf("Cannot set directory to "TSTR_PRINTF_FORMAT, stunnel_exe_path);		
          message_box(errmsg, MB_ICONERROR);
          str_free(errmsg);
          return 1;
***************
*** 323,328 ****
--- 333,341 ----
      MSG msg;
      LPTSTR classname=TEXT("stunnel_main_window_class");
  
+ 	/* Ensure commctrl.dll is loaded *//* pdelaage 20140621 addition, needed -eg- for WCE commandbars ... */
+ 	InitCommonControls(); /* pdelaage 20140621 : Good practice before using common controls, both for WCE and W32 */
+ 
      /* register the class */
  #ifndef _WIN32_WCE
      wc.cbSize=sizeof wc;
***************
*** 391,397 ****
          s_log(LOG_DEBUG, "Window message: %d", message);
  #endif
      switch(message) {
!     case WM_CREATE:
  #ifdef _WIN32_WCE
          /* create command bar */
          command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1);
--- 404,410 ----
          s_log(LOG_DEBUG, "Window message: %d", message);
  #endif
      switch(message) {
!     case WM_CREATE:			
  #ifdef _WIN32_WCE
          /* create command bar */
          command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1);
***************
*** 404,412 ****
  #endif
  
          /* create child edit window */
!         edit_handle=CreateWindow(TEXT("EDIT"), NULL,
!             WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
!             0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL);
  #ifndef _WIN32_WCE
          SendMessage(edit_handle, WM_SETFONT,
              (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
--- 417,426 ----
  #endif
  
          /* create child edit window */
!         edit_handle=CreateWindowEx(WS_EX_STATICEDGE, /* pdelaage 20140610 : for better look and feel, 3D edges to separate from menubar...over Win31 flat style */
! 		TEXT("EDIT"), NULL,
! 		WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY,
!         0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL);
  #ifndef _WIN32_WCE
          SendMessage(edit_handle, WM_SETFONT,
              (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
***************
*** 421,432 ****
  #ifdef _WIN32_WCE
          MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle),
              rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE);
  #else
          MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE);
  #endif
          UpdateWindow(edit_handle);
          /* CommandBar_Show(command_bar_handle, TRUE); */
!         return TRUE;
  
      case WM_SETFOCUS:
          SetFocus(edit_handle);
--- 435,451 ----
  #ifdef _WIN32_WCE
          MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle),
              rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE);
+ 
+ /* pdelaage 20140610 WCE : dixit MSDN, and indeed, commandbars do not resize automatically unless providing this code, necessary on "sliding-keyboard" OR "auto-rotating screen orientation" smart phones when switching from portrait to landscape display and vice/versa */
+ 		SendMessage(command_bar_handle, TB_AUTOSIZE, 0L, 0L);
+ 		CommandBar_AlignAdornments(command_bar_handle);/* pdelaage 20140610 WCE: MSDN says we have to repeat this for auto-repositioning of Help btn */
+ 			
  #else
          MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE);
  #endif
          UpdateWindow(edit_handle);
          /* CommandBar_Show(command_bar_handle, TRUE); */
!         return TRUE;/* pdelaage 20140621, TODO: both for W32 and WCE, this should be "return 0", not "TRUE"... dixit MSDN. Same remark for most of the msg processing here */
  
      case WM_SETFOCUS:
          SetFocus(edit_handle);
***************
*** 441,454 ****
          ShowWindow(main_window_handle, SW_HIDE);
          return TRUE;
  
!     case WM_SHOWWINDOW:
!         visible=wParam; /* setup global variable */
          if(tray_menu_handle)
              CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG,
                  visible ? MF_CHECKED : MF_UNCHECKED);
          if(visible)
!             update_logs();
!         return TRUE;
  
      case WM_DESTROY:
  #ifdef _WIN32_WCE
--- 460,478 ----
          ShowWindow(main_window_handle, SW_HIDE);
          return TRUE;
  
! /* pdelaage 20140610: I made "visible" a real BOOL, as defined by MSDN doc on WM_SHOWWINDOW...instead of an int between 0 and 1...*/
! /*	case WM_SHOWWINDOW: 
! 		visible= (BOOL) wParam;  *//*  setup global variable 
! */
! /* pdelaage 20140610: WM_SHOWWINDOW does NOT exist on WCE, so replaced by WM_WINDOWPOSCHANGED W32/WCE compatible */
! 	case WM_WINDOWPOSCHANGED :
!         visible = IsWindowVisible(main_window_handle);/* setup global variable *//* pdelaage 20140610: more reliable than msg content */	 
          if(tray_menu_handle)
              CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG,
                  visible ? MF_CHECKED : MF_UNCHECKED);
          if(visible)
!             update_logs();		
! 		break;/* return TRUE;*//* pdelaage 20140610: WM_WINDOWPOSCHANGED MUST go to DefProc to properly refresh window appearance (WM_SIZE/WM_MOVE)*/
  
      case WM_DESTROY:
  #ifdef _WIN32_WCE
***************
*** 903,909 ****
      HMENU tray_peer_list=NULL;
      char *str;
      unsigned int section_number;
!     MENUITEMINFO mii;
  
      /* purge menu peer lists */
  #ifndef _WIN32_WCE
--- 927,934 ----
      HMENU tray_peer_list=NULL;
      char *str;
      unsigned int section_number;
! 
! /* 20140610 pdelaage unsupported on WCE, useless with common code in W32 (and thus generates a compilation warning) :     MENUITEMINFO mii; */
  
      /* purge menu peer lists */
  #ifndef _WIN32_WCE
***************
*** 916,923 ****
      if(tray_menu_handle)
          tray_peer_list=GetSubMenu(GetSubMenu(tray_menu_handle, 0), 2);
      if(tray_peer_list)
!         while(GetMenuItemCount(tray_peer_list)) /* purge old menu */
!             DeleteMenu(tray_peer_list, 0, MF_BYPOSITION);
  
      /* initialize data structures */
      number_of_sections=0;
--- 941,948 ----
      if(tray_menu_handle)
          tray_peer_list=GetSubMenu(GetSubMenu(tray_menu_handle, 0), 2);
      if(tray_peer_list)
! /* pdelaage 20140610 : W32/WCE trick because GetMenuItemCount does not exist on WCE */
!         while (DeleteMenu(tray_peer_list, 0, MF_BYPOSITION) == TRUE) {;}; /* purge old menu */	
  
      /* initialize data structures */
      number_of_sections=0;
***************
*** 950,955 ****
--- 975,981 ----
          section->chain=NULL;
  
          /* insert new menu item */
+ /* pdelaage 20140610 : this code is not supported by WCE, and the same can be achieved by a SHORTER common code for W32/WCE       		
          mii.cbSize=sizeof mii;
          mii.fMask=MIIM_STRING|MIIM_DATA|MIIM_ID|MIIM_STATE;
          mii.fType=MFT_STRING;
***************
*** 965,970 ****
--- 991,1007 ----
          if(tray_peer_list)
              if(!InsertMenuItem(tray_peer_list, section_number, TRUE, &mii))
                  ioerror("InsertMenuItem");
+ */				
+ 	/* pdelaage 20140610, W32/WCE short COMMON code to create menuitems			*/
+ #ifndef _WIN32_WCE
+         if(main_peer_list)
+             if(InsertMenu(main_peer_list, section_number, MF_BYPOSITION | MF_STRING | MF_GRAYED, IDM_PEER_MENU+section_number, section->file) == 0)
+                 ioerror("InsertMenu");
+ #endif
+         if(tray_peer_list)
+             if(InsertMenu(tray_peer_list, section_number, MF_BYPOSITION | MF_STRING | MF_GRAYED, IDM_PEER_MENU+section_number, section->file) == 0)
+                 ioerror("InsertMenu");
+ 				
          ++section_number;
      }
      if(hwnd)
***************
*** 994,1003 ****
  ICON_IMAGE load_icon_file(const char *name) {
      LPTSTR tname;
      ICON_IMAGE icon;
! 
      tname=str2tstr((LPSTR)name);
      icon=LoadImage(NULL, tname, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
          GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE);
      str_free(tname);
      return icon;
  }
--- 1031,1044 ----
  ICON_IMAGE load_icon_file(const char *name) {
      LPTSTR tname;
      ICON_IMAGE icon;
! 	
      tname=str2tstr((LPSTR)name);
+ #ifdef _WIN32_WCE /* pdelaage 20140610 : LR_LOADFROMFILE unsupported in WCE, cannot be replaced by SHLoadDIBitmap in this context, but... */
+ 	icon=wceLoadIconFromFile(tname);/* pdelaage 20140610  : ...with some standard W32 coding, an equivalent to loadimage for BMP files  (not ICO) is possible, for WCE...working also for W32 if needed */
+ #else	
      icon=LoadImage(NULL, tname, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
          GetSystemMetrics(SM_CYSMICON), LR_LOADFROMFILE);
+ #endif		
      str_free(tname);
      return icon;
  }
***************
*** 1006,1011 ****
--- 1047,1054 ----
      NOTIFYICONDATA nid;
      static ICON_TYPE previous_icon=ICON_NONE;
      ICON_TYPE current_icon;
+ 	HICON prevIcon_l = (HICON) NULL; /* pdelaage 20140610 WCE */
+ 	BOOL retval_l = FALSE; /* pdelaage 20140610 WCE */
  
      if(!global_options.option.taskbar) { /* save menu resources */
          if(tray_menu_handle) { /* disabled in the new configuration */
***************
*** 1026,1032 ****
      nid.uCallbackMessage=WM_SYSTRAY; /* notification message */
      nid.hWnd=hwnd; /* window to receive notifications */
      if(num<0) {
!         _stprintf(nid.szTip, TEXT("Server is down"));
          current_icon=ICON_ERROR;
      } else if(num>0) {
          _stprintf(nid.szTip, TEXT("%d active session(s)"), num);
--- 1069,1075 ----
      nid.uCallbackMessage=WM_SYSTRAY; /* notification message */
      nid.hWnd=hwnd; /* window to receive notifications */
      if(num<0) {
!         _stprintf(nid.szTip, TEXT("Server is down"));/* pdelaage 20140621 : Be careful that on WCE, szTip is ALWAYS WCHAR. Anyway ANSI version of stunnel for WCE, although possible with some port effort, is of no practical interest since UNICODE covers ANSI... */
          current_icon=ICON_ERROR;
      } else if(num>0) {
          _stprintf(nid.szTip, TEXT("%d active session(s)"), num);
***************
*** 1037,1046 ****
      }
      nid.hIcon=global_options.icon[current_icon];
      if(current_icon!=previous_icon) {
!         nid.uFlags|=NIF_ICON;
!         previous_icon=current_icon;
!     }
!     if(Shell_NotifyIcon(NIM_MODIFY, &nid)) /* modify tooltip */
          return; /* OK: taskbar icon exists */
      /* tooltip update failed - try to create the icon */
      nid.uFlags|=NIF_ICON;
--- 1080,1097 ----
      }
      nid.hIcon=global_options.icon[current_icon];
      if(current_icon!=previous_icon) {
! #ifdef _WIN32_WCE /* pdelaage 20140610 : on WCE, the replaced Icon will be DELETED and LOST from the system resources, so that we have to duplicate it before losing it, and in the objective to restore it later. */
! 		if (previous_icon != ICON_NONE) 
! 		{
! 		prevIcon_l = global_options.icon[previous_icon];
! 		global_options.icon[previous_icon] = DuplicateIcon((HINSTANCE) NULL, prevIcon_l);
! 		DestroyIcon(prevIcon_l);/* pdelaage 20140610: ok, the WCE system will do that, but it is better to do it explicitely, either if one day WCE doesn't do it anymore AND/OR if this code is reused in W32: something absolutely possible ...*/
! 		}
! #endif		
!         nid.uFlags|=NIF_ICON;		
!         previous_icon=current_icon;		
!     }	
! 	if(Shell_NotifyIcon(NIM_MODIFY, &nid)) /* modify tooltip */
          return; /* OK: taskbar icon exists */
      /* tooltip update failed - try to create the icon */
      nid.uFlags|=NIF_ICON;
***************
*** 1096,1106 ****
  	TCHAR *conf_string; /* pdelaage 20140609 : needed for UNICODE ShellExecute, because "configuration_file" is JUST ASCII !! */
  	
      /* TODO: port it to WCE */
      if(is_admin()) {
  		conf_string = str2tstr(configuration_file);
  	
!         ShellExecute(main_window_handle, TEXT("open"),
              TEXT("notepad.exe"), conf_string,/* pdelaage 20140609 : now UNICODE correct */
              NULL, SW_SHOWNORMAL);
  
  		str_free(conf_string);	
--- 1147,1159 ----
  	TCHAR *conf_string; /* pdelaage 20140609 : needed for UNICODE ShellExecute, because "configuration_file" is JUST ASCII !! */
  	
      /* TODO: port it to WCE */
+ 	/* pdelaage 20140610 : DONE ! for ShellExecute in mywcedefs.c */
      if(is_admin()) {
  		conf_string = str2tstr(configuration_file);
  	
!         ShellExecute(main_window_handle, TEXT("open"), /* pdelaage 20140610 : reimplemenred for WCE, see mywcedefs.c */
              TEXT("notepad.exe"), conf_string,/* pdelaage 20140609 : now UNICODE correct */
+ /* pdelaage 20140610 : TODO : notepad is NOT available on CE, we have to find/suggest a free replacement: some exist. */			
              NULL, SW_SHOWNORMAL);
  
  		str_free(conf_string);	
***************
*** 1109,1122 ****
          if(strchr(configuration_file, '\\')) {
              conf_path=str_dup(configuration_file);
          } else {
!             GetCurrentDirectory(MAX_PATH, cwd);
!             conf_path=str_printf("%s\\%s", cwd, configuration_file);
          }
  		
  		conf_string = str2tstr(conf_path);
  				
          ShellExecute(main_window_handle, TEXT("runas"),
              TEXT("notepad.exe"), conf_string, /* pdelaage 20140609 : now UNICODE correct */
              NULL, SW_SHOWNORMAL);	
  			
   		str_free(conf_string);				
--- 1162,1177 ----
          if(strchr(configuration_file, '\\')) {
              conf_path=str_dup(configuration_file);
          } else {
!             GetCurrentDirectory(MAX_PATH, cwd);/* pdelaage 20140610 : reimplemenred for WCE, see mywcedefs.c */
! 			/*  pdelaage 20140621 : UNICODE in printf format spec */
!             conf_path=str_printf(TSTR_PRINTF_FORMAT"\\%s", cwd, configuration_file);
          }
  		
  		conf_string = str2tstr(conf_path);
  				
          ShellExecute(main_window_handle, TEXT("runas"),
              TEXT("notepad.exe"), conf_string, /* pdelaage 20140609 : now UNICODE correct */
+ /* pdelaage 20140610 : TODO : notepad is NOT available on CE, we have to find/suggest a free replacement: some exist. */					
              NULL, SW_SHOWNORMAL);	
  			
   		str_free(conf_string);				
***************
*** 1125,1130 ****
--- 1180,1186 ----
  }
  
  NOEXPORT BOOL is_admin(void) {
+ #ifndef _WIN32_WCE
      SID_IDENTIFIER_AUTHORITY NtAuthority={SECURITY_NT_AUTHORITY};
      PSID admin_group;
      BOOL retval;
***************
*** 1138,1143 ****
--- 1194,1202 ----
          FreeSid(admin_group);
      }
      return retval;
+ #else
+ 	return TRUE; /* pdelaage 20140610 :on WCE, user is always admin */
+ #endif		
  }
  
  /**************************************** windows service */
***************
*** 1161,1182 ****
      SC_HANDLE scm, service;
      TCHAR stunnel_exe_path[MAX_PATH], *tservice_path;/* pdelaage 20140609: UNICODE for GetModuleFileName, CreateService */
      char *service_path;
! 
      scm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if(!scm) {
          error_box("OpenSCManager");
          return 1;
      }
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
! 	#ifdef UNICODE /* pdelaage 20140609 : we CAN mix TCHAR* and char* in printf...provided we use the proper h or l FORMAT SPEC */
!     service_path=str_printf("\"%ls\" -service %hs", stunnel_exe_path, command_line);
! 	#else
!     service_path=str_printf("\"%hs\" -service %hs", stunnel_exe_path, command_line);
! 	#endif	
  
  	tservice_path = str2tstr(service_path);
  	
!     service=CreateService(scm, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS,
          SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
          SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, tservice_path,
          NULL, NULL, NULL, NULL, NULL);
--- 1220,1242 ----
      SC_HANDLE scm, service;
      TCHAR stunnel_exe_path[MAX_PATH], *tservice_path;/* pdelaage 20140609: UNICODE for GetModuleFileName, CreateService */
      char *service_path;
! 	
! 	TCHAR service_description_string[256];/* pdelaage 20140621: Added service description for Services Manager */
! 	SERVICE_DESCRIPTION service_description;
! 	
      scm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if(!scm) {
          error_box("OpenSCManager");
          return 1;
      }
      GetModuleFileName(0, stunnel_exe_path, MAX_PATH);
! 	/* pdelaage 20140609 : we CAN mix TCHAR* and char* in printf...provided we use the proper h or l FORMAT SPEC */
!     service_path=str_printf("\""TSTR_PRINTF_FORMAT"\" -service %hs", stunnel_exe_path, command_line);
  
  	tservice_path = str2tstr(service_path);
  	
!     service=CreateService(scm, SERVICE_NAME, SERVICE_DISPLAY_NAME, /* pdelaage 20140623: Added service display-name for Service Manager */
! 		SERVICE_ALL_ACCESS,
          SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
          SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, tservice_path,
          NULL, NULL, NULL, NULL, NULL);
***************
*** 1187,1192 ****
--- 1247,1260 ----
          CloseServiceHandle(scm);
          return 1;
      }
+ 	
+ 	/* pdelaage 20140623 : set more explicit description for the service, in Windows Service Control Manager */
+ 	if (LoadString(ghInst, IDS_SERVICE_DESC, service_description_string, sizeof(service_description_string)))
+ 	{
+ 	service_description.lpDescription = service_description_string;
+ 	ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &service_description);
+ 	}
+ 	
      message_box("Service installed", MB_ICONINFORMATION);
      CloseServiceHandle(service);
      CloseServiceHandle(scm);
diff -cr patch1/src/vc.mak patch2/src/vc.mak
*** patch1/src/vc.mak	2014-06-09 21:32:43.031250000 +0200
--- patch2/src/vc.mak	2014-06-21 17:54:40.734375000 +0200
***************
*** 4,9 ****
--- 4,12 ----
  # pdelaage 20140609 : added UNICODE optional FLAG
  # pdelaage 20140609 : added WX (fails on warning) flag to detect subtle error prone cast
  # pdelaage 20140609 : added _CRT_NON_CONFORMING_SWPRINTFS to explicitely support old fashioned stprintf in ui_win_gui.c
+ # pdelaage 20140610 : BUG FIX : no clean working because of a typo in GUIOBJS and NOGUIOBJS names in clean rule
+ # pdelaage 20140610 : BUG FIX : no clean working because of a typo in SHAREOBJS list ($(OBJ)/fd.obj instead of xx\xx)
+ # pdelaage 20140610 : Explicit link to comctl32.lib for InitCommonControls call
  
  # the compilation requires:
  # - Visual C++ 2005 Express Edition with Platform SDK
***************
*** 50,56 ****
  	$(OBJ)\verify.obj $(OBJ)\file.obj $(OBJ)\client.obj \
  	$(OBJ)\protocol.obj $(OBJ)\sthreads.obj $(OBJ)\log.obj \
  	$(OBJ)\options.obj $(OBJ)\network.obj $(OBJ)\resolver.obj \
!  	$(OBJ)\str.obj $(OBJ)/fd.obj
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
  	
--- 53,59 ----
  	$(OBJ)\verify.obj $(OBJ)\file.obj $(OBJ)\client.obj \
  	$(OBJ)\protocol.obj $(OBJ)\sthreads.obj $(OBJ)\log.obj \
  	$(OBJ)\options.obj $(OBJ)\network.obj $(OBJ)\resolver.obj \
!  	$(OBJ)\str.obj $(OBJ)\fd.obj
  GUIOBJS=$(OBJ)\ui_win_gui.obj $(OBJ)\resources.res
  NOGUIOBJS=$(OBJ)\ui_win_cli.obj
  	
***************
*** 70,76 ****
  LDFLAGS=/NOLOGO
  
  SHAREDLIBS=ws2_32.lib user32.lib shell32.lib
! GUILIBS=advapi32.lib comdlg32.lib crypt32.lib gdi32.lib psapi.lib
  NOGUILIBS=
  SSLLIBS=/LIBPATH:"$(LIBDIR)" libeay32.lib ssleay32.lib
  # static linking:
--- 73,79 ----
  LDFLAGS=/NOLOGO
  
  SHAREDLIBS=ws2_32.lib user32.lib shell32.lib
! GUILIBS=advapi32.lib comctl32.lib comdlg32.lib crypt32.lib gdi32.lib psapi.lib
  NOGUILIBS=
  SSLLIBS=/LIBPATH:"$(LIBDIR)" libeay32.lib ssleay32.lib
  # static linking:
***************
*** 88,95 ****
  
  clean:
  	-@ del $(SHAREDOBJS) >NUL 2>&1
! 	-@ del $(GUIBJS) >NUL 2>&1
! 	-@ del $(NOGUIBJS) >NUL 2>&1
  #	-@ del *.manifest >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe.manifest >NUL 2>&1
--- 91,98 ----
  
  clean:
  	-@ del $(SHAREDOBJS) >NUL 2>&1
! 	-@ del $(GUIOBJS) >NUL 2>&1
! 	-@ del $(NOGUIOBJS) >NUL 2>&1
  #	-@ del *.manifest >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe >NUL 2>&1
  	-@ del $(BIN)\stunnel.exe.manifest >NUL 2>&1
-------------- next part --------------
 /* Win32-like Services for Windows CE 5.0 and above win32 applications,
	such as stunnel.
    Copyright (C) 2014 Pierre DELAAGE <delaage.pierre at free.fr>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
	
#ifndef MYWCEDEFS_H
#define MYWCEDEFS_H

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <windows.h>
#include <tchar.h>

LPSTR wstr2str(LPCWSTR);

typedef int errno_t;

errno_t _tputenv_s(
   const TCHAR *name,
   const TCHAR *value 
);

HICON wceLoadIconFromFile(TCHAR *filename);/* works only for BMP dib files 16x16, 16 colors (or more...) */

#define DuplicateIcon wceDuplicateIcon /* Comment this out if your SDK AND TARGET DEVICE support DuplicateIcon natively */

HICON wceDuplicateIcon( /* same -stupid- prototype as w32 DuplicateIcon */
  HINSTANCE hInst,      // not used
  HICON hIcon          // handle to icon
);

#define ShellExecute wceShellExecute /* Comment this out if your SDK AND TARGET DEVICE support DuplicateIcon natively */

HINSTANCE wceShellExecute(
    HWND hwnd, 
    LPCTSTR lpVerb,
    LPCTSTR lpFile, 
    LPCTSTR lpParameters, 
    LPCTSTR lpDirectory,
    INT nShowCmd
);

#define GetCurrentDirectory wceGetCurrentDirectory /* Comment this out if your SDK AND TARGET DEVICE support DuplicateIcon natively */

DWORD wceGetCurrentDirectory(
  DWORD nBufferLength,  // size of directory buffer
  LPTSTR lpBuffer       // directory buffer
);

/* For ANSI WCE version of _tcsrchr : there is a lack of macro def in tchar.h, fixed here */

#ifdef _WIN32_WCE
#ifndef _tcsrchr
#ifdef UNICODE
#define _tcsrchr wcsrchr
#else
#define _tcsrchr strrchr
#endif
#endif
#endif



#endif

-------------- next part --------------
 /* Win32-like Services for Windows CE 5.0 and above win32 applications,
	such as stunnel.
    Copyright (C) 2014 Pierre DELAAGE <delaage.pierre at free.fr>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.h"
#include "prototypes.h"

#include <commctrl.h>

#include "mywcedefs.h"


LPSTR wstr2str(LPCWSTR in) { /* code identical to W part of tstr2str function in file.c */
	int len;
	LPSTR out;

	len=WideCharToMultiByte(CP_ACP, 0, in, -1, NULL, 0, NULL, NULL);
	if(!len)
        return NULL;
    out=str_alloc(len+1);
    len=WideCharToMultiByte(CP_ACP, 0, in, -1, out, len, NULL, NULL);	
	if(!len)
        return NULL;
	return out;
}

errno_t _tputenv_s(
   const TCHAR *name,
   const TCHAR *value 
)
{
TCHAR envcmd_l[MAX_PATH];
int cr_l;

_tcscpy(envcmd_l, name);
_tcscat(envcmd_l,TEXT("="));
_tcscat(envcmd_l,value);

cr_l = _tputenv(envcmd_l);
if (cr_l < 0) return EINVAL;
return 0;
}

HICON wceLoadIconFromFile(TCHAR *filename) /* Loads only BMP (NOT .ico !) files as HICON, 16x16 and 16 colors */
{
char *pANDMASK_l;
int width_l, height_l;

HBITMAP HBMICON_l;/* Icon image Hbitmap */
HBITMAP HBMAND_l; /* AND-Mask, to "AND" with background, before xor-ing the bg with the image, all at 0 */

ICONINFO iconinfo_l;
HICON hicon_l;

DWORD errcode_l;

/* Load the file in a bitmap (file MUST BE a bmp file, not a ".ico" one) */

HBMICON_l = SHLoadDIBitmap(filename);
errcode_l=GetLastError();
if (!HBMICON_l) s_log(LOG_DEBUG, "MYWCEDEFS[%d] : wceLoadIconFromFile HBMICON_l is %x error is %d", __LINE__, HBMICON_l, errcode_l);

/* Create Masks as MONOCHROME bitmaps (1 plane, 1 bit/pixel), based on SXCM metrics */

width_l  = GetSystemMetrics(SM_CXSMICON); /* should be...is...multiple of 2 (word aligned see CreateBitmap doc...or 4 ?) */
height_l = GetSystemMetrics(SM_CYSMICON);

pANDMASK_l = (char *) malloc(width_l * height_l / 8);/* monochrome masks are 1 bit/pixel images */
memset(pANDMASK_l, 0x00, width_l * height_l / 8 );   /* the Color Bitmap (from the file) will Overwrite the background */

HBMAND_l = CreateBitmap(width_l, height_l, 1, 1, pANDMASK_l); /* dixit MSDN "for performance reasons applications should use CreateBitmap to create monochrome bitmaps" */
errcode_l=GetLastError();
if (!HBMAND_l) s_log(LOG_DEBUG, "MYWCEDEFS[%d] : HBMAND_l is %x error is %d", __LINE__, HBMAND_l, errcode_l);

/* Create an icon from the bitmap and MASKS */

iconinfo_l.fIcon = TRUE; 
iconinfo_l.xHotspot = 0; /* ignored */
iconinfo_l.yHotspot = 0; /* ignored */
iconinfo_l.hbmMask  = HBMAND_l;/* AND Mask for a Color Icon; AND+XOR mask for a BW icon */
iconinfo_l.hbmColor = HBMICON_l;/* NULL for a BW icon */

hicon_l = CreateIconIndirect(&iconinfo_l);
errcode_l=GetLastError();
if(!hicon_l) s_log(LOG_DEBUG, "MYWCEDEFS[%d] : hicon_l is %x error is %d",  __LINE__, hicon_l, errcode_l);

DeleteObject(HBMICON_l);  
DeleteObject(HBMAND_l);  

/* pANDMASK_l freed because memory area not anymore used by GUI (?) */
free(pANDMASK_l);

return(hicon_l);
}


HICON wceDuplicateIcon(
  HINSTANCE hInst,     /* not used (as in MSDN) */
  HICON hIcon          /* handle to icon */
)
{
HDC hdc,    /* Full Screen DC */
    hdcsrc, /* Color memory DC, based on Screen, to internally store the original Icon with its original colors AND transparency zones */
	hdcmask;/* B&W memory DC, for AND-mask management */

int width_l, height_l;

HBITMAP HBMICON_l;/* Color bitmap for original Icon -transparent- drawing */
HBITMAP HBMMASK_l; /* NEW Icon AND-Mask, basically at 1 on the background (ie icon transparent pixels), 1 under the Icon "sprite" */

ICONINFO iconinfo_l;
HICON hNewIcon_l = (HICON) NULL;


COLORREF bgColor;/* conventional BackGround Color for original Icon : MUST be an "improbable" color */
HBRUSH bgBrush= (HBRUSH) NULL;/* to draw the background of the original Icon bitmap */

BOOL cr_l = FALSE;
DWORD errcode_l;

width_l  = GetSystemMetrics(SM_CXSMICON); /* should be...is...multiple of 2 (word aligned see CreateBitmap doc...or 4 ?) */
height_l = GetSystemMetrics(SM_CYSMICON);

/* STEP 1 : we just need to draw the original Icon into a bitmap, with an easily removable coloured background 
   -----------------------------------------------------------------------------------------------------------
  To do this we paint the background of a coloured hdc with some rarely used color (ideally a "never-used" color.
  Then we draw, with original transparency support, the original Icon to that painting surface.
  NOW we have a typical coloroured background, and our Icon projected on it.
  The background will be made transparent later...
*/

/* Draw the original Icon in a "screen-like" hdc (to get highest possible color fidelity) */

hdc       = GetDC(NULL);
hdcsrc    = CreateCompatibleDC(hdc);
HBMICON_l = CreateCompatibleBitmap(hdc, width_l, height_l);/* Note: hdc, NOT hdcsrc, just to HAVE A FULL COLOR bitmap, as close as possible to the screen colors */
SelectObject(hdcsrc, HBMICON_l);

/*
For future computation of BGMASK (white outside Icon, black under the icon), we need to decide of a transparent Background Color
This MUST be an "improbable" color, ie that is probably NOT used in the original Icon, this color will be transparent in next steps.
NB : be careful that on poor color display, this color will be interpolated to something else "as close as possible":
but we do NOT want something being interpolated to black nor white (because those colors are USED in icons)...
and we DO want something that is "probably" supported by ANY device WITHOUT interpolation (just to have a predictive effect on masking computation)

This is OK but sometimes used : bgColor = (COLORREF) RGB(127,127,127);
This is NOT ok because interpolated to black : bgColor = (COLORREF) RGB(1,1,1);
*/

bgColor = (COLORREF) RGB(15,15,15);/* This is Ok on WCE5/WM6 HTC smartphones */
SetBkColor(hdcsrc, bgColor);/* THIS is ABSOLUTELY necessary to get some B&W mask FROM this coloured icon, in second step */

/* Fill the background of our Icon hdc with our BgColor: necessary for when we will make this background transparent */

bgBrush = CreateSolidBrush(bgColor);
SelectObject(hdcsrc, bgBrush);
PatBlt(hdcsrc,0,0,width_l, height_l, PATCOPY);

/* Draw the Icon (remember : our hdcsrc is AS CLOSE AS POSSIBLE to the Screen DC in color support) */

DrawIcon(hdcsrc, 0, 0, hIcon); 



/* STEP2 : Generate a "transparency" AND-mask for the icon : 
   ---------------------------------------------------------
   This mask will be anded to the screen background, to DELETE the area where the future NEW-Icon will be drawn by XOR (0 XOR Y = Y)
   This is done by a typical MSDN trick, using Monochrome Bitmaps and COLOR conversion rules between COLOR HDC and B&W hdc :
   Color  hdc => B&W hdc : BkColor will become White, OTHER colors will become BLACK
   B&W hdc => Color hdc  : B&W 0 becomes DST TextColor, B&W 1 becomes DST BkColor (as set by SetBkColor)
*/

hdcmask   = CreateCompatibleDC(hdc);
HBMMASK_l = CreateBitmap(width_l, height_l, 1, 1, NULL);/* Mandatory B&W bitmap here */
SelectObject(hdcmask, HBMMASK_l);
/*	Optional : Just in case anything goes wrong, the mask "could be at least" completely black 
PatBlt(hdcmask,0,0,width_l, height_l, BLACKNESS);
*/

BitBlt(hdcmask, 0,0,width_l, height_l, hdcsrc, 0, 0, SRCCOPY);/* This is the graal of Win32 transparent bitmap copy */
/* now we have a mask WHERE each original bg pixel (from the original color Icon bitmap), in NOW a "white pixel",
   and anything else, ie the Icon itself, is just a black surface, similar to the shadow of the original Icon.
*/

/* STEP 3 : DELETE -ONLY- BACKGROUND pixels from the Original Color Icon Bitmap
  This is necessary because we will use that bitmap as the future DUPLICATE of the original Icon,
  and, by using CreateIconIndirect to create the icon, we need to be sure that the background will be transparent:
  This is not only obtained by having an and-mask for the background, BUT ALSO by BEING sure that, in the colored icon bitmap,
  the bg pixels will be at 0 : because the colored icon bitmap will be XOR'ed to the screen background, and 0 XOR Y = Y...

  Ideally, to do that we do : Icon = Icon AND (NOT(MASK)) (ie ternary ROP code "DSna" : 0x00220326, dixit MSDN)
  
  BUT...as this ROP operation will mix a B&W hdc and a Color HDC we need to be sure that the B&W 0 will translate to RGB(0,0,0) (BLACK) and 
  that the B&W 1 will translate to RGB(255,255,255) (WHITE), BEFORE than the logical ROP operation occurs.
  Because this is how it will happen : before a ROP occurs between a B&W hdc and a coloured hdc, 1st/ the B&W hdc is converted to coloured
  one (0= DST TextColr / 1 : DST BkColor) and 2nd/ the logical ROP operation occurs.
  
  So, before ROP bitblt, we DO : Orig Icon TextColor = black, Orig Icon BkColor = White.
  
*/

SetTextColor(hdcsrc, RGB(  0,  0,  0));/* to translate 0 from the mask */
SetBkColor(  hdcsrc, RGB(255,255,255));/* to translate 1 from the mask */
BitBlt(hdcsrc, 0, 0, width_l, height_l, hdcmask, 0, 0, 0x00220326);/* NOTSRC_AND ternary ROP code ("DSna" in MSDN) */

/* Create an icon from the bitmap and MASKS */

iconinfo_l.fIcon = TRUE; 
iconinfo_l.xHotspot = 0; /* ignored */
iconinfo_l.yHotspot = 0; /* ignored */
iconinfo_l.hbmMask  = HBMMASK_l;/* AND Mask for a Color Icon; AND+XOR mask for a BW icon */
iconinfo_l.hbmColor = HBMICON_l;/* NULL for a BW icon */

hNewIcon_l = CreateIconIndirect(&iconinfo_l);
errcode_l  = GetLastError();
if(!hNewIcon_l) s_log(LOG_DEBUG, "MYWCEDEFS[%d] : wceDuplicateIcon hNewIcon_l is %x error is %d",__LINE__, hNewIcon_l, errcode_l);

/* Free resources */

DeleteObject(HBMMASK_l);
DeleteObject(HBMICON_l);

DeleteDC(hdcmask);
DeleteDC(hdcsrc);
ReleaseDC(NULL, hdc);
 
return(hNewIcon_l);
}

HINSTANCE wceShellExecute(
    HWND hwnd, 
    LPCTSTR lpVerb,
    LPCTSTR lpFile, 
    LPCTSTR lpParameters, 
    LPCTSTR lpDirectory,
    INT nShowCmd
)
{
SHELLEXECUTEINFO execinfo_l;
BOOL cr_l;

execinfo_l.cbSize = sizeof(SHELLEXECUTEINFO); 
execinfo_l.fMask = 0; 
execinfo_l.hwnd = hwnd; 
execinfo_l.lpVerb = lpVerb; /* must be COMPLETE PATH in WCE, because there is NO "current dir" in WCE */
execinfo_l.lpFile = lpFile; 
execinfo_l.lpParameters = lpParameters; 
execinfo_l.lpDirectory = lpDirectory; 
execinfo_l.nShow = nShowCmd; 
/* output parameter : execinfo_l.hInstApp; */
/* ignored on WCE :
execinfo_l.lpIDList; 
execinfo_l.lpClass; 
execinfo_l.hkeyClass; 
execinfo_l.dwHotKey; 
execinfo_l.hIcon;
*/ 
/* output parameter : execinfo_l.hProcess; */

  
cr_l = ShellExecuteEx(&execinfo_l);
return(execinfo_l.hInstApp);
/* on Win32, hInstApp documented to return EITHER success > 32 or error <= 32, not so clear in WCE. If fails, see BELOW... */
/*
DWORD errcode_l;

errcode_l = GetLastError();
if (!cr_l) return(errcode_l);
return(64); */ /* pdelaage 20140610 : as WCE doc says, returns value > 32 if successful*/

}

DWORD wceGetCurrentDirectory(
  DWORD nBufferLength,  /* size of directory buffer */
  LPTSTR lpBuffer       /* directory buffer */
)
{
DWORD cr_l;
TCHAR car_l;
TCHAR *ch_l = NULL;

cr_l = GetModuleFileName((HMODULE) NULL, lpBuffer, nBufferLength);
if (cr_l == 0) return 0;

/* conversion from filename to pathname */

car_l = TEXT('\\');
#ifdef UNICODE
ch_l = _tcsrchr(lpBuffer, car_l); 		/* in UNICODE, wcsrchr takes car_l as a wchar */
#else
ch_l = _tcsrchr(lpBuffer, (int) car_l); /* in ANSI, strrchr takes car_l as an int ! */
#endif

if (!ch_l) return(0);

*ch_l = TEXT('\0');

return(_tcslen(lpBuffer));
}










More information about the stunnel-users mailing list