Index: wp-signup.php
===================================================================
--- wp-signup.php	(revision 21496)
+++ wp-signup.php	(working copy)
@@ -394,7 +394,7 @@
 		$proto = 'https://';
 	else
 		$proto = 'http://';
-	$login_url = site_url( 'wp-login.php?redirect_to=' . urlencode($proto . $_SERVER['HTTP_HOST'] . '/wp-signup.php' ));
+	$login_url = site_url( 'wp-login.php?redirect_to=' . urlencode( network_site_url( 'wp-signup.php' ) ) );
 	echo sprintf( __( 'You must first <a href="%s">log in</a>, and then you can create a new site.' ), $login_url );
 } else {
 	$stage = isset( $_POST['stage'] ) ?  $_POST['stage'] : 'default';
Index: wp-login.php
===================================================================
--- wp-login.php	(revision 21496)
+++ wp-login.php	(working copy)
@@ -509,7 +509,7 @@
 case 'register' :
 	if ( is_multisite() ) {
 		// Multisite uses wp-signup.php
-		wp_redirect( apply_filters( 'wp_signup_location', site_url('wp-signup.php') ) );
+		wp_redirect( apply_filters( 'wp_signup_location', network_site_url('wp-signup.php') ) );
 		exit;
 	}
 
Index: wp-includes/link-template.php
===================================================================
--- wp-includes/link-template.php	(revision 21496)
+++ wp-includes/link-template.php	(working copy)
@@ -1964,11 +1964,14 @@
 			$scheme = ( is_ssl() ? 'https' : 'http' );
 	}
 
-	if ( empty( $blog_id ) || !is_multisite() ) {
-		$url = get_option( 'siteurl' );
+	if ( empty( $blog_id ) ) {
+		if ( is_multisite() )
+			$url = get_option( 'home' );
+		else
+			$url = get_option( 'siteurl' );
 	} else {
 		switch_to_blog( $blog_id );
-		$url = get_option( 'siteurl' );
+		$url = get_option( 'home' );
 		restore_current_blog();
 	}
 
Index: wp-includes/rewrite.php
===================================================================
--- wp-includes/rewrite.php	(revision 21496)
+++ wp-includes/rewrite.php	(working copy)
@@ -1726,75 +1726,17 @@
 		<rewrite>
 			<rules>';
 		}
-		if ( !is_multisite() ) {
-			$rules .= '
-				<rule name="wordpress" patternSyntax="Wildcard">
-					<match url="*" />
-						<conditions>
-							<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
-							<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
-						</conditions>
-					<action type="Rewrite" url="index.php" />
-				</rule>';
-		} else {
-			if (is_subdomain_install()) {
-				$rules .= '
-				<rule name="wordpress - Rule 1" stopProcessing="true">
-					<match url="^index\.php$" ignoreCase="false" />
-					<action type="None" />
-				</rule>
-				<rule name="wordpress - Rule 2" stopProcessing="true">
-					<match url="^files/(.+)" ignoreCase="false" />
-					<action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
-				</rule>
-				<rule name="wordpress - Rule 3" stopProcessing="true">
-					<match url="^" ignoreCase="false" />
-					<conditions logicalGrouping="MatchAny">
-						<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
-						<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
+
+		$rules .= '
+			<rule name="wordpress" patternSyntax="Wildcard">
+				<match url="*" />
+					<conditions>
+						<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
+						<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
 					</conditions>
-					<action type="None" />
-				</rule>
-				<rule name="wordpress - Rule 4" stopProcessing="true">
-					<match url="." ignoreCase="false" />
-					<action type="Rewrite" url="index.php" />
-				</rule>';
-			} else {
-				$rules .= '
-				<rule name="wordpress - Rule 1" stopProcessing="true">
-					<match url="^index\.php$" ignoreCase="false" />
-					<action type="None" />
-				</rule>
-				<rule name="wordpress - Rule 2" stopProcessing="true">
-					<match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
-					<action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
-				</rule>
-				<rule name="wordpress - Rule 3" stopProcessing="true">
-					<match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
-					<action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
-				</rule>
-				<rule name="wordpress - Rule 4" stopProcessing="true">
-					<match url="^" ignoreCase="false" />
-					<conditions logicalGrouping="MatchAny">
-						<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
-						<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
-					</conditions>
-					<action type="None" />
-				</rule>
-				<rule name="wordpress - Rule 5" stopProcessing="true">
-					<match url="^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*)" ignoreCase="false" />
-					<action type="Rewrite" url="{R:1}" />
-				</rule>
-				<rule name="wordpress - Rule 6" stopProcessing="true">
-					<match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
-					<action type="Rewrite" url="{R:2}" />
-				</rule>
-				<rule name="wordpress - Rule 7" stopProcessing="true">
-					<match url="." ignoreCase="false" />
-					<action type="Rewrite" url="index.php" />
-				</rule>';
-			}
-		}
+				<action type="Rewrite" url="index.php" />
+			</rule>';
+
 		if ( $add_parent_tags ) {
 			$rules .= '
 			</rules>
Index: wp-includes/canonical.php
===================================================================
--- wp-includes/canonical.php	(revision 21496)
+++ wp-includes/canonical.php	(working copy)
@@ -18,7 +18,7 @@
  * one or the other.
  *
  * Prevents redirection for feeds, trackbacks, searches, comment popup, and
- * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7, 
+ * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7,
  * page/post previews, WP admin, Trackbacks, robots.txt, searches, or on POST
  * requests.
  *
@@ -282,7 +282,7 @@
 
 		if ( 'wp-register.php' == basename( $redirect['path'] ) ) {
 			if ( is_multisite() )
-				$redirect_url = apply_filters( 'wp_signup_location', site_url( 'wp-signup.php' ) );
+				$redirect_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) );
 			else
 				$redirect_url = site_url( 'wp-login.php?action=register' );
 			wp_redirect( $redirect_url, 301 );
@@ -517,7 +517,7 @@
 		site_url( 'dashboard', 'relative' ),
 		site_url( 'admin', 'relative' ),
 	);
-	if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins ) ) {
+	if ( parse_url( admin_url( '', 'relative' ), PHP_URL_PATH ) !== $_SERVER['REQUEST_URI'] && in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins ) ) {
 		wp_redirect( admin_url() );
 		exit;
 	}
Index: wp-includes/ms-load.php
===================================================================
--- wp-includes/ms-load.php	(revision 21496)
+++ wp-includes/ms-load.php	(working copy)
@@ -142,6 +142,7 @@
 		$current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1;
 		$current_site->domain = DOMAIN_CURRENT_SITE;
 		$current_site->path   = $path = PATH_CURRENT_SITE;
+
 		if ( defined( 'BLOG_ID_CURRENT_SITE' ) )
 			$current_site->blog_id = BLOG_ID_CURRENT_SITE;
 		elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) // deprecated.
Index: wp-includes/ms-settings.php
===================================================================
--- wp-includes/ms-settings.php	(revision 21496)
+++ wp-includes/ms-settings.php	(working copy)
@@ -86,7 +86,7 @@
 			if ( '%siteurl%' == $destination )
 				$destination = "http://" . $current_site->domain . $current_site->path;
 		} else {
-			$destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
+			$destination = 'http://' . $current_site->domain . $current_site->wp_siteurl_subdir . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
 		}
 		header( 'Location: ' . $destination );
 		die();
Index: wp-includes/ms-functions.php
===================================================================
--- wp-includes/ms-functions.php	(revision 21496)
+++ wp-includes/ms-functions.php	(working copy)
@@ -595,8 +595,8 @@
 		$mydomain = $blogname . '.' . preg_replace( '|^www\.|', '', $domain );
 		$path = $base;
 	} else {
-		$mydomain = "$domain";
-		$path = $base.$blogname.'/';
+		$mydomain = $domain;
+		$path = '/' . join_with_slashes( $base, $blogname ) . '/';
 	}
 	if ( domain_exists($mydomain, $path) )
 		$errors->add('blogname', __('Sorry, that site already exists!'));
@@ -1142,7 +1142,7 @@
 
 	$wpdb->suppress_errors(false);
 
-	$url = get_blogaddress_by_id($blog_id);
+	$homeurl = $siteurl = untrailingslashit( get_blogaddress_by_id( $blog_id ) );
 
 	// Set everything up
 	make_db_current_silent( 'blog' );
@@ -1150,21 +1150,22 @@
 	populate_roles();
 	$wp_roles->_init();
 
-	$url = untrailingslashit( $url );
-	// fix url.
-	update_option('siteurl', $url);
-	update_option('home', $url);
-	update_option('fileupload_url', $url . "/files" );
-	update_option('upload_path', UPLOADBLOGSDIR . "/$blog_id/files");
+	// Maybe fix url
+	if ( defined( 'WP_SITEURL_SUBDIR' ) && WP_SITEURL_SUBDIR )
+		$siteurl = join_with_slashes( $siteurl, WP_SITEURL_SUBDIR );
+
+	update_option('siteurl', $siteurl);
+	update_option('home', $homeurl);
+	update_option('fileupload_url', join_with_slashes( $homeurl, 'files' ) );
+	update_option('upload_path', join_with_slashes( UPLOADBLOGSDIR, $blog_id, 'files' ) );
 	update_option('blogname', stripslashes( $blog_title ) );
 	update_option('admin_email', '');
 	$wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') );
 
 	// remove all perms
-	$wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'user_level' ) );
+	$wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix . 'user_level'   ) );
+	$wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix . 'capabilities' ) );
 
-	$wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'capabilities' ) );
-
 	$wpdb->suppress_errors( false );
 }
 
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 21496)
+++ wp-includes/functions.php	(working copy)
@@ -1434,6 +1434,8 @@
 function wp_upload_dir( $time = null ) {
 	global $_wp_switched;
 	$siteurl = get_option( 'siteurl' );
+	$homeurl = get_option( 'home' );
+	$baseurl = is_multisite() && defined( 'MULTISITE' ) ? $homeurl : $siteurl;
 	$upload_path = get_option( 'upload_path' );
 	$upload_path = trim($upload_path);
 	$main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
@@ -1453,12 +1455,12 @@
 		if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
 			$url = WP_CONTENT_URL . '/uploads';
 		else
-			$url = trailingslashit( $siteurl ) . $upload_path;
+			$url = trailingslashit( $baseurl ) . $upload_path;
 	}
 
 	if ( defined('UPLOADS') && ! $main_override && ! $_wp_switched ) {
 		$dir = ABSPATH . UPLOADS;
-		$url = trailingslashit( $siteurl ) . UPLOADS;
+		$url = trailingslashit( $baseurl ) . UPLOADS;
 	}
 
 	if ( is_multisite() && ! $main_override && ! $_wp_switched  ) {
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 21496)
+++ wp-includes/formatting.php	(working copy)
@@ -1355,6 +1355,46 @@
 }
 
 /**
+ * Removes trailing and leading strings from elements (array), then combines elements
+ * with a string in between each element. Leading and trailing strings should be
+ * manually concatenated.
+ *
+ * @since  3.5.0
+ *
+ * @param  array $parts Items to be combined
+ * @param  string $string String to be used to combine items
+ * @return  string Concatenated parts with given strings in between each element.
+ */
+function join_with_string( $parts, $string ) {
+	$members = array();
+	foreach ( (array) $parts as $part ) {
+		if ( is_array( $part ) ) {
+			foreach ( $part as $member ) {
+				$members[] = trim( $member, $string );
+			}
+		} else {
+			$members[] = trim( $part, $string );
+		}
+	}
+
+	return implode( $string, $members );
+}
+
+/**
+ * Removes trailing and leading slashes from elements (array or string args), then combines elements
+ * with a slash in between each element. Leading and trailing slashes should be
+ * manually concatenated.
+ *
+ * @since  3.5.0
+ *
+ * @return  string Concatenated string with slashes in between each element.
+ */
+function join_with_slashes() {
+	$args = func_get_args();
+	return join_with_string( $args, '/' );
+}
+
+/**
  * Adds slashes to escape strings.
  *
  * Slashes will first be removed if magic_quotes_gpc is set, see {@link
Index: wp-admin/network.php
===================================================================
--- wp-admin/network.php	(revision 21496)
+++ wp-admin/network.php	(working copy)
@@ -51,8 +51,8 @@
  * @return bool Whether subdomain install is allowed
  */
 function allow_subdomain_install() {
-	$domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'siteurl' ) );
-	if( false !== strpos( $domain, '/' ) || 'localhost' == $domain || preg_match( '|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|', $domain ) )
+	$domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
+	if( parse_url( get_option( 'home' ), PHP_URL_PATH ) || 'localhost' == $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) )
 		return false;
 
 	return true;
@@ -144,13 +144,6 @@
 function network_step1( $errors = false ) {
 	global $is_apache;
 
-	if ( get_option( 'siteurl' ) != get_option( 'home' ) ) {
-		echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . sprintf( __( 'Your <strong>WordPress address</strong> must match your <strong>Site address</strong> before creating a Network. See <a href="%s">General Settings</a>.' ), esc_url( admin_url( 'options-general.php' ) ) ) . '</p></div>';
-		echo '</div>';
-		include ( ABSPATH . 'wp-admin/admin-footer.php' );
-		die();
-	}
-
 	if ( defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
 		echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . __( 'The constant DO_NOT_UPGRADE_GLOBAL_TABLES cannot be defined when creating a network.' ) . '</p></div>';
 		echo '</div>';
@@ -314,21 +307,25 @@
  * @since 3.0.0
  */
 function network_step2( $errors = false ) {
-	global $base, $wpdb;
-	$hostname = get_clean_basedomain();
+	global $wpdb;
 
-	if ( ! isset( $base ) )
-		$base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) );
+	$hostname          = get_clean_basedomain();
+	$slashed_home      = trailingslashit( get_option( 'home'    ) );
+	$slashed_siteurl   = trailingslashit( get_option( 'siteurl' ) );
+	$wp_siteurl_subdir = '/' . str_replace( $slashed_home, '', $slashed_siteurl );
+	$rewrite_base      = ! empty( $wp_siteurl_subdir ) ? ltrim( trailingslashit( $wp_siteurl_subdir ), '/' ) : '';
+	$base              = parse_url( $slashed_home, PHP_URL_PATH );
 
 	// Wildcard DNS message.
 	if ( is_wp_error( $errors ) )
 		echo '<div class="error">' . $errors->get_error_message() . '</div>';
 
-	if ( $_POST ) {
-		if ( allow_subdomain_install() )
+	if ( ! empty( $_POST ) ) {
+		if ( allow_subdomain_install() ) {
 			$subdomain_install = allow_subdirectory_install() ? ! empty( $_POST['subdomain_install'] ) : true;
-		else
+		} else {
 			$subdomain_install = false;
+		}
 	} else {
 		if ( is_multisite() ) {
 			$subdomain_install = is_subdomain_install();
@@ -337,6 +334,10 @@
 <?php
 		} else {
 			$subdomain_install = (bool) $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
+
+	$subdir_match       = $subdomain_install ? '' : '(?:[_0-9a-zA-Z-]+/)?';
+	$subdir_replacement = $subdomain_install ? '' : '$1';
+
 ?>
 	<div class="error"><p><strong><?php _e('Warning:'); ?></strong> <?php _e( 'An existing WordPress network was detected.' ); ?></p></div>
 	<p><?php _e( 'Please complete the configuration steps. To create a new network, you will need to empty or remove the network database tables.' ); ?></p>
@@ -344,7 +345,7 @@
 		}
 	}
 
-	if ( $_POST || ! is_multisite() ) {
+	if ( ! empty( $_POST ) || ! is_multisite() ) {
 ?>
 		<h3><?php esc_html_e( 'Enabling the Network' ); ?></h3>
 		<p><?php _e( 'Complete the following steps to enable the features for creating a network of sites.' ); ?></p>
@@ -369,20 +370,25 @@
 				<textarea class="code" readonly="readonly" cols="100" rows="7">
 define('MULTISITE', true);
 define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>);
-$base = '<?php echo $base; ?>';
 define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>');
 define('PATH_CURRENT_SITE', '<?php echo $base; ?>');
 define('SITE_ID_CURRENT_SITE', 1);
-define('BLOG_ID_CURRENT_SITE', 1);</textarea>
+define('BLOG_ID_CURRENT_SITE', 1);
+<?php if ( $wp_siteurl_subdir ): ?>
+define('WP_SITEURL_SUBDIR', '<?php echo $wp_siteurl_subdir; ?>');
+<?php endif; // $wp_siteurl_subdir ?>
+</textarea>
 <?php
 	$keys_salts = array( 'AUTH_KEY' => '', 'SECURE_AUTH_KEY' => '', 'LOGGED_IN_KEY' => '', 'NONCE_KEY' => '', 'AUTH_SALT' => '', 'SECURE_AUTH_SALT' => '', 'LOGGED_IN_SALT' => '', 'NONCE_SALT' => '' );
 	foreach ( $keys_salts as $c => $v ) {
-		if ( defined( $c ) )
+		if ( defined( $c ) ) {
 			unset( $keys_salts[ $c ] );
+		}
 	}
+
 	if ( ! empty( $keys_salts ) ) {
 		$keys_salts_str = '';
-		$from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
+		$from_api       = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
 		if ( is_wp_error( $from_api ) ) {
 			foreach ( $keys_salts as $c => $v ) {
 				$keys_salts_str .= "\ndefine( '$c', '" . wp_generate_password( 64, true, true ) . "' );";
@@ -404,10 +410,13 @@
 </li>
 <?php
 	if ( iis7_supports_permalinks() ) :
+		// IIS doesn't support RewriteBase, all your RewriteBase are belong to us
+		$iis_subdir_match = ltrim( $base, '/' ) . $subdir_match;
+		$iis_rewrite_base = ltrim( $base, '/' ) . $rewrite_base;
+		$iis_subdir_replacement = $subdomain_install ? '' : '{R:1}';
 
-			if ( $subdomain_install ) {
-				$web_config_file =
-'<?xml version="1.0" encoding="UTF-8"?>
+		$web_config_file = <<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <system.webServer>
         <rewrite>
@@ -417,45 +426,14 @@
                     <action type="None" />
                 </rule>
                 <rule name="WordPress Rule 2" stopProcessing="true">
-                    <match url="^files/(.+)" ignoreCase="false" />
-                    <action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
+                    <match url="^{$iis_subdir_match}files/(.+)" ignoreCase="false" />
+                    <action type="Rewrite" url="{$iis_rewrite_base}wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
                 </rule>
                 <rule name="WordPress Rule 3" stopProcessing="true">
-                    <match url="^" ignoreCase="false" />
-                    <conditions logicalGrouping="MatchAny">
-                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
-                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
-                    </conditions>
-                    <action type="None" />
+                    <match url="^{$iis_subdir_match}wp-admin$" ignoreCase="false" />
+                    <action type="Redirect" url="{$iis_subdir_replacement}wp-admin/" redirectType="Permanent" />
                 </rule>
                 <rule name="WordPress Rule 4" stopProcessing="true">
-                    <match url="." ignoreCase="false" />
-                    <action type="Rewrite" url="index.php" />
-                </rule>
-            </rules>
-        </rewrite>
-    </system.webServer>
-</configuration>';
-			} else {
-				$web_config_file =
-'<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
-    <system.webServer>
-        <rewrite>
-            <rules>
-                <rule name="WordPress Rule 1" stopProcessing="true">
-                    <match url="^index\.php$" ignoreCase="false" />
-                    <action type="None" />
-                </rule>
-                <rule name="WordPress Rule 2" stopProcessing="true">
-                    <match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
-                    <action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
-                </rule>
-                <rule name="WordPress Rule 3" stopProcessing="true">
-                    <match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
-                    <action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
-                </rule>
-                <rule name="WordPress Rule 4" stopProcessing="true">
                     <match url="^" ignoreCase="false" />
                     <conditions logicalGrouping="MatchAny">
                         <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
@@ -464,12 +442,12 @@
                     <action type="None" />
                 </rule>
                 <rule name="WordPress Rule 5" stopProcessing="true">
-                    <match url="^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*)" ignoreCase="false" />
-                    <action type="Rewrite" url="{R:1}" />
+                    <match url="^{$iis_subdir_match}(wp-(content|admin|includes).*)" ignoreCase="false" />
+                    <action type="Rewrite" url="{$iis_rewrite_base}{R:1}" />
                 </rule>
                 <rule name="WordPress Rule 6" stopProcessing="true">
-                    <match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
-                    <action type="Rewrite" url="{R:2}" />
+                    <match url="^{$iis_subdir_match}([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
+                    <action type="Rewrite" url="{$iis_rewrite_base}{R:2}" />
                 </rule>
                 <rule name="WordPress Rule 7" stopProcessing="true">
                     <match url="." ignoreCase="false" />
@@ -478,40 +456,39 @@
             </rules>
         </rewrite>
     </system.webServer>
-</configuration>';
-			}
+</configuration>
+EOF;
+
 	?>
-		<li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p>
+		<li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), trailingslashit( str_replace( trailingslashit( $wp_siteurl_subdir ), '', ABSPATH ) ) ); ?></p>
 		<textarea class="code" readonly="readonly" cols="100" rows="20">
-		<?php echo esc_textarea( $web_config_file ); ?>
+<?php echo esc_textarea( $web_config_file ); ?>
 		</textarea></li>
 		</ol>
 
 	<?php else : // end iis7_supports_permalinks(). construct an htaccess file instead:
-
-		$htaccess_file = 'RewriteEngine On
-RewriteBase ' . $base . '
+		$htaccess_file = <<<EOF
+RewriteEngine On
+RewriteBase {$base}
 RewriteRule ^index\.php$ - [L]
 
 # uploaded files
-RewriteRule ^' . ( $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?' ) . 'files/(.+) wp-includes/ms-files.php?file=$' . ( $subdomain_install ? 1 : 2 ) . ' [L]' . "\n";
+RewriteRule ^{$subdir_match}files/(.+) {$rewrite_base}wp-includes/ms-files.php?file=$1 [L]
 
-		if ( ! $subdomain_install )
-			$htaccess_file .= "\n# add a trailing slash to /wp-admin\n" . 'RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]' . "\n";
+# add a trailing slash to /wp-admin
+RewriteRule ^{$subdir_match}wp-admin$ {$subdir_replacement}wp-admin/ [R=301,L]
 
-		$htaccess_file .= "\n" . 'RewriteCond %{REQUEST_FILENAME} -f [OR]
+RewriteCond %{REQUEST_FILENAME} -f [OR]
 RewriteCond %{REQUEST_FILENAME} -d
-RewriteRule ^ - [L]';
+RewriteRule ^ - [L]
+RewriteRule ^{$subdir_match}(wp-(content|admin|includes).*) {$rewrite_base}$1 [L]
+RewriteRule ^{$subdir_match}(.*\.php)$ {$rewrite_base}$1 [L]
+RewriteRule . index.php [L]
+EOF;
 
-		// @todo custom content dir.
-		if ( ! $subdomain_install )
-			$htaccess_file .= "\nRewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]\nRewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]";
-
-		$htaccess_file .= "\nRewriteRule . index.php [L]";
-
 		?>
-		<li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p>
-		<textarea class="code" readonly="readonly" cols="100" rows="<?php echo $subdomain_install ? 11 : 16; ?>">
+		<li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), trailingslashit( str_replace( trailingslashit( $wp_siteurl_subdir ), '', ABSPATH ) ) ); ?></p>
+		<textarea class="code" readonly="readonly" cols="100" rows="16">
 <?php echo esc_textarea( $htaccess_file ); ?></textarea></li>
 		</ol>
 
@@ -523,24 +500,26 @@
 	}
 }
 
-if ( $_POST ) {
+if ( ! empty( $_POST ) ) {
 
-	$base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) );
-
 	check_admin_referer( 'install-network-1' );
 
 	require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
+
 	// create network tables
 	install_network();
-	$hostname = get_clean_basedomain();
+
+	$base              = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
 	$subdomain_install = allow_subdomain_install() ? !empty( $_POST['subdomain_install'] ) : false;
+
 	if ( ! network_domain_check() ) {
 		$result = populate_network( 1, get_clean_basedomain(), sanitize_email( $_POST['email'] ), stripslashes( $_POST['sitename'] ), $base, $subdomain_install );
 		if ( is_wp_error( $result ) ) {
-			if ( 1 == count( $result->get_error_codes() ) && 'no_wildcard_dns' == $result->get_error_code() )
+			if ( 1 == count( $result->get_error_codes() ) && 'no_wildcard_dns' == $result->get_error_code() ) {
 				network_step2( $result );
-			else
+			} else {
 				network_step1( $result );
+			}
 		} else {
 			network_step2();
 		}
Index: wp-admin/includes/ms.php
===================================================================
--- wp-admin/includes/ms.php	(revision 21496)
+++ wp-admin/includes/ms.php	(working copy)
@@ -673,7 +673,7 @@
 	<?php if ( in_array( get_site_option( 'registration' ), array( 'all', 'blog' ) ) ) : ?>
 		<tr>
 			<th scope="row" colspan="2" class="th-full">
-				<a href="<?php echo apply_filters( 'wp_signup_location', network_home_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a>
+				<a href="<?php echo apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a>
 			</th>
 		</tr>
 	<?php endif; ?>
Index: wp-admin/network/site-new.php
===================================================================
--- wp-admin/network/site-new.php	(revision 21496)
+++ wp-admin/network/site-new.php	(working copy)
@@ -62,10 +62,10 @@
 
 	if ( is_subdomain_install() ) {
 		$newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
-		$path = $base;
+		$path      = $current_site->path;
 	} else {
 		$newdomain = $current_site->domain;
-		$path = $base . $domain . '/';
+		$path      = $current_site->path . $domain . '/';
 	}
 
 	$password = 'N/A';
