“Path not found” with subst

The subst help display this

Associates a path with a drive letter.

SUBST [drive1: [drive2:]path]
SUBST drive1: /D

drive1: Specifies a virtual drive to which you want to assign a path.
[drive2:]path Specifies a physical drive and path you want to assign to
a virtual drive.
/D Deletes a substituted (virtual) drive.

Type SUBST with no parameters to display a list of current virtual drives.

Which is not really helpful when I encounter this

c:Program Files (x86)Microsoft Visual Studio 10.0VC>subst Y: “c:Program File
s (x86)Microsoft Visual Studio 10.0VC”
Path not found – C:Program Files (x86)Microsoft Visual Studio 10.0VC

Several searches on Google points to things like moved folder or incorrect path, with is not my problem, that is when I figured out what works:

c:Program Files (x86)Microsoft Visual Studio 10.0VC>subst Y: “c:Program File
s (x86)Microsoft Visual Studio 10.0VC”

c:Program Files (x86)Microsoft Visual Studio 10.0VC>

 

Just remove the trailing ” from the path. It’s understandable from a DOS viewpoint that you have to supply a directory name not a path but I have been copying and paste Windows paths for years now without any problem. It looks like Microsoft forgot to update this corner of its apps

Building WS4D-gSOAP on Linux

WS4D-gSOAP is a framework that assists development of web services on multiple platforms. These includes mobile phones, server, computers or embedded system.

WS4D Features

WS4D can run as a standalone application or based upon a server and has been used in many commercial products. Despite being the most prominent framework for embedded system SOAP services, WS4D seems to be lacking behind in version support and documentation. Namely, you cannot build the latest version of WS4D-gSOAP with the latest version of gSOAP, even though both frameworks’ last version were one or two years ago. Development doesn’t seem to be active, so does the community. Finding help is a big hassle!

So, this post outlines some problems i encountered while working with the framework and how to solve them, hoping that the next follower won’t have as much trouble starting in a new environment.

Terminology

It seems that the WS4D documentation assumes that you have a certain level of understanding on Unix-based build system and working across platform. You cannot find definition for several new terminologies used in the documentation, so the docs may be quite confusing and intimidating for new users. I find these words particularly weird:

  • In source build: The binaries will be generated inside the same directory as the source. This has the advantage of simplifying the make files as you don’t have to link and copy libraries over, but the directory may look extremely messy.
  • Out-of-source build: Separate source and binary directories. This is the configuration used by WS4D tutorial and code. The sample make file in the tutorial already to the hard work and creates the most common directories used in almost all WS4D projects.
  • Cross-compile (and compilation): This means instead of compiling only one binary to use on your development platform, it will compile another binary for another platform. What do you do with this second binary is up to you: you can push it to the device or run it in a simulator, but cmake’s job in this case is only generating the binary file for you.
  • Tool-chain: A set of compiler and linker for a specific device or platform. Cross-compiling uses two or more tool-chain to generate two or more executable.

Proper version

The documentation for WS4D is a bit disorganized, so it may not relevant for first-time readers that you must compile WS4D with specific versions of gSOAP, doing otherwise will lead to make-errors and build headaches. It is mentioned in Features page (which is not visible from the first page of documentation). I was reading only the installation instruction and tutorial when I started to build the system, so I missed this important fact! How should I know that Getting Started is not a good place to get started?

ws4d-gsoap 0.7.x ws4d-gsoap 0.8.x ws4d-gsoap trunk
 gSOAP 2.8.0 Not yet supported Not yet supported Not yet supported
 gSOAP 2.7.17 Not yet supported supported with patch supported with patch
 gSOAP 2.7.16 Not yet supported supported with patch supported with patch
 gSOAP 2.7.15 Not yet supported Not yet supported Not yet supported
 gSOAP 2.7.14 Not yet supported Not yet supported Not yet supported
 gSOAP 2.7.13 supported supported supported
 gSOAP 2.7.12 supported supported supported
 gSOAP 2.7.11 supported supported supported
 gSOAP 2.7.10 supported supported supported

So the latest version of the stack you can use is gSOAP 2.7.17 with WS4D-gSOAP 0.8. I don’t know why it is so complicated, maybe due to the fact the gSOAP 2.8 also implemented WS-Discovery (a feature overlap with WS4D), and the auther didn’t have enough time to adjust WS4D-gSOAP to the new changes.

Build steps and permissions

Supposed you have decent Linux knowledge, you can use this inside the directory where WS4D-gSOAP was extracted to

  1. ./configure
  2. ccmake .
  3. Edit path to gSOAP directory (the source you downloaded, do not ‘make install’ this)
  4. Press g to generate, there may by some warning, ignore them
  5. Press c to configure
  6. make (I don’t know why this step is needed, but if you misses this step, the next step will result in various errors. This step will result in errors)
  7. su -c ‘make’ – (You can’t use sudo, you have to use su with a trialing dash to load root user’s environment. Root permission is required to install binaries to their proper locations)

Web service for device (WS4D) and using make, cmake with Integrated Development Environments (IDEs) on Linux

WS4D-gSOAP is a framework to deploy web services on multiple environments (computers, embedded devices, phones…) without having to rewrite code. More introduction information can be found in this post. The downside for WS4D is that the build system is based on cmake, and it’s a bit complicated to use. I have since managed to successfully build the stack from source (there’s no binary distribution). But I ran into numerous problems during my time getting familiar with the stack. Namely following the tutorial.

Even for such a simple task of copying and pasting code from the tutorial (The Air Conditioner tutorial), I did not succeed. The client and device doesn’t seem to be able to communicate with each other. Even though the tutorial have been kind enough to include logging code (send, received and memory allocations), I’m still unable to figure out where the problem lies. And that’s when I think I’m forced to perform debugging on the project. That leads to a big problem: what am I supposed to use to debug this?

So I tried to install Code Blocks, but it doesn’t support cmake projects, it couldn’t import the CMakeList.txt. Then reading through several articles revealed Eclipse to be a pretty good gdb front-end, I installed it, and have successfully imported the project, but I was hit with several problems:

  • I couldn’t build the project, Eclipse’s project structure was make-based, not cmake-based, trying to ‘make all’ or ‘make clean’ with Eclipse obviously would generate errors
  • Editing  the code is an eyesore because Eclipse doesn’t seem to be able to recognize include and libraries directories even after I added them manually in project properties.
After several more hours of analyzing WS4D-gSOAP documentation (not really helpful, they are only related to build and run with command line), cmake (wiki pages after wiki pages with no structure between pages and in articles), Eclipse and Code Blocks’ documentation on make projects; I finally realized the right way to do this: cmake supports generating make-based projects for both Code Blocks and Eclipse, and it’s as simple as this:
  1. Go to the directory where you would normally run cmake to build your project from the command line
  2. Perform

    cmake -G"Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../certi_src
    cmake . -G "CodeBlocks - Unix Makefiles"
  3. Import

    The project directory
    ProjectName.cbp file
You can now work with the project normally within your preferred IDE

Management task: Remote shutdown utility

I run a simple web server to serve as a storage medium for my mobile devices (I don’t like using dropbox or other online storage solutions because they don’t offer much space and they hogs up bandwidth unnecessarily). Before I go to sleep I usually shut down the server to save energy, but in order to do so, I have to have another computer turned on to perform remote access into the server and shut it down via command line. Occasionally, I would turn off my work computer before I remember that I want to shut down the server and I’m too lazy by then to turn on my work computer again.

That’s why I wanted an application that is capable of shutting down Windows on my behalf. The scenario is like this: because I can access FTP service from my phone, I will create a file, namely ‘shutdown’; when the server sees this file, it will delete the file and initiate shutdown. Quite simple.

To shut down, I use Windows management interface (System.Management namespace in C#)

        static void Shutdown()
        {
            ManagementBaseObject mboShutdown = null;
            ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem");
            mcWin32.Get();

            // You can't shutdown without security privileges
            mcWin32.Scope.Options.EnablePrivileges = true;
            ManagementBaseObject mboShutdownParams =
                     mcWin32.GetMethodParameters("Win32Shutdown");

            // Flag 1 means we want to shut down the system. Use "2" to reboot.
            mboShutdownParams["Flags"] = "1";
            mboShutdownParams["Reserved"] = "0";
            foreach (ManagementObject manObj in mcWin32.GetInstances())
            {
                mboShutdown = manObj.InvokeMethod("Win32Shutdown",
                                               mboShutdownParams, null);
            }
        }

From here

And the rest is just a loop to check if the file exists

        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            while (true)
            {
                if (!System.IO.File.Exists("D:\Shutdown"))
                {
                    Thread.Sleep(500);
                }
                else
                {
                    System.IO.File.Delete("D:\Shutdown");
                    Shutdown();
                    return;
                }
            }
        }

That’s it, I run the application and it will wait until I create a file named ‘shutdown’ in D:, it will perform shutdown and quit

Here’s the sample code and binary