Click here to Skip to main content
15,879,348 members
Articles / TFTP

Writing a tftp Server Windows Service

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
9 Jun 2010CPOL3 min read 21.8K   5  
A tftp server running as service on Windows. Includes tftpUtil class library and service control source code in C#

For an actual project, I needed a tftp server service for a Windows 2003 server. I looked around on the internet and only found tftp servers running in user space, no real Windows service. So I searched for source code applications I could use and found tftpUtil at sourceforge.net (here). Although the short description states it would implement a service, it does not in reality. But the tftpUtil class was more or less easy to use and so I started to write a service ‘wrapper’ around it.

C#
        protected override void OnStart(string[] args)
        {
            AddLog("OnStart entered...");
            StartTFTPServer();
...
        }

        protected override void OnStop()
        {
            tftp.StopListener();
            if (TFTPServerThread != null)
                TFTPServerThread.Abort();
            TFTPServerThread = null;
            timerEvents.Stop();
            StopTFTPServer();
            GC.Collect(); 
        }

The StartTFTPServer code uses the same class file ServerSettings.cs as used in the desktop app project (tftpUtilSvcSettings), this is easier to manage:

C#
try
{
    AddLog("CreateTFTPFromReg reading path");
    Path = svcSettings.sPath;
    LoggingLevel = svcSettings.LoggingLevel;
    DisplayLevel = svcSettings.SendEventLevel;
    FileAccess = svcSettings.FileAccess;
    AllowOptions = svcSettings.AllowOptions;
    RRQWRQStateCheck = svcSettings.RRQWRQStateCheck;

    AddLog("CreateTFTPFromReg reading IPstring");
    string IPstring = svcSettings.ServerIPAddr;
    if (IPstring.ToLower() == "any")
        ServerIPAddr = System.Net.IPAddress.Any;
    else
        System.Net.IPAddress.TryParse(IPstring, out ServerIPAddr);

    AddLog("CreateTFTPFromReg reading ServerUDPPort");
    ServerUDPPort = Convert.ToInt32(svcSettings.ServerUDPPort);
    iTimeout = Convert.ToInt32(svcSettings.Timeout);
    Resend = Convert.ToInt32(svcSettings.Resend);

    AddLog("CreateTFTPFromReg reading LoggingMethodInfo");
    LoggingMethodInfo[0] = svcSettings.LoggingMethod;
    LoggingMethodInfo[1] = svcSettings.LoggingOptions;

    //bool ShowAlert = false;
    AddLog("CreateTFTPFromReg reading BlockedIPs");
    BlockedIPs = svcSettings.BlockedIPs;

    AddLog("CreateTFTPFromReg starting new TFTPServer(...)");
    if (ServerIPAddr == null)
        tftp = new TFTPServer(ServerUDPPort, Path, LoggingLevel,
        DisplayLevel, FileAccess, AllowOptions, RRQWRQStateCheck,
        Resend, iTimeout, LoggingMethodInfo, BlockedIPs);
    else
        tftp = new TFTPServer(ServerUDPPort, Path, LoggingLevel,
        DisplayLevel, FileAccess, AllowOptions, RRQWRQStateCheck,
        Resend, iTimeout, LoggingMethodInfo, BlockedIPs, ServerIPAddr);
    returnval = true;
    AddLog("CreateTFTPFromReg everything seems to be OK");
}
catch (Exception ex)
{
    AddLog("CreateTFTPFromReg EXCEPTION:" + ex.Message);
}
return returnval;

Changing Service Settings

As I would like to control the service later and change settings, I needed a way to ‘communicate’ with the server. I started with using the registry, but that did not work first. The service was unable to access [HKLM]Software\tftpUtilSvc. I researched and found the idea to use [HKU].Default\Software\tftpUtilSvc. Although the registry location does not look nice (I mean service parameters have to reside below HKLM, but who cares), I tried the HKEY_USER.Default location and the service was able to load the values from the registry. Did not find any reference, why the service cannot access other root registry trees.

Here is my ugly "tftpUtilSvcSettings" application:

Image 1

Although the tftpUtil code from sourceforge already contained code to write/read tftp settings to/from registry, it was not very clear and straight. I implemented a ServerSettings class and changed all direct references to the registry to this class. Inside the class, ServerSettings.cs, the values are saved/restored to the registry. As I did not like to change too much of the original tftpUtil class, there may be strange looking constructs and possible duplicate internal values.

During my debugging tests, the service did not start/stop correctly sometimes, due to errors in code. As the service remained in a disabled state, I had to rename all tftpUtilSvc service names to be able to test one more time without having to reboot my PC. If a service gets into this state, the service control manager is unable to remove the service as "InstallUtil.exe /u" was unable to uninstall the ‘broken’ service.

The Service Installer and Controller

The tftp server service should later run on a Windows 2003 server and as I did not like to copy InstallUtil and possibly other files onto the server and then run InstallUtil.exe to install the service, I researched and found some cool CSharp code to install/uninstall/start/stop/restart a service from code. This code has been integrated into the tftpUtilSvcSettings application (see ServiceUtils.cs) and so there is no real need for an installer. It is possible to just copy the files:

  • nspring.dll
  • TFTPUtil.dll
  • tftpUtilSvc.exe
  • tftpUtilSvcSettings.exe

into one directory and then launch tftpUtilSvcSettings from there (assumed the DotNet runtimes are already installed). Then, you can install and start the service directly from the tftpUtilSettings application.

A tftp Test Client

Included with the source code of tftpUtil of sourceforge is a project called "TFTPUtil Client GUI". The name made me think this is a tftp client I could use to test the server. BUT this is not a tftp client, it is just a dialog driven tftpUtil server. To test the tftp server, I finally used also code found on the internet: tftpClient at CodeProject.com. It is very simple code, no threading, no events, no progress indicator. I added a very simple interface and included the tftpClient class file to be able to do simple tests against the tftpUtil service. The tftpClient project is available as a separate download for interested readers.

Image 2

Downloads (Visual Studio 2008)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --