string[] IServerConfig.GetVirtualSubdirs(VirtualPath path, bool inApp)
        {
            // WOS 1956227: PERF: inactive applications on the web server degrade Working Set by 10%
            // It is very expensive to get a list of subdirs not in the application if there are a lot of applications,
            // so instead, use ProcessHostServerConfig.IsWithinApp to check if a particular path is in the app.
            if (inApp == false)
            {
                throw new NotSupportedException();
            }

            string vpath = path.VirtualPathString;

            string [] dirList      = null;
            int       dirListCount = 0;

            IntPtr pAppCollection = IntPtr.Zero;
            IntPtr pBstr          = IntPtr.Zero;
            int    cBstr          = 0;

            try {
                int count  = 0;
                int result = _nativeConfig.MgdGetAppCollection(CurrentAppSiteName, vpath, out pBstr, out cBstr, out pAppCollection, out count);
                if (result < 0 || pBstr == IntPtr.Zero)
                {
                    throw new InvalidOperationException(SR.GetString(SR.Cant_Enumerate_NativeDirs, result));
                }
                string appRoot = StringUtil.StringFromWCharPtr(pBstr, cBstr);
                Marshal.FreeBSTR(pBstr);
                pBstr   = IntPtr.Zero;
                cBstr   = 0;
                dirList = new string[count];

                int lenNoTrailingSlash = vpath.Length;
                if (vpath[lenNoTrailingSlash - 1] == '/')
                {
                    lenNoTrailingSlash--;
                }
                int    lenAppRoot          = appRoot.Length;
                string appRootRelativePath = (lenNoTrailingSlash > lenAppRoot) ? vpath.Substring(lenAppRoot, lenNoTrailingSlash - lenAppRoot) : String.Empty;

                for (uint index = 0; index < count; index++)
                {
                    result = UnsafeIISMethods.MgdGetNextVPath(pAppCollection, index, out pBstr, out cBstr);
                    if (result < 0 || pBstr == IntPtr.Zero)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.Cant_Enumerate_NativeDirs, result));
                    }
                    // if cBstr = 1, then pBstr = "/" and can be ignored
                    string subVdir = (cBstr > 1) ? StringUtil.StringFromWCharPtr(pBstr, cBstr) : null;
                    Marshal.FreeBSTR(pBstr);
                    pBstr = IntPtr.Zero;
                    cBstr = 0;

                    // only put the subVdir in our list if it is a subdirectory of the specified vpath
                    if (subVdir != null && subVdir.Length > appRootRelativePath.Length)
                    {
                        if (appRootRelativePath.Length == 0)
                        {
                            if (subVdir.IndexOf('/', 1) == -1)
                            {
                                dirList[dirListCount++] = subVdir.Substring(1);
                            }
                        }
                        else if (StringUtil.EqualsIgnoreCase(appRootRelativePath, 0, subVdir, 0, appRootRelativePath.Length))
                        {
                            int nextSlashIndex = subVdir.IndexOf('/', 1 + appRootRelativePath.Length);
                            if (nextSlashIndex > -1)
                            {
                                dirList[dirListCount++] = subVdir.Substring(appRootRelativePath.Length + 1, nextSlashIndex - appRootRelativePath.Length);
                            }
                            else
                            {
                                dirList[dirListCount++] = subVdir.Substring(appRootRelativePath.Length + 1);
                            }
                        }
                    }
                }
            }
            finally {
                if (pAppCollection != IntPtr.Zero)
                {
                    Marshal.Release(pAppCollection);
                    pAppCollection = IntPtr.Zero;
                }
                if (pBstr != IntPtr.Zero)
                {
                    Marshal.FreeBSTR(pBstr);
                    pBstr = IntPtr.Zero;
                }
            }

            string[] subdirs = null;
            if (dirListCount > 0)
            {
                subdirs = new string[dirListCount];
                for (int i = 0; i < subdirs.Length; i++)
                {
                    subdirs[i] = dirList[i];
                }
            }
            return(subdirs);
        }