Lightnix is a open source serial/parallel port holiday flasher driver for windows. You can see its full capability by opening winlight.exe at the command prompt.
Examples
Flashing lights from serial port com1
Winlight.exe flash=100 com=\\.\COM1
The number in blue is the slowness speed of the flash in milliseconds and \\.\com1 is the com port path. This way can only flash up to 2 strains of lights at once.
program winlight; {$APPTYPE CONSOLE} {$RESOURCE Lightnix.res} uses SysUtils, windows, Classes; const DRVF_USERDEF_MASK=1; type TDriverInfo=record cbSize,Flags,mask:integer; CurrentBuildDate,RequiredBuildDate:TSYSTEMTIME; etc,errormsg:ShortString; end; TOut32=procedure(io:word;x:byte);stdcall; TInp32=function(io:word):byte;stdcall; TDriverInit=function(var drvinfo:tdriverinfo):integer;stdcall; TDriverInp=function(xdefault:integer):integer;stdcall; TDriverOut=function(x:integer):integer;stdcall; var x,y,i:integer; params:tstringlist; io:word; dinfo:TDriverInfo; Out32:tout32; Inp32:tinp32; inpout32,drv:hmodule; driverinit:tdriverinit; driverinp:tdriverinp; driverout:tdriverout; happ,com:thandle; url:string; verinfo:_BY_HANDLE_FILE_INFORMATION; label loop1,loop2; begin dinfo.cbSize:=sizeof(dinfo); happ:=createfile(PChar(paramstr(0)),generic_read,file_share_read,nil,open_existing, file_attribute_normal,0); getfileinformationbyhandle(happ,verinfo); closehandle(happ); filetimetosystemtime(verinfo.ftLastWriteTime,dinfo.currentbuilddate); writeln('Lightnix32 build ',dinfo.currentbuilddate.wMonth,'/', dinfo.currentbuilddate.wDay,'/',dinfo.currentbuilddate.wYear); if paramcount = 0 then begin writeln('Usage: WINLIGHT [option=value]'); writeln('I/O Options:'); writeln('IOAddr Specifies the I/O address to use'); writeln('OUT Specifies what value to set the I/O Address'); writeln('WAIT Specifies the number of seconds to wait,before the address reverts back'); Writeln('FLASH Enter flash mode, its value is a delay in miliseconds'); writeln('MASK Defines the maximum value that it will oscilate to, use with FLASH'); writeln(''); writeln('Serial Options:'); writeln('COM Specifies the COM Port to use. Example COM=\\.\COM1'); writeln('MCR Specifies what to set the Modem Control Register D for Data Terminal Ready and R for Request To Send'); writeln('WAIT Same as above but for serial ports'); writeln('FLASH Same as above but for serial ports'); writeln(''); writeln('Plugin Options:'); writeln('DRIVER Defines the driver DLL file'); writeln('ETC Defines extra settings for the driver'); writeln('WAIT Same as above but for driver'); writeln('OUT Same as above but for driver'); writeln('OUT2 Used only when WAIT is used, its the reverting value'); writeln('FLASH Same as above but for driver'); writeln('MASK Same as above but for driver'); exit; end; params:=tstringlist.create; for i:= 1 to paramcount do params.Add(paramstr(i)); if params.Values['DRIVER']<>'' then begin dinfo.CurrentBuildDate.wDayOfWeek:=0; copymemory(@dinfo.requiredbuilddate,@dinfo.currentbuilddate,sizeof(tsystemtime)); drv:=loadlibrary(pchar(params.values['driver'])); if drv=0 then begin writeln(Syserrormessage(getlasterror));exit;end; @DriverInit:=GetProcAddress(drv,'DriverInit'); @DriverInp:=GetProcAddress(drv,'DriverInp'); @DriverOut:=GetProcAddress(drv,'DriverOut'); if (@driverinit=nil)or(@driverinp=nil)or(@driverout=nil) then begin writeln('Some functions couldnt load'); exitprocess(error_bad_driver); end; dinfo.mask:=strtointdef(params.values['Mask'],255); dinfo.etc:=params.Values['etc']; i:=driverinit(dinfo); if encodedate(dinfo.currentbuilddate.wYear,dinfo.currentbuilddate.wMonth, dinfo.currentbuilddate.wDay)<encodedate(dinfo.requiredbuilddate.wyear, dinfo.requiredbuilddate.wMonth,dinfo.requiredbuilddate.wDay) then begin writeln('This driver requires a newer build in order to run.'); exitprocess(error_bad_device); end; if (i<>0) or (dinfo.errormsg<>'') then begin if dinfo.errormsg='' then begin writeln('DriverInit:',syserrormessage(i)); exitprocess(i); end else begin writeln('DriverInit:',dinfo.errormsg); exitprocess(error_bad_driver); end; end; if params.Values['wait']<>''then begin writeln('Requesting for starting value...'); x:=DriverInp(strtointdef(params.values['out2'],0)); if x<-1 then begin writeln('Driver failed!');exitprocess(error_bad_driver);end; if x=-1 then writeln('There is no starting value') else writeln('Starting value is $',IntToHex(x,0)); driverout(strtointdef(params.values['out'],0)); sleep(1000*strtointdef(params.values['wait'],1)); driverout(x); end; end else if params.Values['IOAddr']<>'' then begin inpout32:=LoadLibrary('inpout32.dll'); @out32:=getprocaddress(inpout32,'Out32'); @inp32:=Getprocaddress(inpout32,'Inp32'); io:= strtointdef(params.values['IOAddr'],$378); x:=inp32(io); writeln('Starting value for $'+inttohex(io,0)+' is $'+inttohex(x,2)); if strtointdef(Params.values['Wait'],0)>0 then begin y:=strtointdef(params.values['out'],$ff); writeln('Outputing $'+inttohex(y,2)); out32(io,y); sleep(1000*strtointdef(params.Values['wait'],1)); writeln('Reverting back'); out32(io,x); exitprocess(0); end; if params.Values['Flash']<>'' then begin write('Sending pulses'); loop1: for x:= 0 to StrTointDef(params.values['Mask'],255) do begin out32(io,x); write('.'); sleep(strtointdef(params.values['flash'],100)); end; goto loop1; end else begin writeln('Sending Byte'); Out32(io,StrToIntDef(params.values['out'],0)); end; end else if params.Values['COM']<>'' then begin com:=createfile(@params.values['com'][1],generic_read,0,nil,open_existing, file_attribute_normal,0); if com=INVALID_HANDLE_VALUE then begin writeln(Syserrormessage(getlasterror)); exitprocess(getlasterror); end; if not escapecommfunction(com,clrdtr) then begin writeln(syserrormessage(getlasterror)); closehandle(com); exitprocess(getlasterror); end; if Params.Values['WAIT']<>'' then begin writeln('Waiting...'); sleep(1000*strtointdef(params.values['wait'],1)); if pos('D',params.values['MCR'])>0 then escapecommfunction(com,setdtr); if pos('R',params.values['MCR'])>0 then escapecommfunction(com,setrts); end; if params.Values['Flash']<>'' then begin write('Sending Pulses'); loop2: EscapeCommfunction(com,clrdtr); EscapeCommFunction(com,clrrts); write('.'); sleep(strtointdef(Params.values['flash'],100)); EscapeCommfunction(com,setdtr); EscapeCommFunction(com,clrrts); write('.'); sleep(strtointdef(Params.values['flash'],100)); EscapeCommfunction(com,clrdtr); EscapeCommFunction(com,setrts); write('.'); sleep(strtointdef(Params.values['flash'],100)); EscapeCommfunction(com,setdtr); EscapeCommFunction(com,setrts); write('.'); sleep(strtointdef(Params.values['flash'],100)); goto loop2; end; closehandle(com); end else writeln('Cannot tell what to use, perhaps you forgot an option.'); end.