--- wpkg.js	Thu Mar 16 19:25:47 2006
+++ wpkg_n.js	Mon Mar 20 17:22:26 2006
@@ -59,6 +59,9 @@
  * /forceinstall
  *     Forces installation over existing packages.
  *
+ * /norunningstate
+ *     Do not export the running state to the registry. (sRegWPKG_Running)
+ *
  * /debug
  * /verbose
  *     Prints some debugging info.
@@ -101,6 +104,7 @@
 
 var nonotify = false;
 var noreboot = false;
+var exportRunningState = true;	
 
 var packagesDocument;
 var profilesDocument;
@@ -127,6 +131,8 @@
 var settings_file_name = "wpkg.xml";
 
 var sRegPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+// here we indicate our running state
+var sRegWPKG_Running = "HKLM\\Software\\WPKG\\running";
 
 
 /*******************************************************************************
@@ -205,6 +211,13 @@
         forceInstall = false;
     }
     
+    // want to export the state of WPKG to registry?
+    if (isArgSet(argv, "/norunningstate")) {
+    	exportRunningState = false;
+    } else {
+	// indicate that we are running
+	setRunningState("true");
+    }
     
     // will use the fso a bit
     var fso = new ActiveXObject("Scripting.FileSystemObject");
@@ -403,6 +416,9 @@
     message += "/forceinstall\n";
     message += "    Forces installation over existing packages.\n";
     message += "\n";
+    message += "/norunningstate\n";
+    message += "   Do not export the running state to the registry.\n";
+    message += "\n";
     message += "/debug\n";
     message += "/verbose\n";
     message += "    Prints some debugging info.\n";
@@ -860,6 +876,19 @@
     return val;
 }
 
+function setRunningState(statename) {
+    var WshShell = new ActiveXObject("WScript.Shell");
+    var val;
+    
+    try {
+    	val = WshShell.RegWrite(sRegWPKG_Running, statename);
+    } catch (e) {
+    	val = null;
+    }
+
+    return val;
+}
+    	
 
 /**
  * Scans uninstall list for given name.
@@ -1710,34 +1739,54 @@
             if (searchArray(packageArray, packageNode)) {
                 continue;
             }
-            // Somewhere to store our dependencies
-            var depends=null;
+
             // sometimes nodes can be null
             if (packageNode != null) {
-                // add the new node to the array
+		// add package-id dependencies 
+		appendPackageDependencies(packageArray, packageNode);
+                // add the new node to the array _after_ adding dependencies
                 packageArray.push(packageNode);
-                depends = packageNode.getAttribute("depends");
+            }
+        }
             }
 
-            // Now search all the dependencies
-            if ((depends != null) && (depends != "")) {
-                var deparray=depends.split(",");
-                for (var k=0;k<deparray.length;k++) {
-                    deppack=trim(deparray[k]);
-                    var deppkg=packages.selectSingleNode("package[@id='" + deppack + "']");
-                    if (searchArray(packageArray,deppkg)) {
+    return packageArray;
+}
+
+/* nearly the same as appendProfileDependencies() but more relaxed on unknown
+ * or invalid dependencies */
+function appendPackageDependencies(packageArray, packageNode) {
+    appendDependencies(packageArray, packageNode, packages, "package");
+}
+
+function appendDependencies(appendArray, appendNode, sourceArray, sourceName) {
+    // search for package tags in each profile
+    var dependsNodes = appendNode.selectNodes("depends");
+    if (dependsNodes != null) {
+	for (var i = 0; i < dependsNodes.length; i++) {
+	    var dependsId = dependsNodes(i).getAttribute(sourceName + "-id");
+	    // skip unknown entries 
+	    if (dependsId == null) continue;
+
+	    if (debug) info("Checking " + sourceName + " dependency: " + dependsId);
+	    var dependsNode = sourceArray.selectSingleNode(sourceName + "[@id='" +
+		dependsId + "']");
+
+	    if (dependsNode == null) {
+		throw new Error(0, "Invalid dependency \"" + dependsId +
+			"\" from " + sourceName +  " \"" + appendNode.getAttribute("id") 
+			+ "\".");
+	    }
+	    // duplicate check 
+	    if (searchArray(appendArray, dependsNode)) {
                         continue;
                     } else {
-                        if ((deppkg != null)) {
-                            packageArray.push(deppkg);
-                        }
-                    }
+		if (debug) info("Add " + sourceName + " dependecy: " + dependsId);
+		appendArray.push(dependsNode);
+		appendDependencies(appendArray, dependsNode, sourceArray, sourceName);
                 }
-            } // end search of dependencies
         }
     }
-    
-    return packageArray;
 }
 
 /**
@@ -1768,30 +1817,7 @@
  * array. Recurses into self to get an entire dependency tree.
  */
 function appendProfileDependencies(profileArray, profileNode) {
-    var dependencyNodes = profileNode.selectNodes("depends");
-    for (var i = 0; i < dependencyNodes.length; i++) {
-        var dependentId = dependencyNodes(i).getAttribute("profile-id");
-        
-        // select profile that matches the "profile-id" attribute
-        var dependentNode = profiles.selectSingleNode("profile[@id='" +
-            dependentId + "']");
-            
-        // if the profile doesn't exist, we have a bad dependency
-        if (dependentNode == null) {
-            throw new Error(0, "Invalid dependency \"" + dependentId +
-                "\" from profile \"" + profileNode.getAttribute("id") + "\".");
-        }
-        
-        // search array for pre-existing profile, we don't want duplicates
-        if (searchArray(profileArray, dependentNode)) {
-            continue;
-        }
-        
-        // add the new node to the array, and add it's dependencies also
-        // (recurse)
-        profileArray.push(dependentNode);
-        appendProfileDependencies(profileArray, dependentNode);
-    }
+    appendDependencies(profileArray, profileNode, profiles, "profile");
 }
 
 /**
@@ -2229,6 +2255,10 @@
  * Ends program execution with the specified exit code.
  */
 function exit(exitCode) {
+    if (exportRunningState) {
+	// reset running state 
+	setRunningState("false");
+    }
     WScript.Quit(exitCode);
 }
 /**
