Cloud computing types, perspectives, and disadvantages

Around the beginning of the 20th century, factories used to be placed near river sources in order to get controlled access to electricity. Now electricity is not a differentiation factor among factories anymore, so they simply outsource this service to specialized electrical companies. I think the same will occur with computing sooner or later. In a previous post, I explored the context in which cloud computing was born, and why it is an effective way to reduce computing costs by turning fixed costs into variable costs. This is one of its principal attractiveness, but it’s not the only one. Other advantages can be discovered by considering cloud computing from many different viewpoints:

  • Cloud computing as a use model, where we are interested in computing results and not in how we implement them.
  • Cloud computing as an access model, where we can access an application from everywhere.
  • Cloud computing as an infrastructure model, where capacity is not reserved upfront, and it changes elastically.


We therefore cannot talk about a unique cloud computing model anymore. Multiple models make up the cloud and they are actually independent problems, each with its own research efforts, difficulties, and implementations. There are also different types or deployment models: There are public clouds (also known as external clouds), in which users access the cloud via interfaces using web browsers. Resources are provisioned on a fine-grained basis, which clearly consists a form of utility computing. Private clouds are set up inside an organization’s internal data center. They provide more control over deployment and use than public clouds, in a similar way than Intranet functionality. Amid the two previous approaches, hybrid clouds are private clouds linked to one or more external cloud services. They provide more secure control of data and allow various parties to access information over the Internet. They also have open architectures to be able to integrate themselves in larger, external management systems.

From these different models we can elaborate a list of aspects that every company should assess before adopting a cloud computing solution. In the following list I summarize some that I consider most relevant:

  • Cloud providers are responsible for security management using (hopefully) a specialized team that applies state-of-the-art technologies.
  • The coherence problem derived from data synchronization is now responsibility of the provider.
  • Licenses are “pay-per-use”, instead of a high initial fixed cost.
  • Systems are automatically upgraded by the cloud provider.
  • Collaborative work is easier (Google Docs and similar products are a great example of this).
  • Lightweight clients can access the cloud from anywhere there is an Internet connection.
  • Energetic costs are minimized.


In my opinion, Cloud computing help differentiate companies by reducing time in those tasks that are not principal in their business and, at the same time, enables new delivery methods that help increase competitiveness. However, cloud computing is not a universal solution to every computing need. Some problems, scenarios and applications are not appropriate for a cloud environment, and there is also a risk of downtime, so the recommendation is that businesses should migrate their less critical services first. Businesses must conduct a rigorous analysis before looking into a migration to the cloud, and this analysis must not overlook some weak points:

  • There is not full control over the service’s internal management.
  • There is a high dependency on an Internet connection.
  • There is an inherent migration risk if the cloud provider goes out of business. Which tools and procedures are available to export our data from the cloud provider? This phenomenon is technically called the “lock-in problem”.
  • There is some uncertainty about the performance of computations in the cloud. Bottlenecks can occur in data-centric applications.


I left out two of the most important aspects of cloud computing, or at least they are the main causes of concern to users and companies around the world, according to many surveys: security and privacy. They are tangled concepts that have deserved great attention from the research community, and I will try to explain them in a future post.

Yes, you can set a drop default action “per file type”, too

What happens when you drag&drop a file in Windows Explorer? Will it result in a copy? Maybe a move? Will the file be engulfed by a black hole and you lose all your work? The exact answer is that it depends. In this blog post, I’d try to summarize the most common situations. Basically:
  • If the source is the root of a local or remote drive, or it is a registered application on the system, the default action is a shortcut.
  • If the source and destination folders are on the same volume (i.e., they have a common root component), the default action is a move.
  • Otherwise, the default action is a copy.

But there are some exceptions. One that I know of is the temporary DVD burn folder, where the default “drop effect” (shell terminology) is a copy even if the source and target are on the same volume. This particular behavior just makes sense for the staging area. Additionally, you can set a default drop effect by adding the DefaultDropEffect parameter to the Desktop.ini file of the target folder, as it’s explained here: http://hwiegman.home.xs4all.nl/desktopini.html.

You can also override the default drop effect by using the keyboard. If you hold the Control key while dragging the object, the result is a copy; if you hold Shift, the result is a move; and if you hold both Control and Shift (or the Alt key), the result is a shortcut.

And finally, a feature that few people know and something you can tell at a geek party: The shell allows to set default drop effects based on the file that is being dragged. Add a new DWORD value named DefaultDropEffect to the HKEY_CLASSES_ROOT\ProgID registry key (where “ProgID” is the program identifier associated with the file type you’re dragging, for example HKEY_CLASSES_ROOT\Windows.IsoFile) and that’s it. The range of valid values is documented here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms693457(v=vs.85).aspx

How do you set a REG_MULTI_SZ value in native code?

One question that arrived to my e-mail asked about how to set a REG_MULTI_SZ value in the Windows registry programmatically using native code. Most people have no problems setting other value types such as REG_SZ or REG_DWORD, but REG_MULTI_SZ might be a bit special on its own so I decided to sketch some code and write a quick blog post before I gear up for El Clásico:

The tricky part about REG_MULTI_SZ is that it is terminated by two null characters (‘’). If you don’t forget this, then everything will work as it should. You can assume that every REG_MULTI_SZ value has a zero-length string as the last element in the array of strings (to avoid ambiguity, zero-length strings are excluded from the potential strings you can put in a REG_MULTI_SZ value).

Here’s some example code:

#include <Windows.h>

static LPTSTR szFirstString = L"This is the first value";
static LPTSTR szSecondString = L"And this is the second";
static LPBYTE pString;

// Main entry point
int main()
{
    HKEY hKey;
    if (SUCCEEDED(RegCreateKeyEx(HKEY_CURRENT_USER,
                                 L"Test",
                                 0,
                                 NULL,
                                 REG_OPTION_NON_VOLATILE,
                                 KEY_ALL_ACCESS,
                                 NULL,
                                 &hKey,
                                 NULL)))
    {
        size_t totalSizeInBytes        = (wcslen(szFirstString) + wcslen(szSecondString) + 3) * sizeof(wchar_t);
        size_t firstStringSizeInBytes  = (wcslen(szFirstString) + 1) * sizeof(wchar_t);
        size_t secondStringSizeInBytes = (wcslen(szSecondString) + 1) * sizeof(wchar_t);

        pString = static_cast<LPBYTE>(malloc(totalSizeInBytes));
        
        if (pString)
        {
            memcpy(pString, szFirstString, firstStringSizeInBytes);
            memcpy(pString + firstStringSizeInBytes, szSecondString, secondStringSizeInBytes);
        
            pString[firstStringSizeInBytes + secondStringSizeInBytes] = 0;
            pString[firstStringSizeInBytes + secondStringSizeInBytes + 1] = 0;

            RegSetValueEx(hKey, 
                          L"TestValue", 
                          0, 
                          REG_MULTI_SZ, 
                          pString, 
                          totalSizeInBytes);

            RegCloseKey(hKey);
            delete pString;
        
            return 0;
        }
    }
    
    return -1;
}


In the first lines below the #include directive I declared two null-terminated strings and a byte buffer that I will use to feed the registry value. In the main method I created a new “Test” subkey and then defined some convenient sizes in bytes (buffer size, first string size, and second string size). Note that the length of a wide character string is wcslen(string) + 1 to account for the null character1. In totalSizeInBytes I added 3 to account for the null character of each string and the null character of the resulting string itself. Then I put aside some memory space for the pString buffer and glued together both strings, one after the other, using the memcpy function.



The next lines are very important. You need to end the string buffer with an additional null character to mark the end of the sequence of strings. This will be the final representation of our buffer:



This is the first valueAnd this is the second



The last thing is to pass this buffer to RegSetValueEx and wait for the configuration manager to flush the information to the registry.



1 If you happen to pass wcslen(string) as the length of a wide character string to RegSetValueEx, Windows will add transparently a terminating null because the error is so common that the Windows team had to add a compatibility hack. But as a spell checker is not a replacement for correct writing, don’t rely on this patch and always account for the terminating null character when you work with strings.

A brief introduction to grid, virtualization, and cloud computing

“Cloud” is one of the latest buzzwords in the media today. People in technology circles often associate the cloud with Dropbox, Facebook or Windows Azure, but in fact the cloud is a broader concept. What’s exactly cloud computing?

A little bit of context

We have to introduce the context in which cloud computing was born: parallel and distributed computing. We can say that the parallel and distributed computing aim is to run intensive data or calculation applications in an efficient way. There are two main paradigms in parallel and distributed computing:

  • High performance computing, or HPC
  • High throughput computing, or HTC

In HPC we are interested in running one parallel application as fast as possible. Thus, this paradigm is useful in domains where time is constrained. For example, in computational fluid dynamics engineers simulate how an airplane wing behaves in a wind tunnel using complex algorithms. Here it is obvious that we need to reduce the computational time as much as we can. Another typical example is a weather forecast. It is also a CPU-intensive activity that computers need to finish in timely fashion (i.e. it’s not acceptable to complete a weather forecast for the next week in two weeks). In HTC we are interested in completing as many jobs per second as possible. For example, financial models and bioinformatics are two fields were HTC is commonly used.

Now that we have presented the two paradigms, let’s see the type of platforms that can be found in each. In HPC there are two important platforms: Symmetric Multi-Processors, or SMP, and Massive Parallel Processors, or MPP. In HTC, clusters and network systems are the rule. You can see clearly that there is a shift from the centralized, easy to administrate, homogeneous, tightly-coupled platforms in HPC to the more heterogeneous and not-so-easy to administrate platforms in HTC. This motivates the addition of a layer of abstraction that offers a uniform view of a system and simplifies administration. This layer is what computer scientists call a local resource management system, or LRMS. One of the most popular open source LRMS is Oracle Grid Engine. Local resource management systems are not exempt of disadvantages, though. The most important is that they lack a common interface and security infrastructure, which makes it difficult to construct computational architectures that span multiple administration domains.

Many, if not all computer science problems can be solved by adding a new layer of indirection. And that’s what is actually done to integrate different domain administrations: we add a computational grid as middleware layer above LRMS. A computational grid is chiefly a system that complies with the following requirements formulated by Ian Foster in 2002:

  • Coordinates decentralized resources.
  • Uses open protocols and standards.
  • Provides non-trivial quality of service.

Examples of middleware grids are The Globus Alliance, Unicore, or GRIA.

Servers, virtualization, and the cloud

Classic servers are static, pre-configured environments that run a particular instance of an operating system. Therefore, there’s a close relationship between server and resources (be it an operating system or a hardware configuration). This involves a high cost destined to fault tolerance monitoring and hardware maintenance, a high cost in downtime during hardware upgrades, etc. The alternative is virtualization, which decouples servers and physical resources, that is, many virtual machines can be executing on top of the same resource, even simultaneously.

Cloud computing can be understood as a paradigm to deliver on-demand hardware resources by means of virtualization. The assumption is that, in many scenarios, hardware resources are not used to the full for a long time, so it’s more efficient to consume computing power like cable TV or electricity. More precisely, we can observe cloud computing from multiple angles: Infrastructure as a Service (IaaS), which delivers a raw computer infrastructure, like Amazon web services, Platform as a Service (PaaS), which is a platform for the developing and delivering of web applications, like Windows Azure, and Software as a Service (SaaS), which provides on-demand access to any application, like Skype or Gmail.

At the simplest level, every cloud architecture has two principal components that we will see in greater detail in future posts:

  • A front-end, which is basically a remote interface, like Globus Nimbus.
  • A back-end, which behaves as a local manager, like OpenNebula.

In this article my intention was to summarize a high-level vision of what cloud computing is and where it comes from. Many people are still unwilling to adopt this incipient paradigm just like some people were reluctant to use cars at the beginning of the 20th century. In my opinion, when a new technology arises people usually try to adapt it to what is used right now, instead of trying to discover potential new use cases and functionality. In a nutshell, virtualization, cloud, and grid are complementary technologies that will coexist and cooperate at different levels of abstraction. One attractive of virtualization and cloud to end users is that they don’t have to change anything from their point of view. In the next posts I will explore in more detail the cloud concept and some relevant issues that are not solved yet, like providing a security model for the cloud.

How to display the “Open With” dialog box with the “Always associate this program” checkbox unchecked by default – Part III

In the first part of this article series I proposed a small program in the form of a “RunDll32-callable” DLL that executes the Open With dialog with the “Always associate this program” checkbox unchecked for the sake of running a file with a particular program without the risk of a permanent association. In that blog post I left as a question if we can do better, because the method I presented doesn’t work when the file is not already associated with a particular program. In this post I’m going to describe a somewhat “hacky” procedure that works with unknown file extensions also. First of all, we have to dig into the theory and explain why the “standard” use of the API does not completely fulfill our requirements.

When you invoke the “Open With” dialog by calling the SHOpenWithDialog API, what you are really invoking is one of a few different dialog box templates; the template that gets invoked is decided internally by Windows depending on a few factors. The main of those factors is if the file you are trying to open has a known or unknown file type. Indeed, you can see that the “Open With” dialog box is aesthetically a bit different if you’re dealing with a known file type than if you’re dealing with an unknown file type:

UnknownFileTypeKnownFileType

You can see that the difference (marked in a red rectangle) that tell us that they are different dialog boxes is the description text field in the dialog box on the left. By design, this dialog box also places a mark next to the “Always use the selected program” checkbox even if we don’t set the OAIF_FORCE_REGISTRATION flag in the OPENASINFO structure.

Windows considers that a file extension is “known” when there is a class key in the registry associated with that extension. In plain words, there must be a HKEY_CLASSES_ROOT\.ext registry key, with its (Default) value pointing to ExtProgID, where ExtProgID is the program identifier for that file extension (HKEY_CLASSES_ROOT\ExtProgID). For the interested reader, there’s much more information about file associations and program identifiers in this MSDN article: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144104(v=vs.85).aspx. Therefore, if we could “mislead” the system and make it think that an unknown file type is known, at least momentarily, we might get our desired result. Of course, we should be neat and clear our tracks afterwards, to leave the system in the same situation as it was before.

MSDN describes an interface for file association queries: IQueryAssociations. We’re going to consume this interface in order to ask the operating system whether the file type we’ve right clicked is known or not. Here is a possible code snippet to accomplish the task:

IQueryAssociations* pqa;
DWORD cch;
BOOL bUnknownType = TRUE;

if (SUCCEEDED(AssocCreate(CLSID_QueryAssociations, IID_PPV_ARGS(&pqa))))
{
    if (SUCCEEDED(pqa->Init(ASSOCF_INIT_DEFAULTTOSTAR, pszFileExt, NULL, NULL)) && 
        FAILED(pqa->GetString(ASSOCF_IGNOREBASECLASS, ASSOCSTR_COMMAND, L"openas", NULL, &cch)))
    {
        if (SUCCEEDED(pqa->GetKey(ASSOCF_IGNOREBASECLASS, ASSOCKEY_CLASS, NULL, &hKey)))
        {
	    bUnknownType = FALSE;
            RegCloseKey(hKey);
        }
    }
}


The semantics are pretty straightforward. First, we set up a pointer to IQueryAssocations interface and then we use the GetKey method to get the registry key associated with the file extension. The FAILED(pqa->GetString(ASSOCF_IGNOREBASECLASS, ASSOCSTR_COMMAND, L"openas", NULL, &cch) line is not totally obvious. It avoids that a file extension that has one or several applications in its “open with” section is considered a known file extension. If you omit this test, some extensions would be considered known extensions even though they have not a default program associated to them; that’s not what we want.



Once we have determined that the file extension is unknown, we have to “deceive" the system a bit before calling SHOpenWithDialog as we did in the first version of the DLL. The goal is to make Windows think that the file extension is known so let’s create a HKEY_CURRENT_USER\Software\Classes\.ext and HKEY_CURRENT_USER\Software\Classes\Test registry keys and set the (Default) value of the former to “Test”. In code:



HKEY hKey, hAssocKey, hProgIDKey;
PCWSTR pszFileExt = PathFindExtension(lpszCmdLine);
LPWSTR lpszClassesSubkey = TEXT("Software\\Classes\\");
WCHAR szClassesExtKey[256] = {0};
WCHAR szClassesProgIDKey[256] = {0};

StringCchCopy(szClassesExtKey, ARRAYSIZE(szClassesExtKey), lpszClassesSubkey);
StringCchCopy(szClassesProgIDKey, ARRAYSIZE(szClassesProgIDKey), lpszClassesSubkey);
StringCchCat(szClassesExtKey, ARRAYSIZE(szClassesExtKey), pszFileExt);
RegCreateKeyEx(HKEY_CURRENT_USER, szClassesExtKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hAssocKey, NULL);
RegSetValueEx(hAssocKey, NULL, 0, REG_SZ, (BYTE*)TEXT("Test"), (4 + 1) * sizeof(TCHAR)); // Set the "(Default)" value
StringCchCat(szClassesProgIDKey, ARRAYSIZE(szClassesProgIDKey), TEXT("Test"));
RegCreateKeyEx(HKEY_CURRENT_USER, szClassesProgIDKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hProgIDKey, NULL);
RegCloseKey(hAssocKey);
RegCloseKey(hProgIDKey);


For demonstration purposes, I omitted all error handling in this snippet. Another improvement could be to create a uniquely named registry key, and not simply “Test”, in order to avoid name clashes. This is left as an exercise to the reader. Now it’s time to call SHOpenWithDialog and, much to our surprise, the checkbox remains unchecked, just as we want. There are no conflicts if we decide to make a permanent association, because associations created by users are registered in a different key, HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ext\UserChoice, and our registry key is deleted after we close the Open With dialog box.



This second version of the DLL is available at my website: http://www.wintecnico.com/Ficheros/MyOpenAs_v2.zip. Of course, as it was the case with the previous version, the DLL is provided “as is”.



To sum up, I’ve described the aspects of the Open With dialog that were relevant to build a solution to our problem. We started using nothing more than the public API (a not so popular public API, though). After that, we used a debugger to demonstrate that some tricks published on the Internet have no scientific basis, and finally we suggested another solution that works with unknown file types too. The downside is that it is “hackier” than the first one and not something that you would implement in a production enviroment, but it may help you if you’re bothered by this design limitation in Windows.

How to display the “Open With” dialog box with the “Always associate this program” checkbox unchecked by default – Part II

In the previous post I explored a method to clear the checkbox near “Always use the selected program to open this kind of file” in the Open With dialog in Windows Vista and Windows 7. In that post I wanted to share that registry hacks should not be the first step to try when you need a change in the appearance and/or behavior of the operating system. Sure, registry hacks are cool and geeky, but they present two important problems: First of all, they are not documented, usually because they are intended for internal use only. Therefore, we never know for sure if we are using them correctly. Also, undocumented registry entries are subject to change in future versions of Windows, so there’s a good chance that the implementation that worked on the “n” version of Windows will cease to work on the “n+1” version.

In this post I will analyze a registry hack and categorize it in the first pattern I present in this blog: “The behavior resulting from unknowingly using an interface outside of its normal range of inputs gives an apparent solution to the problem, but only because you were lucky.”

In particular, the registry hack described in this page, as we will see, relies on not very well-known behavior of a public API when it is invoked with a special kind of parameter. Let’s first understand what happens when you add the “%2” parameter to the command string, and then prove our theory using a debugger attached to a live system:

The (Default) registry value in the HKEY_CLASSES_ROOT\Unknown\shell\opendlg\command key contains the following command string:

%SystemRoot%\system32\rundll32.exe %SystemRoot%\system32\shell32.dll,OpenAs_RunDLL %1

The %1 is the placeholder for a variable passed as a parameter to the function. It was (and still is) commonly used in batch scripts, back in the DOS days. When you right click any item in the shell namespace to display its context menu, its path goes along with the request so verbs can use placeholders when they describe their actions. In case we need to pass more than one parameter, we can increment the integer (%2, %3, and so on).

What happens when we add a %2 to the end of the command line? Well, it doesn’t match with any parameter, so a blank character is appended to end of the string. We can use Windbg, a user and kernel mode debugger from the Debugging Tools for Windows, to show that. Open Windbg and attach it to Explorer.exe. As RunDLL32.exe will be a child process of Explorer.exe at runtime, we must configure the debugger to attach to child processes, using the .childdbg command like in the following picture:

Childdbg

Now we can let Explorer run under the debugger, while we invoke the Open With dialog with a test file, and wait until the debugger stops.

Rundll32Load

We see that Explorer wants to give birth to a new RunDLL32.exe process and that means that we are now ready to set a breakpoint in the OpenAs_RunDLL function in Shell32.dll. Note that because Rundll32.exe loads Shell32.dll dynamically at runtime (you can check this using the list modules –lm- command), we need to set an special type of breakpoint, a deferred (or unresolved) breakpoint:

bu shell32!OpenAs_RunDLLW

If we continue our debugging session until the debugger stops, and then display the third parameter passed to OpenAs_RunDLLW as Unicode string, we get the following result:

BlankSpacePath

There’s a blank space at the end of this null-terminated path, just like we supposed previously. That’s suspicious. Maybe this is what is causing the user interface to gray out the checkbox as a side effect? But why? Let’s set a breakpoint on access to that virtual memory address to see functions that read or write it. We get an interesting result:

PathFindExtension

As we see, the string is passed to the public PathFindExtension API. The reason probably is that the Open With dialog might need to block pointless “open with” requests on executable files or “extensionless” files. If we examine the return value, again interpreted as a Unicode string (du 0025404c), we see a terminating null character as the above picture depicts.

So now we know the reason why the registry tweak “works”. PathFindExtension is returning a terminating null character when we pass a file path with a blank space appended to the end. Therefore, the Open With dialog thinks that the file has no extension and consequently disables the “Always use this program to open this file” checkbox.

One last question remains, why does PathFindExtension returns a null terminating character? The answer is in the Remarks section of the MSDN documentation of that API: File extensions cannot have spaces. If a space is found when parsing the string, the path is interpreted to be a directory and a null terminating character is returned.

Case closed. I don’t know whether the author of the registry tweak did know the reason why it works, or it is simply a matter of luck; in either case, as we saw in the previous blog post, we can do better using only documented interfaces and not passing weird strings to functions. In the next post I will discuss if we can do even better and devise a valid solution for unknown extensions also.

How to display the “Open With” dialog box with the “Always associate this program” checkbox unchecked by default

One of the most common user interface problems in Windows occurs when the user unintentionally associates a file extension with the wrong application. This was not particularly problematic in Windows XP, because you had the option to revert everything using the File Types dialog, but since Windows Vista and Windows 7 don’t come with that dialog or a replacement (possibly because rewriting it to be UAC-compatible was not deem the effort for Microsoft), end users are forced to solve the problem by editing the Registry. And, you know, when I give users Registry instructions or a script to solve a problem like this, I feel Microsoft has failed and there’s room for improvement.

My fellow MVP, Ramesh Srinivasan, developed a fantastic tool to unassociate file extensions in Windows Vista and Windows 7, you can download it from here: http://www.winhelponline.com/articles/231/1/An-Utility-to-Unassociate-File-Types-in-Windows-7-and-Vista.html. At least we have a simple UI replacement for one of the most used features of the old File Types dialog.

But what if we want to prevent the problem from happening? I went to one of the best sources for usability studies, the Windows forums and newsgroups. Some people discussed that if the “Always use the selected program to open this kind of file” checkbox were unchecked by default, it would help decrease the number of cases where users want to open a file with a different program, only once, but they end up with a permanent association that they don’t know how to undo.

Exploring possible implementations

Now that we’ve determined a way to prevent the problem, we need to implement it. I searched the Internet and the articles I found didn’t convince me. All of them of them either disable or remove the checkbox (so you can’t register an association even if you want to). For example, the tweak explained in this page is more a side effect caused by passing wrong arguments to a DLL function than a valid solution.

In my search, I discovered that Windows Vista introduced a new API that looked promising: SHOpenWithDialog. The second parameter of this function is a pointer to a constant structure, OPENASINFO, that specifies the filename, description, and some flags that control the characteristics of the dialog box. The flag OAIF_FORCE_REGISTRATION, per the MSDN documentation, forces the “Always use this program” checkbox to be checked. After reading carefully the semantics of the other flags I determined that I needed to combine the OAIF_ALLOW_REGISTRATION, OAIF_REGISTER_EXT and OAIF_EXEC flags:
OPENASINFO oainfo = {0};
LPWSTR  lpwszCmdLine; // This will be a function parameter
HWND hWnd; // This will be a function parameter
oainfo.pcszFile = lpwszCmdLine;
oainfo.oaifInFlags = (OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT | OAIF_EXEC);
SHOpenWithDialog(hwnd, &oainfo);

And that’s it, we have almost finished our very simple program, but we still need to know how to pass in the file path and the window handle. That’s not hard if we do some inspection on the “(Default)” value of the registry key HKEY_CLASSES_ROOT\Unknown\shell\opendlg\command. In general, inspection is a valuable skill to detect patterns in existing designs, and to avoid engineering things from scratch. When you invoke the “open with” action, Windows calls %SystemRoot%\system32\rundll32.exe %SystemRoot%\system32\shell32.dll,OpenAs_RunDLL %1, i.e., it calls a function in Shell32.dll by using the Rundll32.exe executable. To be callable from Rundll32.exe, functions must conform to a particular signature. This is it for Unicode:
void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow);

So the final result is:
void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
OPENASINFO oainfo = {0};
oainfo.pcszFile = lpszCmdLine;
oainfo.oaifInFlags = (OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT | OAIF_EXEC);
SHOpenWithDialog(hwnd, &oainfo);
}

This is basically all the code we need. Compile it and create a DLL or download the DLL from my server: http://www.wintecnico.com/Ficheros/MyOpenAs.zip. One question you may ask: “Can we do better? Why it doesn’t work with unknown file types?” This question and some in-depth analysis and debunking of some of the tricks that you may find  on the Internet will be the topic of the next article.

We need to explore new ways to teach Mathematics to high school students

It’s not a secret that a popular software company offer their employees a percentage of time to contribute to the project of their wish. I think most people when they are asked the question “how would you spend that time?” would answer: “I’d contribute to this X new project,” “I’d add this Y feature to this Z project”…

They are all very good options that will impact millions of people around the world. But what if we want to impact the future generations of consumers, or even more, the future of computing? I would use that time to improve education. Recent studies report that nowadays not many people are choosing Computer Science as a major, especially in the U.S. This is a serious problem that caught the attention of many well-known people, like Bill Gates. Indeed, if we want to progress in this digital era, we need qualified and creative engineers that are prepared to invent and develop the “next big thing”. How could we generate more interest around Computer Science and, consequently, increase competitiveness? By changing the way Mathematics and, in general, exact sciences are taught in high school.

I don’t know about each country and school in the world, but Mathematics in high school tends to be a subject about calculating things: One of the most prominent goals is that you are able to solve things like a complicated integral without the slightest error. You don’t even need to know what an integral is, and why integrals are important. Of course, calculating is also important and cannot be ignored, but now computers can do this kind of computations in less time, and without a single mistake. Moreover, computers are now able to solve the trickiest differential equations, but this cannot avoid the fact that we don’t know how to model some important “real world” problems in the form of differential equations.

That’s the point I’d like to make. We need to focus the teaching of Mathematics around problem-solving skills. Once we’ve modeled a problem, then use a computer or cloud computing service to get the exact answer. Problem-solving skills are not only essential for engineers, they are useful for professionals in general in their everyday activities. Consequently, I believe that with this change of mentality Engineering would appeal more to students, there would be less drop-outs after the first year, and there would be more opportunities to success in this field.

What do you think? Do you also think that the method of teaching Mathematics at pre-university level is becoming obsolete? How would you foster creativity and innovation to keep up with the world as it is now?

Welcome to my blog!

Hello, all. My name is Daniel, I’m a Microsoft MVP in the Windows category and in this blog I’ll be writing about the technical things that interest me most: Windows user experience topics, trivia about the Windows API, how to troubleshoot difficult problems, and other computer science topics that I consider relevant for the future (image processing, computer vision, artificial intelligence…).

I hope you enjoy this blog, and excuse me if I make some English mistakes, because English is not my mother tongue.