Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Design

Letters


Jan99: Letters

Dear DDJ,

In his article "The Windows CE 2.0 Remote API" (DDJ, September 1998), Andrew Tucker explored some of the possibilities offered by the CeRapiInvoke API. Unfortunately, there are some major flaws with the stream mode implementation of CeRapiInvoke that Andrew did not mention.

It states that CeRapiInvoke in stream mode returns an IRAPIStream* that lets you perform asynchronous communications with the Windows CE device. The problem, however, is that this stream seems to be the same stream used by the Remote API (RAPI) for other RAPI function calls. (For example, CeRapiInvoke in stream mode appears to simply hook into the underlying communications channel used by the remainder of the RAPI).

This means that no RAPI function may be called as long as your application maintains a reference to the IRAPIStream object. Any RAPI functions that are called while the stream object exists simply block.

If you create a thread, which listens to the stream, as is done in Andrew's sample program, things gets even more interesting. Apparently, RAPI calls are encoded as some type of request and transmitted to the Windows CE device across the stream. Thus, the thread that reads from the stream will intercept any such requests. The RAPI function will of course block as it waits for an answer to its request.

We haven't performed exhaustive testing to see if every RAPI function will block after invoking CeRapiInvoke in stream mode (and before releasing the stream) but, in testing a number of RAPI functions (such as CeGetVersionEx, CeFindAllDatabases, and CeRegOpenKeyEx) we have yet to find one that completes successfully.

We're providing (available electronically; see "Resource Center," page 5) a modified version of the stream mode sample program which Andrew wrote. We modified it to support bidirectional communication in a chat style. Further, a menu has been added which allows you to trigger various RAPI functions. The communication does not have to be bi-directional for the problems mentioned earlier to be apparent.

We tested Visual C++ 5.0 with both the H/PC and P/PC toolkits running under NT 4.0 SP3 using Windows CE Services 2.1. We connected with an Ericsson MC16 and a Philips Velo 500 using direct cable connection, network connection via LAN and network dial-up connection.

Based on these observations (and Andrew's comments about the Set/GetRapiStat methods), we are forced to conclude that the stream mode of CeRapiInvoke, while interesting, is a somewhat less than versatile tool. While useful in a severely limited way, it would be more accurate to describe this little nugget of the API (and its accompanying documentation) as horribly broken!

Roger McFarlane at [email protected]
Costa Siourbas at [email protected]

Year 2000 Fix

Dear DDJ,

I was surprised when I read your "News & Views" about the year 2000 correction (DDJ, October 1998). I have used the simple solution described there since 1992 in projects for 8-bit microcontrollers (like MC68HC05), especially when I need days calculations. In this simple solution, you can calculate the days passing from one event to another, with a simple converter function. I would never think about this solution as a patent pending since there is no new technology, nor a new date structure for calculations.

Nassie Evyatar
[email protected]

Dear DDJ,

I just read of the Y2K software patent filed for by Wesley Stout in the October 1998 "News & Views." This only serves as yet another reminder of how bad the software patent problem is becoming. Many publications, including DDJ, have published articles on the Y2K problem and possible solutions. Many of these articles have given the solution Mr. Stout is trying to patent; some ignorant patent clerk and judge will probably grant it as well. It brings to mind the infamous XOR patent that put Commodore out of business, or the patent on storing more than one type of data on a storage media. Patents like this only hurt the software industry and stifle further growth. Excuse me now, but I have to run out and get a patent on using contractions for the days of the week; anyone using "MON" for "MONDAY" will have to pay me a royalty.

Joseph Fenton
[email protected]

Dear DDJ,

Has anybody discussed or acknowledged the "hidden" Y2K date issues with Microsoft software from a developers standpoint?

What I am referring to (in Visual Basic terms) is the use of "Long Date" and "Short Date" formats, and the fact that in Windows 95/98/NT you can change your Long and Short date formats to be set to formats not in the drop-down box, that may or may not display correctly, or be interpreted correctly by application programs.

For example, go to the Control Panel-Regional Settings, and set the date formats

Short Date: M/d/y

Long Date: M/d/yy

The Short Date format is accepted by Win95, but NT will display it as M/d/yy -- until you do something like try formatting a date with that "Short Date" format, in which case you get a strange year. Also, if the user changes the Long Date format to a two-digit year, and the program somewhere formats the date to "Long Date" then stores it, totally new problems can be created for the application.

If you really want to raise some eyebrows, try this in VB5 or above: Create a form, with txt1...txt8 (labels) with label1...label8 (labels) and a command button with Listing One. Use the button to refresh the screen, and then goto control panel regional settings, date, and play with the date formats.

Justin Gale
[email protected]

DebugAPI

Dear DDJ,

I enjoyed Fritz Lowrey's article "Examining the Win32 Debug API" (DDJ, November 1998). I have been programming NT Services for some time now and can attest to the utility of the Debug API and OutputDebugString in particular. I have found the class in Listing Two to be useful under MSVC5.0 and 6.0. It wraps the OutputDebugString function in a class that permits stream operations.

The conditional compilation flags allow the machinery to be removed for a release build; but, as Fritz points out, that is not really necessary. With more ambition, and time, you can create a streambuf and then an ostream that does the same thing more elegantly and safely. If the debug output is to be left in the final build, I strongly recommend that one do just that; or, at the very least, handle the failure modes of the simple class presented here.

The class (see Listing Three for DbgPrint.h) is designed to handle only character strings and will not properly handle wide character strings. This was chosen since debug output usually contains text typed in by the programmer, and it rapidly becomes tiresome to type L ''blah, blah, blah" rather than just "blah, blah, blah."

Robert Stafford
[email protected]

Template-Driven Web Pages

Dear DDJ,

The article "Template-Driven Web Pages," by Jay Johansen (DDJ, November 1997) described a CGI solution to allow visitors to update web pages. He covered a few different methods of security including disallowing "bad" HTML. However, the method described does not provide the security desired.

The problem with most early attempts at CGI security when passing untrusted input to shells was that they removed "bad" characters, however, some little used characters were overlooked, or environment variables not checked breaching the security.

Removing "bad" input is not safe enough, the moral of the CGI story is to only allow "good" input, since it is harder to include a bad input in your good list than to overlook some little known bad input.

The method Jay used was described in the article as "simply disallow all markup tags from user input by removing all '<' and '>' characters and everything in between."

HTML containing "&{location.replace('http://evil.replica.com')};" will cause Netscape 3.0 and later with Javascript enabled to go to replace the current page with the specified URL in the window and in the history, so the back button will go to the page before the original page. This could be used to make a replica of your web site with sensitive information modified. A less sophisticated attack could use &{while(true)alert('')}; which will lock up the browser.

The problem is that Javascript doesn't need to be within <SCRIPT> tags in Netscape 3.0 it can be in a special Javascript HTML entity.

The only way to be truly secure is to encode the supplied text using the standard encode method provided by most CGI libraries, this will encode all the characters special to HTML including <,>, and &. Encoding the text after removing the tags would be the simplest modification required.

Sam Holden
[email protected]

DDA and Fast Image Scaling

Dear DDJ,

I'm writing in response to an article "A 2D DDA Algorithm for Fast Image Scaling" by Dean Clark (DDJ, April 1997). It appears that the algorithm Dean describes can be optimized and simplified even further.

The gist of the algorithm to scale a NM0 image to a new NM1 pixel grid is described in Example 1 of the article:

For clarity, the example described the algorithm in 1D; scale is the ratio of the number of output pixels to that of the original pixels (along X or Y dimension), that is, N1/N0. The algorithm as presented involves some floating-point computations. As Dean writes, "To get rid of the floating-point numbers, simply scale up the differential. Let's use a scaling constant 1000 an cast the differential to an int using Dx = (int)(1.0/scale*1000); There is no real magic to 1000..."

Well, there is magic: note, that scale is N1/N0, that is, the differential is N0/N1. Thus N1 (rather than 1000) is the natural (and the best) scaling factor. It frees the algorithm from any floating-point computations whatsoever; see Example 2.

Note that all computations in this algorithm are integer from the outset. There are not a single multiplication/division, either. The accumulated differential can never become greater than twice the number of original pixels, N0. Thus we are guaranteed to never run into overflow or other nasty thing. The internal while loop would run at most 2*scale times (that is, floor(2*N0/N1): unless the image is being shrunk more than twice, the loop would never go through more than two iterations). The algorithm appears more in Bresenham's spirit. As a spot validation test, it's easy to see that if N0=N1, the algorithm copies pixels; if N0=2*N1, the algorithm skips every other original pixel, and if N1=2*N0, it duplicates the pixels.

The 1D algorithm presented earlier can be generalized to 2D as the article describes in detail.

Oleg Kiselyov
[email protected]

Dean responds: Yes, the scale factor is N1/N0, where N0 is the original image dimension, and N1 is the scaled dimension. However, don't forget that the algorithm doesn't know what N1 is, only what N0 (and M0) is. We would have to calculate N1, to wit: N1 = (int)(N0 * scale), which is still a floating-point expression. So either way there's one FP in the code.

Also, although your idea of using the number of original pixels (did you mean the number of scaled pixels? You said "N1" in the paragraph) would likely be acceptable in many cases, there's a potential for excessive resampling errors if the the multiplication factor (my 1000 magic number) is too small. Scaling up the differential and truncating it to an integer saves a bunch of FP additions and compares, but also throws away some precision. Don't know for sure what the minimum factor is but intuitively it seems that it would be max(M1,N1). My experience over the last 8+ years is that 1000 works fine, but calculating N1 is probably more correct.

As far as your color interpolation idea, the algorithm from the article can be used to do interpolated image scaling since the differentials (as floats this time) are the interpolation factors (for linear interpolation, that is). What's much more interesting is, how can you arrange your color table so that, in general, two pixels that are separated by some span contain colors that are separated by some predetermined constant? Seems to me that's the hard part! Of course I'm assuming it's not just an "intensity" image, where the display value maps one-to-one with the color palette entry. Thanks.

DDJ

Listing One

Private Sub Command1_Click()Dim Test_Date As Date
Dim Test_Text As String
    Test_Date =3D Now
    Label1.Caption =3D Format(Date, "Long Date")
    Test_Text =3D Format(Date, "Short Date")
    Test_Date =3D CDate(Test_Text)
    Label2.Caption =3D Format(Date, "Short Date")
    Label3.Caption =3D Date
    Label4.Caption =3D Format(Now, "Long Date")
    Label5.Caption =3D Format(Now, "Short Date")
    Label6.Caption =3D Now
    Label7.Caption =3D Format(Test_Date, "M/d/yyyy")
    Label8.Caption =3D DateDiff("m", "10/08/1998", Test_Date)
End Sub
Private Sub Form_Load()
    txt1 =3D "Format(Date,Long Date)"
    txt2 =3D "Format(Date,Short Date)"
    txt3 =3D "Date"
    txt4 =3D "Format(Now,Long Date)"
    txt5 =3D "Format(Now,Short Date)"
    txt6 =3D "Now"
    txt7 =3D "Variable set Long Date-yyyy format"
    txt8 =3D "DateDiff(m,10/08/1998," & Test_Date & ")"
    Command1_Click
End Sub

Back to Article

Listing Two

int threadMain(){
 DbgPrint dbg;
    ...
 dbg << "Thread[" << std::setw(4) << ::GetCurrentThreadId() << "] Starting.";
    ...
}

Back to Article

Listing Three

#ifndef DBGPRINT#define DBGPRINT
// A simple class to wrap calls to OutputDebugString(). It can be used
// like a stream--it understands how to format anything you can pass to
// cout. The dtor flushes the accumulated string. If you wish to put
// several messages using the same object, the flush() member function
// will output the accumulated string and start again with an empty
// one. The clear() member function will discard any pending string.


</p>
#if defined(_DEBUG) || defined(DEBUG)


</p>
#ifndef _WINDOWS_
#include <windows.h>
#endif


</p>
#include <iostream>
#include <sstream>
#include <iomanip>


</p>
class DbgPrint
{
        // Don't allow these
        DbgPrint(const DbgPrint &rhs);
        DbgPrint& operator=(const DbgPrint &rhs);
        std::ostringstream* myStream;
        void out()
        {
                std::string s = myStream->str();
                OutputDebugStringA(s.c_str());
        }
public:
        DbgPrint() {myStream = new std::ostringstream;}


</p>
        void clear() {delete myStream;myStream = new std::ostringstream;}
        void flush()
        {
                out();
                clear();
        }
        template<class I>
        DbgPrint& operator << (const I& i)
       {
                (*myStream) << i;
                return *this;
        }
        ~DbgPrint()
        {
                out();
                delete myStream;
        }
};
#else
class DbgPrint
{
        DbgPrint(const DbgPrint &rhs);
        DbgPrint& operator=(const DbgPrint &rhs);
        void out() {}
public:
        DbgPrint() {}
        void clear() {}
        void flush() {}
        template<class I>
        DbgPrint& operator << (const I&) {return *this;}
        ~DbgPrint() {}
};
#endif
#endif

Back to Article


Copyright © 1999, Dr. Dobb's Journal

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.