Feedback Request for Curated Content Views

Publishing technical documentation is an interesting business, and a lot of discussion & deliberation goes into the creation process for articles and videos that we produce at Microsoft. For example, when I am writing an article for IIS, should I publish that on www.iis.net, or technet.microsoft.com, or msdn.microsoft.com? Or should I just write a blog about it? And after I have published an article, how will my intended audience find it? As we continue to publish hundreds of technical articles to the websites that I just mentioned, the navigation hierarchy becomes increasingly complex, and content discoverability suffers.

Some time ago a few of our writers began to experiment with a new way to consolidate lists of related content into something that we called a "Content Map." The following pages will show you an example of what the Content Map concept looks like:

Each of these articles received a great deal of positive feedback from customers, but our team wanted to see if there was a way that customers could help us to improve on this design. We know that there is a great deal of third-party content on the Internet, and we wanted a way to recognize that. We also asked several customers about what kinds of content they need to be successful, and we added their suggestions to our deliberation process.

As a result of our collective discussions, we came up with an idea for what we are internally calling "Curated Content Views." These "views" are lists of related content topics that are organized to answer a particular question or customer need. A view is assembled by someone at Microsoft based on input from anyone who thinks that an article, blog, video, or code sample might be beneficial as part of the view.

With that in mind, here are three conceptual content views that a few of the writers on our content team have assembled:

Our team is requesting feedback from members of the community regarding these conceptual views with regard to the level of detail that is included in each view, the conceptual layouts that were used, and any thoughts about how this content compares with existing table of contents topics or content maps. You can reply to our content team via email, or you can post a response to this blog.

While we are interested in any feedback you may have, our team has put together the following list of specific questions to think about:

  1. Each curated view/content map includes a list of suggested content links. Below is a list of additional information that could be provided with each link. Which of these are most important?
    • Date that the content was posted.
    • Type of content (video, article, code sample, etc.).
    • Author name.
    • Short description.
    • Level of difficulty of the content.
    • Version of software/framework or SDK the content refers to.
    • Website the content appears on.
    • Number of likes or positive reviews.
    • Rating assigned to the content by the community.
  2. If you opened a page similar to one of these curated views/content maps from Google or Bing search results, would you be likely to try the links on this page or just return to search results?
  3. If Microsoft and community experts published a large set of content views similar to these on a website, would you visit that site first when you had technical questions, or would you do an Internet search on Google/Bing first?
  4. Do the questions addressed by each curated view seem too narrow or too broad in scope to be helpful? If so, which ones?
  5. Do any of the curated views/content maps provide too much or too little detail for each link in the list? If so, which ones?
  6. Do you find it helpful to see the profile of the person who created the curated view/content map?
  7. If we provided an easy way for you to publish your own curated views (with attribution) to a common site together with the Microsoft-created curated views, would you be interested in doing so? Why or why not?
  8. If we provided an easy way for you to suggest new content items to add to content views/content maps that have already been published, would you be interested in doing so? Why or why not?
  9. What would make these content views/content maps more helpful?

Thanks!


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

IIS 6.0 WebDAV and Compound Document Format Files Revisited with Workarounds

A few years ago I wrote the following blog, wherein I described how the WebDAV functionality in IIS 6.0 worked with files that are Compound Document format:

IIS 6.0 WebDAV and Compound Document Format Files

As I explained in that blog post, WebDAV needs somewhere to store "properties" for files that are uploaded to the server, and WebDAV uses the compound document format to accomplish this according to the following implementation logic:

  • If the file is already in the compound document file format, IIS simply adds the WebDAV properties to the existing file. This data will not be used by the application that created the file - it will only be used by WebDAV. However, the file size will increase because WebDAV properties are added to the compound document.
  • For other files, WebDAV stores a compound document in an NTFS alternate data stream that is attached to the file. You will never see this additional data from any directory listing, and the file size doesn't change because it's in an alternate data stream.

I recently had a customer contact me in order to ask if there was a way to disable this functionality since he didn't want his files modified in order to store the WebDAV properties. Unfortunately there is no built-in option for IIS that will disable this functionality, but there are a few workarounds.

Workaround #1 - Change the File Type

First and foremost - you can change your file type to something other than the compound document format. For example, if you are uploading files that were created in Microsoft Office, if you can upload your files in the newer Office Open XML formats, then you will not run into this problem. By way of explanation, older Microsoft Office files are in compound document format, whereas files that are that are created with Microsoft Office 2010 and later are in a zipped, XML-based file format. These files will have extensions like *.DOCX for Microsoft Word documents, *.XLSX for Microsoft Excel spreadsheets, and *.PPTX for Microsoft PowerPoint presentations.

Workaround #2 - Wrap Compound Document Files in a Separate File Type

If you are using a file that must be in compound document format, like a setup package in Microsoft Installer (*.MSI) format, you can upload the file in a *.ZIP file, or you can wrap the setup package inside a self-extracting executable by using a technology like Microsoft's IExpress Wizard (which ships as a built-in utility with most versions of Windows).

Workaround #3 - Block WebDAV Properties

If you absolutely cannot change your document from compound document format, I have a completely unsupported workaround that I can suggest. Since the problem arises when properties are added to a file, you can find a way to intercept the WebDAV commands that try to set properties. The actual HTTP verb that is used is PROPPATCH, so if you can find a way to keep this command from being used, then you can prevent files from being modified. Unfortunately you cannot simply suppress PROPPATCH commands by using a security tool like Microsoft's UrlScan to block the command, because this will cause many WebDAV clients to fail.

Instead, what I did as a workaround was to write an example ISAPI filter for IIS 6.0 that intercepts incoming PROPPATCH commands and always sends a successful (e.g. "200 OK") response to the WebDAV client, but in reality the filter does nothing with the properties and ends the request processing. This tricks a WebDAV client into thinking that it succeeded, and it prevents your files in compound document format from being modified. However, this also means that no WebDAV properties will ever be stored with your files; but if that's acceptable to you, (and it usually should be), then you can use this workaround.

With that in mind, here's the C++ code for my example ISAPI filter, and please remember that this is a completely unsupported workaround that is intended for use only when you cannot repackage your files to use something other than the compound document format.

#define _WIN32_WINNT 0x0400

#include <windows.h>
#include <httpfilt.h>

#define STRSAFE_LIB
#include <strsafe.h>

#define BUFFER_SIZE 2048

const char xmlpart1[] = "<?xml version=\"1.0\"?>"
  "<a:multistatus xmlns:a=\"DAV:\">"
  "<a:response>"
  "<a:href>";

const char xmlpart2[] = "</a:href>"
  "<a:propstat>"
  "<a:status>HTTP/1.1 200 OK</a:status>"
  "</a:propstat>"
  "</a:response>"
  "</a:multistatus>";

BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
  HRESULT hr = S_OK;
  // Set the filter's version.
  pVer->dwFilterVersion = HTTP_FILTER_REVISION;
  // Set the filter's description.
  hr = StringCchCopyEx(
    pVer->lpszFilterDesc,256,"PROPPATCH",
    NULL,NULL,STRSAFE_IGNORE_NULLS);
  if (FAILED(hr)) return FALSE;
  // Set the filter's flags.
  pVer->dwFlags = SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_PREPROC_HEADERS;
  return TRUE;
}

DWORD WINAPI HttpFilterProc(
  PHTTP_FILTER_CONTEXT pfc,
  DWORD NotificationType,
  LPVOID pvNotification )
{
  // Verify the correct notification.
  if ( NotificationType == SF_NOTIFY_PREPROC_HEADERS)
  {
    PHTTP_FILTER_PREPROC_HEADERS pHeaders;
    HRESULT hr = S_OK;
  
    bool fSecure = false;

    char szServerName[BUFFER_SIZE] = "";
    char szSecure[2] = "";
    char szResponseXML[BUFFER_SIZE] = "";
    char szResponseURL[BUFFER_SIZE] = "";
    char szRequestURL[BUFFER_SIZE] = "";
    char szMethod[BUFFER_SIZE] = "";

    DWORD dwBuffSize = 0;

    pHeaders = (PHTTP_FILTER_PREPROC_HEADERS) pvNotification;

    // Get the method of the request
    dwBuffSize = BUFFER_SIZE-1;
    // Exit with an error status if a failure occured.
    if (!pfc->GetServerVariable(
      pfc, "HTTP_METHOD", szMethod, &dwBuffSize))
      return SF_STATUS_REQ_ERROR;

    if (strcmp(szMethod, "PROPPATCH") == 0)
    {
      // Send the HTTP status to the client.
      if (!pfc->ServerSupportFunction(
        pfc, SF_REQ_SEND_RESPONSE_HEADER,"207 Multi-Status", 0, 0))
        return SF_STATUS_REQ_ERROR;

      // Get the URL of the request.
      dwBuffSize = BUFFER_SIZE-1;
      if (!pfc->GetServerVariable(
        pfc, "URL", szRequestURL, &dwBuffSize))
        return SF_STATUS_REQ_ERROR;
        
      // Determine if request was sent over secure port.
      dwBuffSize = 2;
      if (!pfc->GetServerVariable(
        pfc, "SERVER_PORT_SECURE", szSecure, &dwBuffSize))
        return SF_STATUS_REQ_ERROR;
      fSecure = (szSecure[0] == '1');
        
      // Get the server name.
      dwBuffSize = BUFFER_SIZE-1;
      if (!pfc->GetServerVariable(
        pfc, "SERVER_NAME", szServerName, &dwBuffSize))
        return SF_STATUS_REQ_ERROR;
        
      // Set the response URL.
      hr = StringCchPrintf(
        szResponseURL,BUFFER_SIZE-1, "http%s://%s/%s",
        (fSecure ? "s" : ""), szServerName, &szRequestURL[1]);
      // Exit with an error status if a failure occurs.
      if (FAILED(hr)) return SF_STATUS_REQ_ERROR;

      // Set the response body.
      hr = StringCchPrintf(
        szResponseXML,BUFFER_SIZE-1, "%s%s%s",
        xmlpart1, szResponseURL, xmlpart2);
      // Exit with an error status if a failure occurs.
      if (FAILED(hr)) return SF_STATUS_REQ_ERROR;

      // Write the response body to the client.
      dwBuffSize = strlen(szResponseXML);
      if (!pfc->WriteClient(
        pfc, szResponseXML, &dwBuffSize, 0))
        return SF_STATUS_REQ_ERROR;

      // Flag the request as completed.
      return SF_STATUS_REQ_FINISHED;
    }
  }
    
  return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

I hope this helps. ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

A=432Hz Tuning versus A=440Hz Tuning

A coworker recently pointed me to the following blog post, and he asked if it had any basis in reality: 432Hz: Crazy Theory Or Crazy Fact. After looking at that blog, I think a better title for it would be "432Hz: Misinterpreted Theory and Misconstrued Facts." I honestly mean no disrespect to the author by my suggestion; but the blog's author clearly does not understand the theory behind what he is discussing. And because he misunderstands some basic concepts, his discussion on this subject offers little by way of practical information. As such, I thought that I would set the record straight on a few things and offer some useful information on the subject.

First of all, the author's suggestion that using A=432Hz for a reference when tuning will put your guitar in Pythagorean Tuning is completely false; all you are doing is changing the base frequency that you are using, but your guitar will still be in Standard Tuning.

Discussing the base frequency is about as effective as discussing the merits of an E-Flat Tuning versus Standard-E Tuning; either one is fine, and it just comes down to user preference as to which one is better. The same thing holds true for choosing A=432Hz over A=440Hz - it's a preference choice. (Unless you have Perfect Pitch, in which case  A=432Hz is probably going to annoy you more than words can say.)

However, there is one major difference: if you choose to record music by using an other-than-normal base frequency, you'll frustrate the heck out of someone who just tuned their guitar with a standard tuner and attempts to sit down and learn your music. ("Hmm... this just doesn't sound right.") And you could retune just to annoy them for fun, of course. ;-]

That being said, any discussion of Pythagorean Tuning and the guitar is utterly useless, because a guitar is not fretted for Pythagorean Tuning. Here is where the real confusion lies, because the author of that blog is confusing changing the base frequency with somehow putting the guitar into a different temperament, which is not possible without re-fretting your instrument. Here's what I mean by that:

The physical interval between the frets on a guitar neck is based on Equal Temperament, which is a constant that is defined as the 12th root of 2. In Microsoft Excel that formula would be 10^(LOG(2)/12), which comes to 1.0594630944. We all know that an octave is double the frequency of the base pitch, so with A=440Hz you would get A=880Hz for the next higher octave. By using the above constant, you can create the following scale from an A to an A in the next higher octave by multiplying each frequency in the scale by the constant in order to derive the resultant frequency for each successive note:

Note Frequency
A = 440.00Hz
Bb = 466.16Hz
B = 493.88Hz
C = 523.25Hz
C# = 554.37Hz
D = 587.33Hz
D# = 622.25Hz
E = 659.26Hz
F = 698.46Hz
F# = 739.99Hz
G = 783.99Hz
Ab = 830.61Hz
A = 880.00Hz

In contrast to the claims that were made by the blog's author, you do not magically get whole-number frequencies (e.g. with no decimal points) if you change the base frequency to A=432Hz; the math just doesn't support that. Here is the list of resulting frequencies for an octave if you start with a base frequency of A=432Hz, and I have included a comparison with a base frequency of A=440Hz:

Note Frequency 1 Frequency 2
A = 432.00Hz <-> 440.00Hz
Bb = 457.69Hz <-> 466.16Hz
B = 484.90Hz <-> 493.88Hz
C = 513.74Hz <-> 523.25Hz
C# = 544.29Hz <-> 554.37Hz
D = 576.65Hz <-> 587.33Hz
D# = 610.94Hz <-> 622.25Hz
E = 647.27Hz <-> 659.26Hz
F = 685.76Hz <-> 698.46Hz
F# = 726.53Hz <-> 739.99Hz
G = 769.74Hz <-> 783.99Hz
Ab = 815.51Hz <-> 830.61Hz
A = 864.00Hz <-> 880.00Hz

When you look at the two sets of frequencies side-by-side, you see that tuning with either base frequency yields only two even frequencies - one for each of the A notes. However, when you use the standard A=440Hz tuning, you have two frequencies (the F# and G) that almost fall on even frequencies (at 739.99Hz and 783.99Hz respectively). Not that this really matters - your ear is not going to care whether a frequency falls on an even number. (Although it might look nice on paper if you have Obsessive Compulsive Disorder and you rounded every frequency to the nearest whole number.)

Since the frets on the guitar are based on this temperament, that's all you get - period. You can fudge your base frequency up or down all you want, but in the end you're still going to be using Equal Temperament, unless you completely re-fret your guitar as I already mentioned. (Note: See the FreeNotes website for guitar necks that are fretted for alternate temperaments.)

If you had a background that included synthesizers, (and as a guitar player I must apologize for my side hobby on keyboards), you might remember that back in the 1980s there was a passing phase with microtonality on keyboards. If you had a keyboard that supported this technology, you were able to play your keyboard by using intonation that was different than the Equal Temperament, which was sometimes pretty cool.

Why would someone want to do this? Because many of the old composers never used Equal Temperament; that's a fairly recent invention. So if you want to hear what a piece of piano music sounded like for the original composer, you might want to set up your keyboard to use the same microtonality temperament that the composer actually used.

But that being said, before the invention of Equal Temperament, there were several competing temperaments, and each was usually based on tuning some interval like the fourth or fifth by ear, and then finding intervals in-between those other intervals that sounded acceptable. What this resulted in, however, were a plethora of tunings/temperaments that sounded great in some keys and terrible in others. More than that, if you continue to work your way up a scale based on intervals based on sound, you will eventually introduce errors. Using the actual Pythagorean Tuning suffers from this problem, so if you put a microtonal keyboard into Pythagorean Tuning and attempted to play a piece of music that extended past a couple of octaves, it sounded terrible. (See Pythagorean Tuning for an explanation.)

But on that note, almost every guitarist suffers from this same problem, but you just don't know it. Have you ever tuned your guitar by using the 5th fret and 7th frets harmonics? Of course you have, and so have I. But here's a side point that most guitarists don't know - when you tune your guitar by using those harmonics, you slowly introduce errors across the guitar, and as a result it will seldom seem completely in tune with itself.

Here's an excerpt from a write-up that I did for the Christian Guitar website a while ago that describes what I mean:

There have been many different temperaments used in the Western Hemisphere, and many of these centered around specific intervals. For example, start with a C note, then find the perfect octave above; you now have the starting and ending points for your scale. Next, find the harmonically perfect 5th of G by tuning and listening to pitches, then use these intervals to find E, which is the major 3rd. Once done, you now have three notes of your scale and the octave. If you jump up to G and use the same process to find the 3rd and 5th, you get the B and D notes. If you keep repeating the process, you eventually derive all of the diatonic notes for your major scale. On a piano that would be just the white keys.

Leaving sharps and flats out of this example, (the piano's black keys), the problem is that if you keep using the perfect 5th for a reference, you gradually find that the notes in your scale are not lining up as you travel around the circle of 5ths. This occurs because using perfect 5ths will eventually introduce slight errors on other intervals, and the result will be that your scale works great in one or two keys, but other keys sound noticeably awful.

Here's why this happens: after having gone around the entire circle using perfect 5ths as a tuning guide, by the time you get to the octave above your starting note, the physical frequency for the octave is not the same as the last pitch that you derived from tuning based on the perfect 5ths. This is especially problematic when you use one particular note/key to tune an instrument, and then try to play in another key. For example, if you tune an instrument using perfect 5ths and start on a C note, the key of C# will sound distinctively out-of-tune.

The only trouble that some people might have with equal-temperament is that the intervals within the octave are not based on perfect intervals, but rather intervals based on the constant. This causes a lot of problems with people who tune by ear using perfect 5ths, which many guitarists do without realizing when they tune their guitars using harmonics over the 7th fret.

For example, if you were to tune an E note using an A note as a reference point, your ear would want to hear the perfect 5th for E which is 660.00Hz, not the equal-tempered E that is 659.26Hz. Although the difference is very small, it is compounded over time as you tune the other notes within the scale. If you continued to tune using 5ths, your next note higher would be the B that is a 5th over E. Your ear would want to hear the perfect 5th again, so you would wind up with 990.00Hz for B instead of the equal-tempered 987.77Hz. Another perfect 5th would be 1485Hz instead of the equal-tempered 1479.98Hz, then 2227.50Hz instead of 2217.46Hz, etc.

I personally find the math part of music fascinating, and I've obviously spent a bunch of time (perhaps too much time  ;-]) studying notes, scales and tunings from a mathematical perspective. Because of that, I view the whole guitar neck as a numerical system and all chords/scales as algorithms. I know that's really geeky, but it's still pretty cool. In the end, I think that math might be my 2nd-favorite part of music. (My favorite part is turning the amps up to 11 and feeling the actual notes as they tangibly pass through my body - it's like a physical feedback loop. Very cool...)

The net result of this discussion is - use a tuner when you are tuning your guitar, not your ear. And it doesn't matter what your base frequency is when you are tuning your guitar - you are still using Equal Temperament because that's the way that your guitar is made. ;-]