README.TXT by Harlan Feinstein, 20 October 1995

Programmer's Notes for Windows Ksign
====================================

The communication model used is non-blocking i/o, very different from the i/o 
that the Unix and Macintosh versions share.  Because of the nature of the 
"multitasking" (or lack thereof) on the Windows platform, this is the most 
acceptable method of i/o, so that background processes (e.g., printing) could 
continue running.

Additionally, instead of using the WSA_ versions of the TCP/IP functions, that 
are more natively Windows-oriented, the i/o has been contained in several 
classes that are used for the communications.  These classes and their methods 
reside in CWINSOCK.CPP, and come verbatim from a distribution disk that comes 
with the book "Programming WINSOCK."

This i/o is completely event-driven, and what this means is that I've set up a 
callback function that fields the WM_USER_STREAM user-defined message.  I 
bring up a CWinSock object after doing other initalization in the OnCreate() 
function. Then a CStreamSocket object is initialized, and this is where the 
callback window and callback message (WM_USER_STREAM) are bound to the stream.

Any of the methods that I use from that point on (e.g., Connect, Write) don't 
block, but rather send this message to the window.  The function OnStream() 
has been bound to WM_USER_STREAM, and checks the wParam message parameter to 
see what type of event has completed.

Since the same OnStream() function is used for two conversations with the 
transd daemon, a state variable is used to keep track of the overall status, 
and which conversation the execution's in the middle of.  This variable, 
m_nState, gets upgraded through the following values: UNINITIALIZED, 
ORDERAUTHSPOOLING, ORDERAUTHCOMPLETE, ORDERREQUESTED, ORDERSPOOLING, 
WAITONUSER, SIGNAUTHSPOOLING,  SIGNAUTHCOMPLETE, SIGNPRESSED, SIGNREQUESTED, 
SIGNSPOOLING, and SIGNDONE.  These are implemented with enum in the KSIGN.H 
file.  The Upgrade() function was written to work as an increment for this 
enum type.

In terms of timing, OnCreate() has all the events that are to transpire when 
the program starts up, and OnDestroy() has all those events to run when the 
program exits.

Another difference on the Windows platform is that when receiving multiple 
lines of text (e.g., receiving the order text in preparation for display), the 
PC has a different need for carriage-returns and linefeeds.  The multiline 
edit box in particular needs for there to be a linefeed, then a carriage 
return ("\r\n").  Neither can be missing, and it must be in that order.  The 
way I've implemented this is to skim through the text as it's received, ignore 
all the linefeeds, and from each newline, manually add a linefeed back in 
before it.  You can see this in ProcessOrder() and ProcessSignature().

The future of the program, possible tweaks: neither of the versions of the GSS 
library we got for Windows contained the gss_str_to_oid() function, so there's 
a block of unchecked, untested code that I've inserted but commented out.  At 
some future point that can be used.  Also, working only in our testbed setup, 
I don't have more than an "academic" idea of what the most common errors will 
be.  I have TRACE() statements in many places, if the code needs to be run in 
Debug mode.  Also, I've put in MessageBox() calls to inform the user, with 
rather basic error messages, of problems in sealing packets or starting up 
sockets, and other problems of that sort.  If some of the errors end up 
happening often, as a result of user error or something, you might think about 
tweaking the error messages to whatever the users understand best.
