Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.69
diff -u -r1.69 system.install
--- modules/system/system.install	10 Jan 2007 23:22:34 -0000	1.69
+++ modules/system/system.install	31 Mar 2007 14:07:47 -0000
@@ -1068,6 +1068,366 @@
       )");
       db_query("CREATE INDEX {watchdog}_type_idx ON {watchdog} (type)");
       break;
+
+   case 'mssql':
+     db_query("CREATE TABLE {access} (
+         aid int NOT NULL identity(1,1),
+         mask varchar(255) NOT NULL default '',
+         type varchar(255) NOT NULL default '',
+         status int NOT NULL default '0',
+         PRIMARY KEY (aid)
+       );");
+     db_query("CREATE TABLE {authmap} (
+       aid int  NOT NULL identity(1,1),
+       uid int NOT NULL default '0',
+       authname varchar(128) unique NOT NULL default '',
+       module varchar(128) NOT NULL default '',
+       PRIMARY KEY (aid)
+     );");
+     db_query("CREATE TABLE {blocks} (
+       module varchar(64) DEFAULT '' NOT NULL,
+       delta varchar(32) NOT NULL default '0',
+       theme varchar(255) NOT NULL default '',
+       status int DEFAULT '0' NOT NULL,
+       weight int DEFAULT '0' NOT NULL,
+       region varchar(64) DEFAULT 'left' NOT NULL,
+       custom int DEFAULT '0' NOT NULL,
+       throttle int DEFAULT '0' NOT NULL,
+       visibility int DEFAULT '0' NOT NULL,
+       pages varchar(4000) DEFAULT '' NOT NULL,
+       title varchar(64) DEFAULT '' NOT NULL
+     );");
+     db_query("CREATE TABLE {boxes} (
+       bid int NOT NULL identity(1,1),
+       title varchar(64) NOT NULL default '',
+       body text,
+       info varchar(128) unique NOT NULL default '',
+       format int NOT NULL default '0',
+       PRIMARY KEY (bid),
+     );");
+     db_query("CREATE TABLE {cache} (
+       cid varchar(255) NOT NULL default '',
+       data text,
+       expire int NOT NULL default '0',
+       created int NOT NULL default '0',
+       headers text,
+       PRIMARY KEY (cid),
+     );");
+     db_query("CREATE TABLE {cache_filter} (
+       cid varchar(255) NOT NULL default '',
+       data text,
+       expire int NOT NULL default '0',
+       created int NOT NULL default '0',
+       headers text,
+       PRIMARY KEY (cid),
+     );");
+     db_query("CREATE TABLE {cache_menu} (
+       cid varchar(255) NOT NULL default '',
+       data text,
+       expire int NOT NULL default '0',
+       created int NOT NULL default '0',
+       headers text,
+       PRIMARY KEY (cid),
+     );");;
+     db_query("CREATE TABLE {cache_page} (
+       cid varchar(255) NOT NULL default '',
+       data text,
+       expire int NOT NULL default '0',
+       created int NOT NULL default '0',
+       headers text,
+       PRIMARY KEY (cid),
+     );");
+     db_query("CREATE TABLE {comments} (
+       cid int NOT NULL default '0',
+       pid int NOT NULL default '0',
+       nid int NOT NULL default '0',
+       uid int NOT NULL default '0',
+       subject varchar(64) NOT NULL default '',
+       comment text NOT NULL,
+       hostname varchar(128) NOT NULL default '',
+       timestamp int NOT NULL default '0',
+       score int NOT NULL default '0',
+       status int  NOT NULL default '0',
+       format int NOT NULL default '0',
+       thread varchar(255) NOT NULL,
+       users text,
+       name varchar(60) NULL default NULL,
+       mail varchar(64) NULL default NULL,
+       homepage varchar(255) NULL default NULL,
+       PRIMARY KEY (cid)
+     );");
+     db_query("CREATE TABLE {node_comment_statistics} (
+       nid int  NOT NULL default '0',
+       last_comment_timestamp int NOT NULL default '0',
+       last_comment_name varchar(60) NULL default NULL,
+       last_comment_uid int NOT NULL default '0',
+       comment_count int  NOT NULL default '0',
+       PRIMARY KEY (nid)
+     );");
+     db_query("CREATE TABLE {files} (
+       fid int  NOT NULL default 0,
+       nid int  NOT NULL default 0,
+       filename varchar(255) NOT NULL default '',
+       filepath varchar(255) NOT NULL default '',
+       filemime varchar(255) NOT NULL default '',
+       filesize int  NOT NULL default 0,
+       PRIMARY KEY (fid)
+     );
+     ");
+     db_query("CREATE TABLE {file_revisions} (
+       fid int  NOT NULL default 0,
+       vid int  NOT NULL default 0,
+       description varchar(255) NOT NULL default '',
+       list int  NOT NULL default 0,
+       PRIMARY KEY (fid, vid)
+     );");
+     db_query("CREATE TABLE {filter_formats} (
+       format int NOT NULL identity(1,1),
+       name varchar(255) unique NOT NULL default '',
+       roles varchar(255) NOT NULL default '',
+       cache int NOT NULL default '0',
+       PRIMARY KEY (format)
+     );");
+     db_query("CREATE TABLE {filters} (
+       format int NOT NULL default '0',
+       module varchar(64) NOT NULL default '',
+       delta int DEFAULT '0' NOT NULL,
+       weight int DEFAULT '0' NOT NULL
+     );");
+     db_query("CREATE TABLE {flood} (
+       event varchar(64) NOT NULL default '',
+       hostname varchar(128) NOT NULL default '',
+       timestamp int NOT NULL default '0'
+     );");
+     db_query("CREATE TABLE {history} (
+       uid int NOT NULL default '0',
+       nid int NOT NULL default '0',
+       timestamp int NOT NULL default '0',
+       PRIMARY KEY (uid,nid)
+     );");
+     db_query("CREATE TABLE {menu} (
+       mid int  NOT NULL default '0',
+       pid int  NOT NULL default '0',
+       path varchar(255) NOT NULL default '',
+       title varchar(255) NOT NULL default '',
+       description varchar(255) NOT NULL default '',
+       weight int NOT NULL default '0',
+       type int  NOT NULL default '0',
+       PRIMARY KEY (mid)
+     );");
+     db_query("CREATE TABLE {node} (
+       nid int  NOT NULL default '0',
+       vid int unique NOT NULL default '0',
+       type varchar(32) NOT NULL default '',
+       title varchar(128) NOT NULL default '',
+       uid int NOT NULL default '0',
+       status int NOT NULL default '1',
+       created int NOT NULL default '0',
+       changed int NOT NULL default '0',
+       comment int NOT NULL default '0',
+       promote int NOT NULL default '0',
+       moderate int NOT NULL default '0',
+       sticky int NOT NULL default '0',
+       PRIMARY KEY  (nid, vid)
+     );");
+     db_query("CREATE TABLE {node_access} (
+       nid int  NOT NULL default '0',
+       gid int  NOT NULL default '0',
+       realm varchar(255) NOT NULL default '',
+       grant_view int  NOT NULL default '0',
+       grant_update int  NOT NULL default '0',
+       grant_delete int  NOT NULL default '0',
+       PRIMARY KEY (nid,gid,realm)
+     );");
+     db_query("CREATE TABLE {node_revisions} (
+       nid int  NOT NULL,
+       vid int  NOT NULL,
+       uid int NOT NULL default '0',
+       title varchar(128) NOT NULL default '',
+       body text NOT NULL default '',
+       teaser varchar(4000) NOT NULL default '',
+       log text NOT NULL default '',
+       timestamp int NOT NULL default '0',
+       format int NOT NULL default '0',
+       PRIMARY KEY  (vid),
+     );");
+     db_query("CREATE TABLE {node_type} (
+       type varchar(32) NOT NULL,
+       name varchar(255) NOT NULL default '',
+       module varchar(255) NOT NULL,
+       description varchar(4000) NOT NULL default '',
+       help varchar(4000) NOT NULL default '',
+       has_title tinyint NOT NULL,
+       title_label varchar(255) NOT NULL default '',
+       has_body tinyint NOT NULL,
+       body_label varchar(255) NOT NULL default '',
+       min_word_count int NOT NULL,
+       custom int NOT NULL DEFAULT '0',
+       modified int NOT NULL DEFAULT '0',
+       locked int NOT NULL DEFAULT '0',
+       orig_type varchar(255) NOT NULL default '',
+       PRIMARY KEY (type))");
+     db_query("CREATE TABLE {url_alias} (
+       pid int  NOT NULL identity(1,1),
+       src varchar(128) NOT NULL default '',
+       dst varchar(128) unique NOT NULL default '',
+       PRIMARY KEY (pid)
+     );");
+     db_query("CREATE TABLE {permission} (
+       rid int  NOT NULL default '0',
+       perm varchar(4000),
+       tid int  NOT NULL default '0'
+     );");
+     db_query("CREATE TABLE {role} (
+       rid int  NOT NULL identity(1,1),
+       name varchar(32) unique NOT NULL default '',
+       PRIMARY KEY (rid)
+     );");
+     db_query("CREATE TABLE {blocks_roles} (
+       module varchar(64) NOT NULL,
+       delta varchar(32) NOT NULL,
+       rid int NOT NULL,
+       PRIMARY KEY (module, delta, rid)
+     );");
+     db_query("CREATE TABLE {sessions} (
+       uid int  NOT NULL,
+       sid varchar(32) NOT NULL default '',
+       hostname varchar(128) NOT NULL default '',
+       timestamp int NOT NULL default '0',
+       cache int NOT NULL default '0',
+       session text,
+       PRIMARY KEY (sid)
+     );");
+     db_query("CREATE TABLE {sequences} (
+       name varchar(255) NOT NULL default '',
+       id int  NOT NULL default '0',
+       PRIMARY KEY (name)
+     );");
+     db_query("CREATE TABLE {node_counter} (
+       nid int NOT NULL default '0',
+       totalcount int  NOT NULL default '0',
+       daycount int NOT NULL default '0',
+       timestamp int  NOT NULL default '0',
+       PRIMARY KEY (nid)
+     );");
+     db_query("CREATE TABLE {system} (
+       filename varchar(255) NOT NULL default '',
+       name varchar(255) NOT NULL default '',
+       type varchar(255) NOT NULL default '',
+       description varchar(255) NOT NULL default '',
+       status char NOT NULL default '0',
+       throttle int DEFAULT '0' NOT NULL,
+       bootstrap int NOT NULL default '0',
+       schema_version smallint NOT NULL default -1,
+       weight int NOT NULL default '0',
+       PRIMARY KEY (filename)
+     );");
+     db_query("CREATE TABLE {term_data} (
+       tid int  NOT NULL default '0',
+       vid int  NOT NULL default '0',
+       name varchar(255) NOT NULL default '',
+       description varchar(4000),
+       weight int NOT NULL default '0',
+       PRIMARY KEY (tid)
+     );");
+     db_query("CREATE TABLE {term_hierarchy} (
+       tid int  NOT NULL default '0',
+       parent int  NOT NULL default '0',
+       PRIMARY KEY (tid, parent)
+     );");
+     db_query("CREATE TABLE {term_node} (
+     nid int  NOT NULL default '0',
+     tid int  NOT NULL default '0',
+     PRIMARY KEY (tid,nid)
+     );");
+     db_query("CREATE TABLE {term_relation} (
+       tid1 int  NOT NULL default '0',
+       tid2 int  NOT NULL default '0'
+     );");
+     db_query("CREATE TABLE {term_synonym} (
+       tid int  NOT NULL default '0',
+       name varchar(255) NOT NULL default ''
+     );");
+     db_query("CREATE TABLE {users} (
+       uid int  NOT NULL default '0',
+       name varchar(60) unique NOT NULL default '',
+       pass varchar(32) NOT NULL default '',
+       mail varchar(64) default '',
+       mode int NOT NULL default '0',
+       sort int default '0',
+       threshold int default '0',
+       theme varchar(255) NOT NULL default '',
+       signature varchar(255) NOT NULL default '',
+       created int NOT NULL default '0',
+       access int NOT NULL default '0',
+       login int NOT NULL default '0',
+       status int NOT NULL default '0',
+       timezone varchar(8) NULL default NULL,
+       language varchar(12) NOT NULL default '',
+       picture varchar(255) NOT NULL DEFAULT '',
+       init varchar(64) default '',
+       data text NULL,
+       PRIMARY KEY (uid)
+     );");
+     db_query("CREATE TABLE {users_roles} (
+       uid int  NOT NULL default '0',
+       rid int  NOT NULL default '0',
+       PRIMARY KEY (uid, rid)
+     );");
+     db_query("CREATE TABLE {variable} (
+       name varchar(48) NOT NULL default '',
+       value text NOT NULL,
+       PRIMARY KEY (name)
+     );");
+     db_query("CREATE TABLE {vocabulary} (
+       vid int  NOT NULL default '',
+       name varchar(255) NOT NULL default '',
+       description varchar(4000),
+       help varchar(255) NOT NULL default '',
+       relations int  NOT NULL default '0',
+       hierarchy int  NOT NULL default '0',
+       multiple int  NOT NULL default '0',
+       required int  NOT NULL default '0',
+       tags int  NOT NULL default '0',
+       module varchar(255) NOT NULL default '',
+       weight int NOT NULL default '0',
+       PRIMARY KEY (vid)
+     );");
+     db_query("CREATE TABLE {vocabulary_node_types} (
+       vid int  NOT NULL DEFAULT '0',
+       type varchar(32) NOT NULL DEFAULT '',
+       PRIMARY KEY (vid, type)
+     );");
+     db_query("CREATE TABLE {watchdog} (
+       wid int NOT NULL identity(1,1),
+       uid int NOT NULL default '0',
+       type varchar(16) NOT NULL default '',
+       message text NOT NULL,
+       severity int  NOT NULL default '0',
+       link varchar(255) NOT NULL default '',
+       location varchar(128) NOT NULL default '',
+       referer varchar(128) NOT NULL default '',
+       hostname varchar(128) NOT NULL default '',
+       timestamp int NOT NULL default '0',
+       PRIMARY KEY (wid)
+     );");
+     // Functions to implement GREATEST function from MySQL, Oracle, and PostGres
+     db_query("CREATE FUNCTION dbo.GREATEST
+              ( @val1 SQL_VARIANT,
+                @val2 SQL_VARIANT, 
+                @val3 SQL_VARIANT )
+                RETURNS SQL_VARIANT 
+                AS
+                BEGIN
+                RETURN ( 
+                  CASE 
+                    WHEN @val1 > @val2 AND @val1 > @val3 THEN @val1 
+                    WHEN @val2 > @val3 THEN @val2
+                  ELSE @val3
+                  END
+                    )
+                END;");
+     break;
   }
 
   db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/engines/phptemplate/phptemplate.engine', 'phptemplate', 'theme_engine', '', 1, 0, 0, 0)");
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.440.2.4
diff -u -r1.440.2.4 system.module
--- modules/system/system.module	29 Jan 2007 21:51:53 -0000	1.440.2.4
+++ modules/system/system.module	31 Mar 2007 14:07:50 -0000
@@ -268,7 +268,20 @@
       'description' => t('Enable or disable clean URLs for your site.'),
       'callback' => 'drupal_get_form',
       'callback arguments' => array('system_clean_url_settings'));
-
+      
+      // Cron:
+      $items[] = array('path' => 'admin/settings/cron',
+        'title' => t('cron'),
+        'description' => t('Cron Settings'),
+        'callback' => 'drupal_get_form',
+        'callback arguments' => array('system_cron_settings'),
+        'access' => $access);
+      $items[] = array('path' => 'admin/logs/cron',
+        'title' => t('cron runs'),
+        'description' => t('Information about past cron runs'),
+        'callback' => 'drupal_get_form',
+        'callback arguments' => array('system_cron_logs'),
+        'access' => $access);
 
     // Logs:
     $items[] = array(
@@ -1227,6 +1240,158 @@
   return 'admin/build/themes';
 }
 
+ /**
+  * Cron logs
+  */
+function system_cron_logs($form_values = NULL) {
+  if(is_numeric(arg(3))) {
+    $rid = arg(3);
+    $cron_run = db_fetch_object(db_query("SELECT cr.rid, cr.run_date, cr.run_status, cr.run_ticks, cr.run_stop, COUNT(riid) modules_ran 
+      FROM {cron_runs} cr INNER JOIN {cron_run_info} ci ON cr.rid = ci.rid 
+      WHERE cr.rid = %d 
+      GROUP BY cr.rid, cr.run_date, cr.run_status, cr.run_ticks, cr.run_stop 
+      ", $rid));
+    if(!$cron_run) {
+      drupal_set_message(t('Invalid cron run given'), 'error');
+      drupal_goto('admin/logs/cron');
+    }
+
+    # Icon Setup
+    $icons = array(WATCHDOG_NOTICE  => theme('image', 'misc/watchdog-ok.png', t('ok'), t('ok')),
+                 WATCHDOG_WARNING => theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning')),
+                 WATCHDOG_ERROR   => theme('image', 'misc/watchdog-error.png', t('error'), t('error')));
+
+    # General Run Information
+    $form['cron_run_info'] = array('#value' => "
+      Run ID: <strong>$rid</strong><br/>
+      Run Date: <strong>" . format_date($cron_run->run_date, 'large') . "</strong><br/>
+      Modules Ran: <strong>$cron_run->modules_ran</strong><br/>
+      Run Status: " . $icons[$cron_run->run_status] . "<br/><hr/>
+    ");
+    
+    # Get the modules that ran
+    $module_runs = db_query("SELECT * FROM {cron_run_info} WHERE rid = %d", $rid);
+    $rows = $module_run = $row = $headers = array();
+    $time_format = 'h:i:s a';
+    while($module_run = db_fetch_object($module_runs)) {
+      $row = array();
+      $row[] = $module_run->module_name;
+      $row[] = format_date($module_run->run_date, 'custom', $time_format);
+      $row[] = $module_run->run_stop != '' ? format_date($module_run->run_stop, 'custom', $time_format) : t('(running)');
+      if($module_run->run_stop) {
+        $row[] = ($module_run->run_stop - $module_run->run_date) . " seconds";
+      }
+      else {
+        $row[] = (time() - $module_run->run_date) . " seconds";
+      }
+      $row[] = $icons[$module_run->run_status];
+      $rows[] = $row;
+    }
+    $headers = array(t('Module'), t('Start'), t('Finish'), t('Run time'), t('Status'));
+    $form['run_table'] = array('#value' => 
+      theme('table', $headers, $rows));
+    
+  }
+  else {
+    $rs = pager_query ("SELECT * FROM {cron_runs} ORDER BY run_date DESC", 20);
+    while($row = db_fetch_object($rs)) {
+      $cron_runs[$row->rid] = $row;
+    }
+
+    $form['cron_runs'] = array('#value' => $cron_runs);
+    $form['pager_info'] = array('#value' => theme('pager', 20, NULL, 0));
+    $form['#theme'] = 'system_cron_runs_logs';
+  }
+   
+  return $form;
+  
+}
+
+function theme_system_cron_runs_logs($form) {
+
+  $icons = array(WATCHDOG_NOTICE  => theme('image', 'misc/watchdog-ok.png', t('ok'), t('ok')),
+                 WATCHDOG_WARNING => theme('image', 'misc/watchdog-warning.png', t('warning'), t('warning')),
+                 WATCHDOG_ERROR   => theme('image', 'misc/watchdog-error.png', t('error'), t('error')));
+  $headers = array(
+    array('field' => 'run_date', 'data' => t('Cron run date')),
+    array('field' => 'rid', 'data' => t('Run ID')),
+    array('field' => 'run_information', 'data' => t('Run status'))
+    );
+  $cron_runs = $form['cron_runs']['#value'];
+  unset($form['cron_runs']);
+  $row = $rows = array();
+  if(!is_array($cron_runs)) {
+    $cron_runs = array();
+  }
+  foreach($cron_runs as $rid => $info) {
+    $link = 'admin/logs/cron/' . $rid;
+    $row['data'] = array(l(format_date($info->run_date,'long'), $link), l($rid, $link), $icons[$info->run_status]);
+    $row['class'] = 'ok';
+    $row['align'] = 'center';
+    $rows[] = $row;
+    $row = array();
+  }
+  
+  $output .= drupal_render($form);
+  $output .= theme('table', $headers, $rows, array('class' => 'system-status-report'));
+  return $output;
+ 
+}
+
+
+/**
+ * Menu callback; provides the cron basic/advanced settings interface.
+ *
+ * A cron run can be setup to run in a "multi-threaded" enviroment.
+ * Each module will have it's own "report" of how it ran, etc.
+ *
+ * @return
+ *   The form array.
+ */
+function system_cron_settings($form_values = NULL) {
+  global $base_url;
+  $form['basic_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Basic Cron Settings'),
+    '#collapsible' => FALSE);
+  $form['basic_settings']['cron_run_time'] = array(
+    '#type' => 'textfield',
+    '#size' => 5,
+    '#title' => t('Cron run time'),
+    '#description' => t('This is the time in seconds that a cron run is alloted to complete a run. Try increasing this value if you notice that 
+      you have a lot of errors of your cron run not finishing.'),
+    '#default_value' => variable_get('cron_run_time', 240));
+  $history_options = drupal_map_assoc(range(50,1000,50));
+  $form['basic_settings']['cron_run_history'] = array(
+    '#type' => 'select',
+    '#title' => t('Cron history'),
+    '#options' => $history_options,
+    '#default_value' => variable_get('cron_run_history', 50),
+    '#description' => t('The number of cron runs you would like to keep. It will delete starting with the oldest cron run.'));
+  if($base_url == '') {
+    drupal_set_message('warning', t('In order to use advanced cron settings, you must set the $base_url variable in your settings.php file.'));
+  } else {
+    $form['advanced_cron_settings'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Advanced Cron Settings'),
+      '#collapsible' => FALSE);
+    $form['advanced_cron_settings']['cron_run_advanced'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable advanced cron runs'),
+      '#description' => t('Check this box to have your cron runs run in a multi-threaded enviroment. 
+        This will also give you more information about each individual modules cron run.'),
+      '#default_value' => variable_get('cron_run_advanced', FALSE));
+    $form['advanced_cron_settings']['cron_run_command'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Cron run command'),
+      '#description' => t('This is the command you use to run your cron. Use <em>ONLY</em> the command. Example: <strong><em>/usr/bin/lynx -source</em></strong>'),
+      '#default_value' => variable_get('cron_run_command', ""));
+  }
+
+  
+  return system_settings_form($form);
+}
+
 /**
  * Menu callback; provides module enable/disable interface.
  *
@@ -1755,7 +1920,12 @@
 function system_run_cron() {
    // Run cron manually
    if (drupal_cron_run()) {
-     drupal_set_message(t('Cron ran successfully'));
+     if(variable_get('cron_run_advanced', FALSE)) {
+       drupal_set_message(t('Cron started successfull'));
+     }
+     else {
+      drupal_set_message(t('Cron ran successfully'));
+     }
    }
    else {
      drupal_set_message(t('Cron run failed'));
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.611
diff -u -r1.611 common.inc
--- includes/common.inc	10 Jan 2007 23:30:07 -0000	1.611
+++ includes/common.inc	31 Mar 2007 14:07:43 -0000
@@ -1977,16 +1977,44 @@
  * Returns TRUE if ran successfully
  */
 function drupal_cron_run() {
+  $cron_run_time = variable_get('cron_run_time', 240);
+  $advanced_cron = variable_get('cron_run_advanced', FALSE);
+  $cron_info = array();
+  $cron_run_max_threads = variable_get('cron_run_max_threads', 4);
   // If not in 'safe mode', increase the maximum execution time:
+  
   if (!ini_get('safe_mode')) {
-    set_time_limit(240);
+    set_time_limit($cron_run_time);
   }
-
+  // RESRET
+  #variable_del('cron_semaphore');
+  #variable_del('cron_wait_sempahore');  
   // Fetch the cron semaphore
   $semaphore = variable_get('cron_semaphore', FALSE);
+  $cron_wait_semaphore = variable_get('cron_wait_semaphore', FALSE);
+  
 
-  if ($semaphore) {
-    if (time() - $semaphore > 3600) {
+  /**
+   * If we enter the cron run w/o a rid 
+   * but the semephore is set, that means we 
+   * are in a 'cron session'. Thus we need
+   * to check to see if we need to time out
+   * this cron session.
+   * 
+   */
+  if (($semaphore || $cron_wait_semaphore) && !$_REQUEST['rid']) {
+    //if (time() - $semaphore > 3600) {
+    if($advanced_cron) {
+      if(time() - $cron_wait_semaphore > 3600) {
+        watchdog('cron', t('Cron been waiting for a cron to shutdown for more than an hour and is most likely stuck.'), WATCHDOG_ERROR);
+        variable_del('cron_wait_semaphore');
+      }
+      else {
+        watchdog('cron', t('Attempting to re-run cron while another cron is waiting for cron shutdown.'), WATCHDOG_WARNING);
+        return;
+      }
+    }
+    if(time() - $semaphore > 3600) {
       // Either cron has been running for more than an hour or the semaphore
       // was not reset due to a database error.
       watchdog('cron', t('Cron has been running for more than an hour and is most likely stuck.'), WATCHDOG_ERROR);
@@ -1999,19 +2027,147 @@
       watchdog('cron', t('Attempting to re-run cron while it is already running.'), WATCHDOG_WARNING);
     }
   }
+  else if($_REQUEST['rid']) {
+    $rid = $_REQUEST['rid'];
+    $riid = $_REQUEST['riid'];
+    error_log("Processing: 'Rid: ' $rid, 'Riid: ' $riid");
+    $run_module = $_REQUEST['module'];
+    db_query("UPDATE {cron_run_info} SET run_status = %d, run_date = %d WHERE riid = %d", -1, time(), $riid);
+    #$module_ping_function = create_function('', 'error_log("Running tick function"); return db_query("UPDATE {cron_run_info} SET run_ping = ' . time() . ' WHERE riid = \'' . $riid . '\'");');
+    #register_tick_function('drupal_cron_ping', $riid);
+    // Run this cron
+    #declare(ticks = 1) {
+      module_invoke($run_module, 'cron');
+    #}
+    # End Run
+    db_query("UPDATE {cron_run_info} SET run_status = %d, run_stop = %d WHERE riid = %d", WATCHDOG_NOTICE, time(), $riid);
+    db_query("UPDATE {cron_runs} SET run_ticks = run_ticks + 1 WHERE rid = %d", $rid);
+  }
   else {
+    # First truncate any old crons
+    $max_crons = variable_get('cron_run_history', 50);
+    $truncate = db_result(db_query("SELECT COUNT(*) FROM {cron_runs}"));
+    if($truncate > $max_crons) {
+      $rs = db_query_range("SELECT rid FROM {cron_runs} ORDER BY rid DESC", $max_crons, $truncate);
+      while($row = db_fetch_object($rs)) {
+        db_query("DELETE FROM {cron_run_info} WHERE rid = %d", $row->rid);
+        db_query("DELETE FROM {cron_runs} WHERE rid = %d", $row->rid);
+      }
+    }
+  
+    if($advanced_cron) {
+      /**
+       * First, we need to wait until the other sessions
+       * have finished. We will also time out as needed
+       * any cron sessions that a running to long. This is 
+       * so we don't over load the system with some errand
+       * cron run and we keep calling a thread for it, thus
+       * getting a race condition.
+       */
+      $cron_wait_semaphore = time(); // So we know we are waiting on a run to finish and we don't stack up runs
+      variable_set('cron_wait_semaphore', $cron_wait_semaphore);
+      $module_count = db_result(db_query("SELECT COUNT(*) FROM {cron_run_info} WHERE run_stop = ''"));
+      while($module_count > 0) {
+        watchdog('cron', t('Cron is attempting to wait for a previous cron run to finish. Currently %module_count modules running', array('%module_count' => $module_count)));
+        sleep(10);
+        // Check for stuck modules
+        $stuck_rs = db_query("SELECT * FROM {cron_run_info} WHERE (%d - run_ping) > 3600", time());
+        while($row = db_fetch_object($stuck_rs)) {
+          watchdog('cron', t('%module was not pinged in over an hour had has been marked as completed with errors.', array('%module' => $row->module_name)), WATCHDOG_ERROR);
+          db_query("UPDATE {cron_run_info} SET run_stop = %d, run_status = %d WHERE riid = %d", time(), WATCHDOG_ERROR, $row->riid);
+        }
+        // Ping that this session is still running
+        // Update the module count
+        $module_count = db_result(db_query("SELECT COUNT(*) FROM {cron_run_info} WHERE run_stop = ''"));
+      }
+      # Before we start again, if were in advanced mode, we need to see if we need to
+      # time out or error and cron runs.
+      # Since we're dealing with dates, and need a date diff, much easier to work
+      # with just a unix time stamp to do a simple (-)
+      /*db_query("UPDATE {cron_runs} SET run_status = '%d' WHERE (run_date - run_stop >= $cron_run_time) || (run_date - %d >= $cron_run_time)",
+        WATCHDOG_ERROR, time());
+      db_query("UPDATE {cron_run_info} SET run_status = '%d' WHERE (run_date - run_stop >= $cron_run_time) || (run_date - %d >= $cron_run_time)",
+        WATCHDOG_ERROR, time());
+      */
+    }
+
     // Register shutdown callback
     register_shutdown_function('drupal_cron_cleanup');
 
     // Lock cron semaphore
-    variable_set('cron_semaphore', time());
-
-    // Iterate through the modules calling their cron handlers (if any):
-    module_invoke_all('cron');
-
+    $semaphore = time();
+    variable_set('cron_semaphore', $semaphore);
+    if($advanced_cron) {
+      variable_del('cron_wait_semaphore');
+    }
+    if($advanced_cron) {
+      global $base_url;
+      $base_path = base_path();
+      $rid = db_next_id("{cron_runs}_rid");
+      db_query("INSERT INTO {cron_runs}(rid, run_date, run_status) VALUES(%d, %d, %d)", $rid, time(), WATCHDOG_WARNING);
+      $cmd = variable_get('cron_run_command', '');
+      if($cmd == '') {
+        watchdog(t('Cron can not run because you have setup advanced cron without a command'), WATCHDOG_ERROR);
+        return;
+      }
+      # Start firing the modules
+      $modules = module_list(); 
+      $winos = eregi("windows", strtolower(php_uname()));
+      $module_count = 0;
+      foreach($modules as $module) {
+        while($module_count > $cron_run_max_threads) {
+          error_log("About to sleep");
+          sleep(10);
+          error_log("Waking up");
+          // Check for stuck modules
+          $stuck_rs = db_query("SELECT * FROM {cron_run_info} WHERE (%d - run_date) > 3600", time());
+          while($row = db_fetch_object($stuck_rs)) {
+            watchdog('cron', t('%module was started over an hour had has been marked as completed with errors.', array('%module' => $row->module_name)), WATCHDOG_ERROR);
+            db_query("UPDATE {cron_run_info} SET run_stop = %d, run_status = %d WHERE riid = %d", time(), WATCHDOG_ERROR, $row->riid);
+          }
+          // Ping that this session is still running
+          // Update the module count
+          $module_count = db_result(db_query("SELECT COUNT(*) FROM {cron_run_info} WHERE run_stop = '' AND rid = %d", $rid));
+        }
+        error_log("Sleeping...");
+        sleep(1); // Put some time between firing requests
+        error_log('Waking up to fire' . $module);
+        if(module_hook($module, 'cron')) {
+          $riid = db_next_id("{cron_run_info}_riid");
+          db_query("INSERT INTO {cron_run_info}(riid, rid, module_name, run_status) VALUES(%d, %d, '%s', %d)", $riid, $rid, $module, WATCHDOG_WARNING);
+          $run_cmd = "$cmd \"$base_url/cron.php?rid=$rid&riid=$riid&module=$module\""; 
+          if(!$winos) {
+            pclose(popen("$run_cmd & ", "r"));
+          }
+          else {
+            pclose(popen("start \"bla\" " . $run_cmd . " ", "r"));
+            //error_log("Firing: $base_url/cron.php?rid=$rid&riid=$riid&module=$module");
+            //drupal_http_request("$base_url/cron.php?rid=$rid&riid=$riid&module=$module");
+          }
+          $module_count++;
+        }
+      }
+      db_query("UPDATE {cron_runs} SET run_status = %d, run_stop = %d, run_ticks = %d", WATCHDOG_OK, time(), (-1 * $module_count));
+    }
+    else {
+      // Iterate through the modules calling their cron handlers (if any):
+      db_query("INSERT INTO {cron_runs}(run_date, run_status) VALUES(%d, %d)", time(), WATCHDOG_WARNING);
+      $rid = db_result(db_query("SELECT MAX(rid) FROM {cron_runs}"));
+      db_query("INSERT INTO {cron_run_info}(rid, module_name, run_status, run_date) VALUES(%d, '%s', %d, %d)", $rid, 'system-all-modules', WATCHDOG_WARNING, time());
+      $riid = db_result(db_query("SELECT MAX(riid) FROM {cron_run_info}"));
+      module_invoke_all('cron');
+      db_query("UPDATE {cron_run_info} SET run_status = %d, run_stop = %d WHERE riid = %d", WATCHDOG_NOTICE, time(), $riid);
+      db_query("UPDATE {cron_runs} SET run_status = %d, run_ticks = %d, run_stop = %d WHERE rid = %d",WATCHDOG_OK, 0, time(), $rid);
+    }
+    
     // Record cron time
     variable_set('cron_last', time());
-    watchdog('cron', t('Cron run completed.'), WATCHDOG_NOTICE);
+    if($advanced_cron) {
+      watchdog('cron', t('Cron run started <em>%module_count</em> runs.', array('%module_count' => $module_count)), WATCHDOG_NOTICE);
+    }
+    else {
+      watchdog('cron', t('Cron run completed.'), WATCHDOG_NOTICE);
+    }
 
     // Release cron semaphore
     variable_del('cron_semaphore');
@@ -2021,6 +2177,12 @@
   }
 }
 
+function drupal_cron_ping($riid) {
+  error_log("Tick: $riid at " . time());
+  db_query('UPDATE {cron_run_info} SET run_ping = %d WHERE riid = %d', time(), $riid);
+  return;
+}
+
 /**
  * Shutdown function for cron cleanup.
  */
Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.31
diff -u -r1.31 install.inc
--- includes/install.inc	2 Jan 2007 05:05:38 -0000	1.31
+++ includes/install.inc	31 Mar 2007 14:07:44 -0000
@@ -144,7 +144,7 @@
 function drupal_detect_database_types() {
   $databases = array();
 
-  foreach (array('mysql', 'mysqli', 'pgsql') as $type) {
+  foreach (array('mysql', 'mysqli', 'pgsql', 'mssql') as $type) {
     if (file_exists('./includes/install.'. $type .'.inc')) {
       include_once './includes/install.'. $type .'.inc';
       $function = $type .'_is_available';
@@ -301,11 +301,11 @@
  * @param module_list
  *   An array of modules to install.
  */
-function drupal_install_profile($profile, $module_list) {
+function drupal_install_profile($profile, $module_list) { 
   // The system module is a special case; we can't bootstrap until it's
   // installed, so we can't use the normal installation function.
   $module_list = array_diff($module_list, array('system'));
-
+  require_once "./profiles/$profile/$profile.profile";
   $system_path = dirname(drupal_get_filename('module', 'system', NULL));
   require_once './' . $system_path . '/system.install';
   module_invoke('system', 'install');
@@ -319,7 +319,7 @@
   // Install schemas for profile and all its modules.
   module_rebuild_cache();
   drupal_install_modules($module_list);
-
+  
   // And now, run the profile's install function.
   $function = $profile .'_install';
   if (function_exists($function)) {
@@ -337,17 +337,17 @@
  */
 function drupal_install_modules($module_list = array()) {
   $enable_modules = array();
-
+  
   foreach ($module_list as $module) {
     if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
       module_load_install($module);
       module_invoke($module, 'install');
-      $versions = drupal_get_schema_versions($module);
+      $versions = drupal_get_schema_versions($module); 
       drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED);
       $enable_modules[] = $module;
     }
   }
-
+  
   module_enable($enable_modules);
 }
 
Index: includes/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.inc,v
retrieving revision 1.62
diff -u -r1.62 database.inc
--- includes/database.inc	3 Jan 2007 10:59:02 -0000	1.62
+++ includes/database.inc	31 Mar 2007 14:07:43 -0000
@@ -131,7 +131,6 @@
   $previous_db = $active_db;
   // Set the active connection.
   $active_db = $db_conns[$name];
-
   return array_search($previous_db, $db_conns);
 }
 
Index: modules/contact/contact.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.install,v
retrieving revision 1.6
diff -u -r1.6 contact.install
--- modules/contact/contact.install	2 Jan 2007 05:30:29 -0000	1.6
+++ modules/contact/contact.install	31 Mar 2007 14:07:44 -0000
@@ -31,6 +31,17 @@
         UNIQUE (category)
       )");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {contact} (
+        cid int NOT NULL default '0',
+        category varchar(255) unique NOT NULL default '',
+        recipients varchar(1024) NOT NULL default '',
+        reply varchar(1024) NOT NULL default '',
+        weight int NOT NULL default '0',
+        selected int NOT NULL default '0',
+        PRIMARY KEY (cid)
+      );");
+      break;
   }
 }
 
Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.34
diff -u -r1.34 install.php
--- install.php	10 Jan 2007 10:15:07 -0000	1.34
+++ install.php	31 Mar 2007 14:07:41 -0000
@@ -19,14 +19,10 @@
   require_once './includes/bootstrap.inc';
   drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
   require_once './modules/system/system.install';
-  require_once './includes/file.inc';
-
-  // Ensure correct page headers are sent (e.g. caching)
-  drupal_page_header();
 
   // Check existing settings.php.
   $verify = install_verify_settings();
-
+  
   // Drupal may already be installed.
   if ($verify) {
     // Establish a connection to the database.
@@ -56,7 +52,7 @@
   else {
     install_no_profile_error();
   }
-
+  
   // Locale selection
   if (!empty($_GET['locale'])) {
     $install_locale = preg_replace('/[^a-zA-Z_0-9]/', '', $_GET['locale']);
@@ -64,7 +60,7 @@
   elseif (($install_locale = install_select_locale($profile)) !== FALSE) {
     install_goto("install.php?profile=$profile&locale=$install_locale");
   }
-
+  
   // Load the profile.
   require_once "./profiles/$profile/$profile.profile";
 
@@ -76,13 +72,13 @@
   if (!$verify) {
     install_change_settings($profile, $install_locale);
   }
-
+  
   // Verify existence of all required modules.
   $modules = drupal_verify_profile($profile, $install_locale);
   if (!$modules) {
     install_missing_modules_error($profile);
   }
-
+  
   // Perform actual installation defined in the profile.
   drupal_install_profile($profile, $modules);
 
@@ -91,9 +87,6 @@
   if (!drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE)) {
     drupal_set_message(st('All necessary changes to %file have been made, so you should now remove write permissions to this file. Failure to remove write permissions to this file is a security risk.', array('%file' => $settings_file)), 'error');
   }
-  else {
-    drupal_set_message(st('All necessary changes to %file have been made. It has been set to read-only for security.', array('%file' => $settings_file)));
-  }
 
   // Show end page.
   install_complete($profile);
@@ -125,7 +118,7 @@
     $db_port = isset($url['port']) ? urldecode($url['port']) : '';
     $db_path = ltrim(urldecode($url['path']), '/');
     $settings_file = './'. conf_path() .'/settings.php';
-
+    
     _install_settings_form_validate($db_prefix, $db_type, $db_user, $db_pass, $db_host, $db_port, $db_path, $settings_file);
     if (!form_get_errors()) {
       return TRUE;
@@ -313,11 +306,12 @@
   // Check for default username/password
   if ($db_user == 'username' && $db_pass == 'password') {
     form_set_error('db_user', st('You have configured @drupal to use the default username and password. This is not allowed for security reasons.', array('@drupal' => drupal_install_profile_name())));
+    die("name error");
   }
 
   // Verify the table prefix
-  if (!empty($db_prefix) && is_string($db_prefix) && !preg_match('/^[A-Za-z0-9_.]+$/', $db_prefix)) {
-    form_set_error('db_prefix', st('The database table prefix you have entered, %db_prefix, is invalid. The table prefix can only contain alphanumeric characters, underscores or dots.', array('%db_prefix' => $db_prefix)), 'error');
+  if (!empty($db_prefix) && is_string($db_prefix) && preg_match('/[^A-Za-z0-9_]/', $db_prefix)) {
+    form_set_error('db_prefix', st('The database table prefix you have entered, %db_prefix, is invalid. The table prefix can only contain alphanumeric characters and underscores.', array('%db_prefix' => $db_prefix)), 'error');
   }
 
   if (!empty($db_port) && !is_numeric($db_port)) {
@@ -368,6 +362,7 @@
     'value'    => $form_values['db_prefix'],
     'required' => TRUE,
   );
+  
   drupal_rewrite_settings($settings);
 
   // Continue to install profile step
@@ -381,6 +376,7 @@
  *   The selected profile.
  */
 function install_select_profile() {
+  include_once './includes/file.inc';
   include_once './includes/form.inc';
 
   $profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
@@ -544,12 +540,7 @@
   $function = $profile .'_profile_final';
   if (function_exists($function)) {
     // More steps required
-    $profile_message = $function();
-  }
-
-  // If the profile returned a welcome message, use that instead of default.
-  if (isset($profile_message)) {
-    $output .= $profile_message;
+    $output .= $function();
   }
   else {
     // No more steps
Index: modules/aggregator/aggregator.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v
retrieving revision 1.8
diff -u -r1.8 aggregator.install
--- modules/aggregator/aggregator.install	26 Sep 2006 14:19:00 -0000	1.8
+++ modules/aggregator/aggregator.install	31 Mar 2007 14:07:44 -0000
@@ -113,6 +113,50 @@
       db_query("CREATE INDEX {aggregator_item}_fid_idx ON {aggregator_item} (fid)");
 
       break;
+    
+    case 'mssql':
+      db_query("CREATE TABLE aggregator_category (
+                cid int NOT NULL identity(1,1),
+                title varchar(255) unique NOT NULL default '',
+                description varchar(1024) NOT NULL,
+                block int NOT NULL default '0',
+                PRIMARY KEY (cid)
+              );");
+      db_query("CREATE TABLE aggregator_category_feed (
+                fid int NOT NULL default '0',
+                cid int NOT NULL default '0',
+                PRIMARY KEY (fid,cid)
+              );");
+      db_query("CREATE TABLE aggregator_category_item (
+                iid int NOT NULL default '0',
+                cid int NOT NULL default '0',
+                PRIMARY KEY (iid,cid)
+              );");
+      db_query("CREATE TABLE aggregator_feed (
+                fid int NOT NULL identity(1,1),
+                title varchar(255) unique NOT NULL default '',
+                url varchar(255) NOT NULL default '',
+                refresh int NOT NULL default '0',
+                checked int NOT NULL default '0',
+                link varchar(255) unique NOT NULL default '',
+                description varchar(1024) NOT NULL,
+                image varchar(1024) NOT NULL,
+                etag varchar(255) NOT NULL default '',
+                modified int NOT NULL default '0',
+                block int NOT NULL default '0',
+                PRIMARY KEY (fid)
+              );");
+      db_query("CREATE TABLE aggregator_item (
+                iid int NOT NULL identity(1,1),
+                fid int NOT NULL default '0',
+                title varchar(255) NOT NULL default '',
+                link varchar(255) NOT NULL default '',
+                author varchar(255) NOT NULL default '',
+                description varchar(1024) NOT NULL,
+                timestamp int default NULL,
+                PRIMARY KEY (iid)
+              );");
+      break;
   }
 }
 
Index: modules/forum/forum.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.install,v
retrieving revision 1.6
diff -u -r1.6 forum.install
--- modules/forum/forum.install	1 Sep 2006 07:40:08 -0000	1.6
+++ modules/forum/forum.install	31 Mar 2007 14:07:44 -0000
@@ -27,6 +27,14 @@
       db_query("CREATE INDEX {forum}_nid_idx ON {forum} (nid)");
       db_query("CREATE INDEX {forum}_tid_idx ON {forum} (tid)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {forum} (
+        nid int  NOT NULL default '0',
+        vid int  NOT NULL default '0',
+        tid int  NOT NULL default '0',
+        PRIMARY KEY (vid)
+      );");
+      break;
   }
 }
 
Index: modules/statistics/statistics.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.install,v
retrieving revision 1.7
diff -u -r1.7 statistics.install
--- modules/statistics/statistics.install	7 Nov 2006 22:27:07 -0000	1.7
+++ modules/statistics/statistics.install	31 Mar 2007 14:07:44 -0000
@@ -37,6 +37,20 @@
       )");
       db_query("CREATE INDEX {accesslog}_accesslog_timestamp_idx ON {accesslog} (timestamp)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {accesslog} (
+        aid int NOT NULL identity(1,1),
+        sid varchar(32) NOT NULL default '',
+        title varchar(255) default NULL,
+        path varchar(255) default NULL,
+        url varchar(255) default NULL,
+        hostname varchar(128) default NULL,
+        uid int  default '0',
+        timer int  NOT NULL default '0',
+        timestamp int  NOT NULL default '0',
+        PRIMARY KEY (aid)
+      );");
+      break;
   }
 }
 
Index: modules/drupal/drupal.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/drupal/drupal.install,v
retrieving revision 1.5
diff -u -r1.5 drupal.install
--- modules/drupal/drupal.install	1 Sep 2006 07:40:08 -0000	1.5
+++ modules/drupal/drupal.install	31 Mar 2007 14:07:44 -0000
@@ -53,6 +53,29 @@
         PRIMARY KEY (cid,name)
       )");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE client (
+        cid int  NOT NULL identity(1,1),
+        link varchar(255) NOT NULL default '',
+        name varchar(128) NOT NULL default '',
+        mail varchar(128) NOT NULL default '',
+        slogan varchar(1024) NOT NULL,
+        mission varchar(1024) NOT NULL,
+        users int NOT NULL default '0',
+        nodes int NOT NULL default '0',
+        version varchar(35) NOT NULL default'',
+        created int NOT NULL default '0',
+        changed int NOT NULL default '0',
+        PRIMARY KEY (cid)
+      );
+      ");
+      db_query("CREATE TABLE client_system (
+        cid int NOT NULL default '0',
+        name varchar(255) NOT NULL default '',
+        type varchar(255) NOT NULL default '',
+        PRIMARY KEY (cid,name)
+      );");
+      break;
   }
 }
 
Index: modules/search/search.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.install,v
retrieving revision 1.6
diff -u -r1.6 search.install
--- modules/search/search.install	1 Sep 2006 07:40:08 -0000	1.6
+++ modules/search/search.install	31 Mar 2007 14:07:44 -0000
@@ -59,6 +59,26 @@
         PRIMARY KEY (word)
       )");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {search_dataset} (
+        sid int  NOT NULL default '0',
+        type varchar(16) default NULL,
+        data varchar(1024) NOT NULL
+      );");
+      db_query("CREATE TABLE {search_index} (
+        word varchar(50) NOT NULL default '',
+        sid int  NOT NULL default '0',
+        type varchar(16) default NULL,
+        fromsid int  NOT NULL default '0',
+        fromtype varchar(16) default NULL,
+        score float default NULL
+      );");
+      db_query("CREATE TABLE {search_total} (
+        word varchar(50) NOT NULL default '',
+        count float default NULL,
+        PRIMARY KEY (word)
+      );");
+      break;
   }
 }
 
Index: modules/poll/poll.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.install,v
retrieving revision 1.7
diff -u -r1.7 poll.install
--- modules/poll/poll.install	1 Sep 2006 07:40:08 -0000	1.7
+++ modules/poll/poll.install	31 Mar 2007 14:07:44 -0000
@@ -64,6 +64,27 @@
       )");
       db_query("CREATE INDEX {poll_choices}_nid_idx ON {poll_choices} (nid)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {poll} (
+          nid int  NOT NULL default '0',
+          runtime int NOT NULL default '0',
+          active int  NOT NULL default '0',
+          PRIMARY KEY (nid)
+        );");
+      db_query("CREATE TABLE {poll_votes} (
+        nid int  NOT NULL,
+        uid int  NOT NULL default 0,
+        hostname varchar(128) NOT NULL default ''
+      );");
+      db_query("CREATE TABLE {poll_choices} (
+        chid int  NOT NULL identity(1,1),
+        nid int  NOT NULL default '0',
+        chtext varchar(128) NOT NULL default '',
+        chvotes int NOT NULL default '0',
+        chorder int NOT NULL default '0',
+        PRIMARY KEY (chid)
+      );");
+      break;
   }
 }
 
Index: modules/book/book.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.install,v
retrieving revision 1.6
diff -u -r1.6 book.install
--- modules/book/book.install	1 Sep 2006 07:40:08 -0000	1.6
+++ modules/book/book.install	31 Mar 2007 14:07:44 -0000
@@ -29,6 +29,15 @@
       db_query("CREATE INDEX {book}_nid_idx ON {book} (nid)");
       db_query("CREATE INDEX {book}_parent_idx ON {book} (parent)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {book} (
+                vid int  NOT NULL default '0',
+                nid int  NOT NULL default '0',
+                parent int NOT NULL default '0',
+                weight int NOT NULL default '0',
+                PRIMARY KEY (vid)
+              );");
+      break;
   }
 }
 
Index: modules/locale/locale.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v
retrieving revision 1.7
diff -u -r1.7 locale.install
--- modules/locale/locale.install	14 Nov 2006 06:20:40 -0000	1.7
+++ modules/locale/locale.install	31 Mar 2007 14:07:44 -0000
@@ -73,7 +73,33 @@
       db_query("CREATE INDEX {locales_target}_plural_idx ON {locales_target} (plural)");
       db_query("CREATE INDEX {locales_source}_source_idx ON {locales_source} (source)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {locales_meta} (
+        locale varchar(12) NOT NULL default '',
+        name varchar(64) NOT NULL default '',
+        enabled int NOT NULL default '0',
+        isdefault int NOT NULL default '0',
+        plurals int NOT NULL default '0',
+        formula varchar(128) NOT NULL default '',
+        PRIMARY KEY (locale)
+      );");
+      db_query("CREATE TABLE {locales_source} (
+        lid int NOT NULL identity(1,1),
+        location varchar(255) NOT NULL default '',
+        source varchar(max) NOT NULL,
+        PRIMARY KEY (lid)
+      );");
+      db_query("CREATE TABLE {locales_target} (
+        lid int NOT NULL default '0',
+        translation varchar(max) NOT NULL,
+        locale varchar(12) NOT NULL default '',
+        plid int NOT NULL default '0',
+        plural int NOT NULL default '0',
+      );");
+      break;
   }
+  
+  
   db_query("INSERT INTO {locales_meta} (locale, name, enabled, isdefault) VALUES ('en', 'English', '1', '1')");
 }
 
Index: modules/profile/profile.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.install,v
retrieving revision 1.8
diff -u -r1.8 profile.install
--- modules/profile/profile.install	28 Nov 2006 14:37:44 -0000	1.8
+++ modules/profile/profile.install	31 Mar 2007 14:07:44 -0000
@@ -64,6 +64,29 @@
       db_query("CREATE INDEX {profile_values}_uid_idx ON {profile_values} (uid)");
       db_query("CREATE INDEX {profile_values}_fid_idx ON {profile_values} (fid)");
       break;
+    case 'mssql':
+      db_query("CREATE TABLE {profile_fields} (
+        fid int NOT NULL identity(1,1),
+        title varchar(255) default NULL,
+        name varchar(128) unique default NULL,
+        explanation TEXT default NULL,
+        category varchar(255) default NULL,
+        page varchar(255) default NULL,
+        type varchar(128) default NULL,
+        weight int DEFAULT '0' NOT NULL,
+        required int DEFAULT '0' NOT NULL,
+        register int DEFAULT '0' NOT NULL,
+        visibility int DEFAULT '0' NOT NULL,
+        autocomplete int DEFAULT '0' NOT NULL,
+        options text,
+        PRIMARY KEY (fid)
+      );");
+      db_query("CREATE TABLE {profile_values} (
+        fid int  default '0',
+        uid int  default '0',
+        value text
+      );");
+      break;
   }
 }
 
Index: includes/install.mssql.inc
===================================================================
RCS file: includes/install.mssql.inc
diff -N includes/install.mssql.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/install.mssql.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,139 @@
+<?php
+// $Id: $
+
+// MS SQL specific install functions
+
+/**
+ * Check if MS SQL is available.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function mssql_is_available() {
+  return function_exists('mssql_connect');
+}
+
+/**
+ * Check if we can connect to MS SQL.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function drupal_test_mssql($url, &$success) {
+  if (!mssql_is_available()) {
+    drupal_set_message('PHP MS SQL support not enabled.', 'error');
+    return FALSE;
+  }
+
+  $url = parse_url($url);
+
+  // Decode url-encoded information in the db connection string.
+  $url['user'] = urldecode($url['user']);
+  $url['pass'] = urldecode($url['pass']);
+  $url['host'] = stripslashes(urldecode($url['host']));
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard MS SQL port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .','. $url['port'];
+  }
+
+  // Test connecting to the database.
+  $connection = mssql_connect($url['host'], $url['user'], $url['pass']);
+  if (!$connection) {
+    drupal_set_message(st('Failure to connect to your MS SQL database server. MS SQL reports the following message: %error.<ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct database hostname?</li><li>Are you sure that the database server is running?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%error' => $php_errormsg)), 'error');
+    return FALSE;
+  }
+
+  // Test selecting the database.
+  if (!mssql_select_db(substr($url['path'], 1))) {
+    drupal_set_message(st('We were able to connect to the MS SQL database server (which means your username and password are valid) but not able to select your database. MS SQL reports the following message: %error.<ul><li>Are you sure you have the correct database name?</li><li>Are you sure the database exists?</li><li>Are you sure the username has permission to access the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%error' => mssql_get_last_message())), 'error');
+    return FALSE;
+  }
+
+  $success = array('CONNECT');
+
+  // Test CREATE.
+  $query = 'CREATE TABLE drupal_install_test (id int NULL)';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to create a test table on your MS SQL database server with the command %query. MS SQL reports the following message: %error.<ul><li>Are you sure the configured username has the necessary MS SQL permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    return FALSE;
+  }
+  $err = FALSE;
+  $success[] = 'SELECT';
+  $success[] = 'CREATE';
+
+  // Test INSERT.
+  $query = 'INSERT INTO drupal_install_test (id) VALUES (1)';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to insert a value into a test table on your MS SQL database server. We tried inserting a value with the command %query and MS SQL reported the following error: %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'INSERT';
+  }
+
+  // Test UPDATE.
+  $query = 'UPDATE drupal_install_test SET id = 2';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to update a value in a test table on your MS SQL database server. We tried updating a value with the command %query and MS SQL reported the following error: %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UPDATE';
+  }
+
+  // Test LOCK.
+  $query = 'BEGIN TRANSACTION';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to lock a test table on your MS SQL database server. We tried locking a table with the command %query and MS SQL reported the following error: %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'LOCK';
+  }
+
+  // Test UNLOCK.
+  $query = 'COMMIT TRANSACTION';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to unlock a test table on your MS SQL database server. We tried unlocking a table with the command %query and MS SQL reported the following error: %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UNLOCK';
+  }
+
+  // Test DELETE.
+  $query = 'DELETE FROM drupal_install_test';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to delete a value from a test table on your MS SQL database server. We tried deleting a value with the command %query and MS SQL reported the following error: %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DELETE';
+  }
+
+  // Test DROP.
+  $query = 'DROP TABLE drupal_install_test';
+  $result = mssql_query($query);
+  if ($result === FALSE) {
+    drupal_set_message(st('We were unable to drop a test table from your MS SQL database server. We tried dropping a table with the command %query and MS SQL reported the following error %error.', array('%query' => $query, '%error' => $php_errormsg)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DROP';
+  }
+
+  if ($err) {
+    return FALSE;
+  }
+
+  mssql_close($connection);
+  return TRUE;
+}
Index: includes/database.mssql.inc
===================================================================
RCS file: includes/database.mssql.inc
diff -N includes/database.mssql.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/database.mssql.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,616 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Database interface code for Microsoft SQL database servers.
+ * 
+ * $connection = mssql_connect('\\\\.\pipe\MSSQL$SQLEXPRESS\sql\query', 'sa', 'pw');
+ */
+
+/**
+ * @ingroup database
+ * @{
+ */
+
+
+/**
+ * Report database status.
+ */
+function db_status_report($phase) {
+  $t = get_t();
+
+  $version = db_version();
+
+  $form['mysql'] = array(
+    'title' => $t('MS SQL database'),
+    'value' => ($phase == 'runtime') ? l($version, 'admin/logs/status/sql') : $version,
+  );
+
+  /*if (version_compare($version, DRUPAL_MINIMUM_MSSQL) < 0) {
+    $form['mysql']['severity'] = REQUIREMENT_ERROR;
+    $form['mysql']['description'] = $t('Your MS SQL Server is too old. Drupal requires at least MS SQL %version.', array('%version' => DRUPAL_MINIMUM_MSSQL));
+  }*/
+
+  return $form;
+}
+
+/**
+ * Returns the version of the database server currently in use.
+ *
+ * @return Database server version
+ */
+function db_version() {
+  $version = db_result(db_query('SELECT @@version;'));
+  list($version) = explode('-', $version);
+  return $version;
+}
+
+/**
+ * Initialize a database connection.
+ *
+ * Note that you can change the mysql_connect() call to mysql_pconnect() if you
+ * want to use persistent connections. This is not recommended on shared hosts,
+ * and might require additional database/webserver tuning. It can increase
+ * performance, however, when the overhead to connect to your database is high
+ * (e.g. your database and web server live on different machines).
+ */
+function db_connect($url) {
+  // Check if MS SQL support is present in PHP
+  if (!function_exists('mssql_connect')) {
+    drupal_maintenance_theme();
+    drupal_set_title('PHP MS SQL support not enabled');
+    print theme('maintenance_page', '<p>We were unable to use the MS SQL database because the MS SQL extension for PHP is not installed. Check your <code>PHP.ini</code> to see how you can enable it.</p>
+<p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>');
+    exit;
+  }
+
+  $url = parse_url($url);
+
+  // Decode url-encoded information in the db connection string
+  $url['user'] = urldecode($url['user']);
+  // Test if database url has a password.
+  if(isset($url['pass'])) {
+    $url['pass'] = urldecode($url['pass']);
+  }
+  else {
+    $url['pass'] = '';
+  }
+  $url['host'] = stripslashes(urldecode($url['host']));
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard MS SQL port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .','. $url['port'];
+  }
+
+  // Allow large texts for MS SQL.
+  ini_set("mssql.textlimit", 16000000);
+  ini_set("mssql.textsize", 16000000);
+
+  // TODO: Put back @.
+  $connection = mssql_connect($url['host'], $url['user'], $url['pass']);
+  if (!$connection) {
+    // Redirect to installer if using default DB credentials
+    if ($url['user'] == 'username' && $url['pass'] == 'password') {
+      include_once 'includes/install.inc';
+      install_goto('install.php');
+    }
+
+    // Show error screen otherwise
+    drupal_maintenance_theme();
+    drupal_set_header('HTTP/1.1 503 Service Unavailable');
+    drupal_set_title('Unable to connect to database server');
+    print theme('maintenance_page', '<p>If you still have to install Drupal, proceed to the <a href="'. base_path() .'install.php">installation page</a>.</p>
+<p>If you have already finished installed Drupal, this either means that the username and password information in your <code>settings.php</code> file is incorrect or that we can\'t connect to the MS SQL database server. This could mean your hosting provider\'s database server is down.</p>
+<p>The MS SQL error was: '. theme('placeholder', mssql_get_last_message()) .'.</p>
+<p>Currently, the username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p>
+<ul>
+  <li>Are you sure you have the correct username and password?</li>
+  <li>Are you sure that you have typed the correct hostname?</li>
+  <li>Are you sure that the database server is running?</li>
+</ul>
+<p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>');
+    exit;
+  }
+
+  if (!mssql_select_db(substr($url['path'], 1))) {
+    drupal_maintenance_theme();
+    drupal_set_title('Unable to select database');
+    print theme('maintenance_page', '<p>We were able to connect to the MS SQL database server (which means your username and password are okay) but not able to select the database.</p>
+<p>The MS SQL error was: '. theme('placeholder', mssql_get_last_message()) .'.</p>
+<p>Currently, the database is '. theme('placeholder', substr($url['path'], 1)) .'. The username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p>
+<ul>
+  <li>Are you sure you have the correct database name?</li>
+  <li>Are you sure the database exists?</li>
+  <li>Are you sure the username has permission to access the database?</li>
+</ul>
+<p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>');
+    exit;
+  }
+
+  // TODO: Document this. Not sure what this does.
+  // Maximum returnable text size
+  mssql_query('SET TEXTSIZE 524287;');
+
+  return $connection;
+}
+
+/**
+ * Helper function for db_query().
+ */
+function _db_query($query, $debug = 0) {
+  global $active_db, $queries, $user, $base_root;
+  global $temp_tables;
+  static $last_error_msg;
+  
+  // First prefix temp tables with # that have been created during this session
+  $query = str_replace($temp_tables['base_name'], $temp_tables['temp_name'], $query);
+
+
+  if (variable_get('dev_query', 0)) {
+    list($usec, $sec) = explode(' ', microtime());
+    $timer = (float)$usec + (float)$sec;
+  }
+
+  // LENGTH is called DATALENGTH in MS SQL.
+  // TODO: Preg search instead of strpos.
+  if(strpos($query,"LENGTH")){
+    $pattern = '/(.+)LENGTH(.+)/i';
+    $query = preg_replace($pattern, '${1}DATALENGTH$2', $query); 
+  }
+  // No LIMIT in MS SQL. We use SELECT TOP n ... FROM ...
+  // Can't do TOP because it is NOT a range.
+  // TODO: Preg search instead of strpos.
+  if(strpos($query,'LIMIT')){
+    $pattern = '/(.+)LIMIT (\d+), (\d+)/i';
+    $query_new = preg_replace($pattern, '${1}', $query);
+    $limit = preg_replace($pattern, '$3', $query);
+    $query = str_replace('SELECT', 'SELECT TOP '.$limit, $query_new);
+    unset($pattern, $query_new, $limit);
+  }
+  // TODO: Not sure what this is. 
+  // TODO: Preg search instead of strpos so we don't replace valid instances of 'relevance'.
+  if(strpos($query,'relevance')){
+    $query = str_replace('relevance', '_relevance', $query_new);
+  }
+  
+  /**
+   * // TODO Fix this big issue
+   * NOTE: Sending the query again is currently in here
+   * becuase for some reason, on certain pages, no result is
+   * returned from SQL-Server even though the qurey is fine.
+   * To prove this, try putting this in the error log after
+   * querying the result. You'll see that 'SELECT * FROM system WHERE type = 'theme'
+   * returns nothing, even though every query before it is fine:
+   * error_log("\n" . $tquery . " and result: " . $result);
+   * 
+   */
+  $result = @mssql_query($query, $active_db);
+
+  
+  if(!$result && $active_db && function_exists("arg")) {
+    trigger_error(check_plain(mssql_get_last_message() ."\nquery: ". $query), E_USER_WARNING);
+    @watchdog('mssql', mssql_get_last_message($active_db) . "<br />SQL:<br />" . $query, WATCHDOG_ERROR);
+  }
+  
+  if (variable_get('dev_query', 0) && false) {
+    $bt = debug_backtrace();
+    $query = $bt[2]['function'] . "\n" . $query;
+    list($usec, $sec) = explode(' ', microtime());
+    $stop = (float)$usec + (float)$sec;
+    $diff = $stop - $timer;
+    $queries[] = array($query, $diff);
+  }
+
+  if ($debug) {
+    print '<p>query: '. $query .'<br />error:'. mssql_get_last_message() .'</p>';
+  }
+  unset($query);
+  return $result;
+}
+
+/**
+ * Given a table name, this tries to locate the primay key.
+ * If no primary key is found, it returns the first column
+ * with an index. If no index is found, it returns FALSE.
+ * 
+ * TODO: Check the cardinatliy, perhaps you could return
+ * the index with the least cardinality for speed.
+ * Filter by schema!!!
+ */
+function _db_mssql_locate_table_index($table) {
+  # Get the table_id
+  $index_column = FALSE;
+  $table = trim($table);
+  $table_id = db_result(db_query("SELECT object_id FROM sys.tables WHERE type_desc = 'USER_TABLE' AND name = '%s'", $table));
+  if(!$table_id) {
+    return $index_column;
+  }
+  # Look at the index_columns sys table
+  $index_id = db_result(db_query("SELECT TOP 1 column_id FROM sys.index_columns WHERE object_id = '%d'", $table_id));
+  if(!$index_id) {
+    return $index_column;
+  }
+  # Grab the column name
+  $index_column = db_result(db_query("SELECT name FROM sys.columns WHERE object_id = %d AND column_id = %d;", $table_id, $index_id));
+  
+  return $index_column;
+}
+
+/**
+ * @author Earnest Berry III <earnest.berry@gmail.com>
+ * @abstract
+ * Please note that in the db_fetch_object and 
+ * the db_fetch_array functions, there is a trimming 
+ * loop to counter act PHP bugs:
+ * http://bugs.php.net/bug.php?id=26996
+ * http://bugs.php.net/bug.php?id=26996
+ * This breaks things like menu.inc (_menu_translate) that 
+ * use the actual value of the variable for TRUE/FALSE, meaning
+ * that ' ' (phantom space) returns true when menu.inc 
+ * expects '', which would be false. Either the bug in PHP 
+ * needs to be fixed, or the logic fixed up in menu.inc so that 
+ * it checks for datatypes (e.g. trim($item->val) != '') 
+ * and doesn't use a side effect for 
+ * evaluation.
+ */
+
+
+/**
+ * Fetch one result row from the previous query as an object.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   An object representing the next row of the result. The attributes of this
+ *   object are the table fields selected by the query.
+ */
+function db_fetch_object($result) {
+  if ($result) {
+    if($tobj =  mssql_fetch_object($result)) {
+      foreach($tobj as $k => $v) {
+        $tobj->$k = trim($v);
+      }
+    }
+    return $tobj;
+  }
+}
+
+/**
+ * Fetch one result row from the previous query as an array.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   An associative array representing the next row of the result. The keys of
+ *   this object are the names of the table fields selected by the query, and
+ *   the values are the field values for this result row.
+ */
+function db_fetch_array($result) {
+  if ($result) {
+    $tarray =  mssql_fetch_array($result, MSSQL_ASSOC);
+    foreach($tarray as $k => $v) {
+      $tarray[$k] = trim($v);
+    }
+    return $tarray;
+  }
+}
+
+/**
+ * Determine how many result rows were found by the preceding query.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   The number of result rows.
+ */
+function db_num_rows($result) {
+  if ($result) {
+    return mssql_num_rows($result);
+  }
+}
+
+/**
+ * Return an individual result field from the previous query.
+ *
+ * Only use this function if exactly one field is being selected; otherwise,
+ * use db_fetch_object() or db_fetch_array().
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @param $row
+ *   The index of the row whose result is needed.
+ * @return
+ *   The resulting field.
+ */
+function db_result($result, $row = 0) {
+  if ($result && mssql_num_rows($result) > $row) {
+    mssql_data_seek($result, $row);
+    $row_result = mssql_fetch_row($result);
+    return $row_result[0];
+  }
+}
+
+/**
+ * Determine whether the previous query caused an error.
+ */
+function db_error() {
+  return mssql_get_last_message();
+}
+
+/**
+ * Return a new unique ID in the given sequence.
+ *
+ * For compatibility reasons, Drupal does not use auto-numbered fields in its
+ * database tables. Instead, this function is used to return a new unique ID
+ * of the type requested. If necessary, a new sequence with the given name
+ * will be created.
+ */
+function db_next_id($name) {
+  $name = db_prefix_tables($name);
+  db_lock_table('sequences');
+  $id = db_result(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) + 1;
+  if (db_num_rows(db_query("SELECT id FROM {sequences} WHERE name = '%s'", $name)) == 0) {
+    db_query("INSERT INTO {sequences} VALUES ('%s', %d)", $name, $id);
+  }
+  else {
+    db_query("UPDATE {sequences} SET id = %d WHERE name = '%s'", $id, $name);
+  }
+  db_unlock_tables();
+
+  return $id;
+}
+
+/**
+ * Determine the number of rows changed by the preceding query.
+ */
+function db_affected_rows() {
+  global $active_db;
+  $result = mssql_query('SELECT @@ROWCOUNT', $active_db);
+  list($affected) = mssql_fetch_row($result);
+  return $affected;
+}
+
+/**
+ * Runs a limited-range query in the active database.
+ *
+ * Use this as a substitute for db_query() when a subset of the query is to be
+ * returned.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * Note that if you need to know how many results were returned, you should do
+ * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and
+ * db_affected_rows() do not give consistent result across different database
+ * types in this case.
+ *
+ * @param $query
+ *   A string containing an SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $from
+ *   The first result row to return.
+ * @param $count
+ *   The maximum number of result rows to return.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_range($query) {
+  $args = func_get_args();
+  
+  $count = array_pop($args);
+  $from = array_pop($args);
+  $to = $from + $count;
+  array_shift($args);
+  
+  if(is_array($args[0])) {
+    $args = array_shift($args);
+  }
+  
+  // TODO Implement
+  // $col = _db_mssql_locate_table_index($table);
+  
+  if($from == 0) {
+    $query = str_replace("SELECT ", "SELECT TOP($to) ", $query);
+  }
+  else {
+    $matches = array();
+  
+    $re = '/SELECT\s*([a-zA-Z0-9.*, \'\n_={}()]+)\s*FROM\s*([a-zA-Z.*, =\'_{}]+)\s*';
+    $loc = 2;
+    if(preg_match('/WHERE/', $query)) {
+      $re .= 'WHERE\s*([%_\'a-zA-Z0-9.*, =><\(\)()]+)\s*';
+      $lwhere = ++$loc;
+    }
+    if(preg_match('/GROUP BY/', $query)) {
+      $re .= 'GROUP BY\s*([a-zA-Z.*, ]+)\s*';
+      $lgroup_by = ++$loc;
+    }
+    if(preg_match('/ORDER BY/', $query)) {
+      $re .= 'ORDER BY\s*([a-zA-Z.*, ]+)';
+      $lorder_by = ++$loc;
+    }
+    $re .= '/';
+    preg_match($re, $query, $matches);
+    
+    $select = $matches[1];
+    $qfrom = $matches[2];
+    $where = $group_by = $order_by = '';
+    if(isset($lwhere)) {
+      $where = 'WHERE ' . $matches[$lwhere];
+    }
+    if(isset($lgroup_by)) {
+      $group_by = 'GROUP BY ' . $matches[$lgroup_by];
+    }
+    if(isset($lorder_by)) {
+      $order_by = 'ORDER BY ' . $matches[$lorder_by];
+    }
+    else {
+      $order_by = 'ORDER BY @@SPID';
+    }
+  
+    $query = "SELECT * FROM (
+                SELECT 
+                  ROW_NUMBER() OVER($order_by) AS rownumber,
+                  $select
+                  FROM $qfrom
+                  $where
+              ) as drupal_range_query
+              WHERE rownumber BETWEEN $from AND $to;";
+    
+  }
+  _db_query_callback($args, TRUE);
+  $query = db_prefix_tables($query);
+  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+  
+  return _db_query($query);
+}
+
+/**
+ * Runs a SELECT query and stores its results in a temporary table.
+ *
+ * Use this as a substitute for db_query() when the results need to stored
+ * in a temporary table. Temporary tables exist for the duration of the page
+ * request.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * Note that if you need to know how many results were returned, you should do
+ * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and
+ * db_affected_rows() do not give consistent result across different database
+ * types in this case.
+ *
+ * @param $query
+ *   A string containing a normal SELECT SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $table
+ *   The name of the temporary table to select into. This name will not be
+ *   prefixed as there is no risk of collision.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_temporary($query) {
+  # A global array of temporary tables
+  global $temp_tables;
+  $args = func_get_args();
+  $tablename = array_pop($args);
+  array_shift($args);
+
+  $split_query = explode('FROM', db_prefix_tables($query));
+  $from = $split_query[1];
+  $fields = $split_query[0];
+  //$query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' SELECT', db_prefix_tables($query));
+  $query = "$fields INTO #$tablename FROM $from";
+  $temp_tables['base_name'] = $tablename;
+  $temp_tables['temp_name'] = "#$tablename";
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  _db_query_callback($args, TRUE);
+  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+  return _db_query($query);
+}
+
+/**
+ * Returns a properly formatted Binary Large OBject value.
+ *
+ * @param $data
+ *   Data to encode.
+ * @return
+ *  Encoded data.
+ */
+function db_encode_blob($data) {
+  global $active_db;
+  return "'" . base64_encode($data) . "'";
+}
+
+/**
+ * Returns text from a Binary Large Object value.
+ *
+ * @param $data
+ *   Data to decode.
+ * @return
+ *  Decoded data.
+ */
+function db_decode_blob($data) {
+  return base64_decode($data);
+}
+
+/**
+ * Prepare user input for use in a database query, preventing SQL injection attacks.
+ */
+function db_escape_string($text) {
+  // TODO: Use proper function here for db escaping.
+  // Above 'TODO' solved by below.
+  // Souvent22
+  // Taken from php.net 
+  // vollmer at ampache dot org
+  /* De MagicQuotes */
+  
+  $text = str_replace("'","''",$text);
+  $text = str_replace("\0","[NULL]",$text);
+  return $text;
+}
+
+/**
+ * Lock a table.
+ */
+function db_lock_table($table = "") {
+  db_query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
+  db_query('BEGIN TRANSACTION');
+}
+
+/**
+ * Unlock all locked tables.
+ */
+function db_unlock_tables() {
+  db_query('COMMIT');
+}
+
+/**
+ * Check if a table exists.
+ */
+function db_table_exists($table) {
+  return db_num_rows(db_query("SHOW TABLES LIKE '{" . db_escape_table($table) . "}'"));
+}
+
+/**
+ * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to
+ * the SELECT list entry of the given query and the resulting query is returned.
+ * This function only applies the wrapper if a DISTINCT doesn't already exist in
+ * the query.
+ *
+ * @param $table Table containing the field to set as DISTINCT
+ * @param $field Field to set as DISTINCT
+ * @param $query Query to apply the wrapper to
+ * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
+ */
+function db_distinct_field($table, $field, $query) {
+  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
+  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
+  return preg_replace('/(SELECT.*)('. $table .'\.)?(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1'. $field_to_select .'\3', $query);
+}
+
+/**
+ * @} End of "ingroup database".
+ */
