Diff of /ooDialog/trunk/ooDialog/oodMain.cpp [r9359] .. [r9360] Maximize Restore

  Switch to side-by-side view

--- a/ooDialog/trunk/ooDialog/oodMain.cpp
+++ b/ooDialog/trunk/ooDialog/oodMain.cpp
@@ -58,6 +58,8 @@
 #include <oorexxapi.h>
 #include <stdio.h>
 #include <shellapi.h>
+#include <shlwapi.h>
+#include <tchar.h>
 #include "oodShared.hpp"
 #include "oodExecutable.hpp"
 
@@ -116,6 +118,26 @@
 }
 
 /**
+ * Simple function to check for the 'test' flag.  The test flag is used for
+ * internal purposes and not documented.  We use it to run tests that work
+ * better printing directly to the console.
+ *
+ * @param argc
+ * @param argv
+ *
+ * @return bool
+ */
+static bool isTestRequest(int argc, char **argv)
+{
+    if ( argc > 1 && argv[1][0] == '-' && argv[1][1] == 't' )
+    {
+        return true;
+    }
+    return false;
+}
+
+
+/**
  * Simple function to check for the version options, -v and --version.  If found
  * we use printf the version string specified.
  *
@@ -160,12 +182,224 @@
     return false;
 }
 
+void qualifyExtensionInfo(char *keyName, pExtensionInfo rec, char *progID)
+{
+    char     value[MAX_HKEY_VALUE] = {'\0'};
+    uint32_t maxValue              = MAX_HKEY_VALUE;
+    HKEY     hKey, hSubkey;
+
+    // See if keyName is a subkey for current user
+    if( RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Classes", 0, KEY_READ, &hKey) == ERROR_SUCCESS )
+    {
+        if ( RegOpenKeyEx(hKey, keyName, 0, KEY_QUERY_VALUE, &hSubkey) == ERROR_SUCCESS )
+        {
+            if ( RegQueryValueEx(hSubkey, "", NULL, NULL, (LPBYTE)value, (LPDWORD)&maxValue) == ERROR_SUCCESS )
+            {
+                if ( StrCmpI(value, progID) == 0 )
+                {
+                    rec->curUser = true;
+                }
+                else
+                {
+                    rec->curUserOther = true;
+                }
+            }
+
+            RegCloseKey(hSubkey);
+        }
+        RegCloseKey(hKey);
+    }
+
+    // See if keyName is a subkey for local machine classes
+    if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes", 0, KEY_READ, &hKey) == ERROR_SUCCESS )
+    {
+        if ( RegOpenKeyEx(hKey, keyName, 0, KEY_QUERY_VALUE, &hSubkey) == ERROR_SUCCESS )
+        {
+            value[0] = '\0';
+            maxValue = MAX_HKEY_VALUE;
+
+            if ( RegQueryValueEx(hSubkey, "", NULL, NULL, (LPBYTE)value, (LPDWORD)&maxValue) == ERROR_SUCCESS )
+            {
+                if ( StrCmpI(value, progID) == 0 )
+                {
+                    rec->allUsers = true;
+                }
+                else
+                {
+                    rec->allUsersOther = true;
+                }
+            }
+            RegCloseKey(hSubkey);
+        }
+        RegCloseKey(hKey);
+    }
+
+    char *prefix = "   ";
+    if ( rec->allUsers )
+    {
+        if ( rec->curUser )
+        {
+            prefix = "** ";
+        }
+        else if ( rec->curUserOther )
+        {
+            prefix = "*+ ";
+        }
+        else
+        {
+            prefix = "*  ";
+        }
+    }
+    else if ( rec->curUser )
+    {
+        if ( rec->allUsersOther )
+        {
+            prefix = "+* ";
+        }
+        else
+        {
+            prefix = " * ";
+        }
+    }
+    else
+    {
+        // This can not happen can it?
+        printf("ERROR extension=%s in neither All Users NOR Current Users\n");
+        prefix = "ERR ";
+    }
+
+    _snprintf(rec->displayName, MAX_EXT_DISPLAY, "%s%s", prefix, keyName);
+}
+
+pExtensionInfo getExtensionRecords(char *progID, size_t *count)
+{
+    uint32_t cSubKeys = 0;
+    HKEY     hKCR     = HKEY_CLASSES_ROOT;
+
+    // We only need the number of subkeys.
+    uint32_t retCode = RegQueryInfoKey(HKEY_CLASSES_ROOT, NULL, NULL, NULL, (LPDWORD)&cSubKeys,
+                                       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+    uint32_t maxName;                  // Size of name buffer
+    char     keyName[MAX_HKEY_NAME];   // Buffer for subkey name
+
+    uint32_t maxValue = MAX_HKEY_VALUE; // Size of value buffer
+    char     value[MAX_HKEY_VALUE];     // Buffer for default value for subkey
+
+    // Enumerate the subkeys, and see if the prog ID matches our ooDialog prog
+    // ID.  We go through the loop twice, once to count the number of matches so
+    // we can allocate the array of extension records.  Then a second time to
+    // actually fill in the records.
+
+    pExtensionInfo recs    = NULL;
+    size_t         matches = 0;
+
+    for ( uint32_t i = 0; i < cSubKeys; i++ )
+    {
+        maxName = MAX_HKEY_NAME;
+        retCode = RegEnumKeyEx(hKCR, i, keyName, (LPDWORD)&maxName, NULL, NULL, NULL, NULL);
+        if (retCode == ERROR_SUCCESS)
+        {
+            if ( *keyName == '.' )
+            {
+                HKEY hExtKey;
+
+                retCode = RegOpenKeyEx(hKCR, keyName, 0, KEY_QUERY_VALUE, &hExtKey);
+                if ( retCode == ERROR_SUCCESS )
+                {
+                    maxValue = MAX_HKEY_VALUE;
+                    value[0] = '\0';
+
+                    retCode = RegQueryValueEx(hExtKey, "", NULL, NULL, (LPBYTE)value, (LPDWORD)&maxValue);
+                    if ( retCode == ERROR_SUCCESS )
+                    {
+                        if ( StrCmpI(value, progID) == 0 )
+                        {
+                            matches++;
+                        }
+                    }
+                    RegCloseKey(hExtKey);
+                }
+            }
+        }
+    }
+
+    if ( matches == 0 )
+    {
+        goto done_out;
+    }
+
+    recs = (pExtensionInfo)LocalAlloc(LPTR, matches * sizeof(extensionInfo));
+    if ( recs == NULL )
+    {
+        /* What to do, we are not in an interpreter context ? */
+        goto done_out;
+    }
+
+    size_t processed = 0;
+    for ( uint32_t i = 0; i < cSubKeys; i++ )
+    {
+        maxName = MAX_HKEY_NAME;
+        retCode = RegEnumKeyEx(hKCR, i, keyName, (LPDWORD)&maxName, NULL, NULL, NULL, NULL);
+        if (retCode == ERROR_SUCCESS)
+        {
+            if ( *keyName == '.' )
+            {
+                HKEY hExtKey;
+
+                retCode = RegOpenKeyEx(hKCR, keyName, 0, KEY_QUERY_VALUE, &hExtKey);
+                if ( retCode == ERROR_SUCCESS )
+                {
+                    maxValue = MAX_HKEY_VALUE;
+                    value[0] = '\0';
+
+                    retCode = RegQueryValueEx(hExtKey, "", NULL, NULL, (LPBYTE)value, (LPDWORD)&maxValue);
+                    if ( retCode == ERROR_SUCCESS )
+                    {
+                        if ( StrCmpI(value, progID) == 0 )
+                        {
+                            pExtensionInfo current = &recs[processed++];
+
+                            current->exists = true;
+                            strcpy(current->extension, keyName);
+
+                            qualifyExtensionInfo(keyName, current, progID);
+
+                            printf("%s -> %s\n", keyName, value);
+                        }
+                    }
+                    RegCloseKey(hExtKey);
+                }
+            }
+        }
+    }
+
+done_out:
+    *count = matches;
+    return recs;
+}
+
 /**
  * Standard main entry point.
  *
  */
 int __cdecl main(int argc, char *argv[])
 {
+    if ( isTestRequest(argc, argv) )
+    {
+        size_t count = 0;
+        pExtensionInfo recs = getExtensionRecords("SlickEdit", &count);
+
+        printf("\ngot extensions recs=%p count=%d\n", recs, count);
+
+        for ( size_t i = 0; i < count; i++ )
+        {
+            pExtensionInfo current = &recs[i];
+            printf("%s\n", current->displayName);
+        }
+        return 0;
+    }
+
     if ( isVersionRequest(argc, argv) )
     {
         return 0;