⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  ReactOS kernel
 *  Copyright (C) 2003 ReactOS Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*
 * COPYRIGHT:         See COPYING in the top level directory
 * PROJECT:           ReactOS system libraries
 * PURPOSE:           System setup
 * FILE:              lib/syssetup/install.c
 * PROGRAMER:         Eric Kohl
 */

/* INCLUDES *****************************************************************/

#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>

#include <commctrl.h>
#include <stdio.h>
#include <io.h>
#include <tchar.h>
#include <stdlib.h>

#include <samlib/samlib.h>
#include <syssetup/syssetup.h>
#include <userenv.h>
#include <setupapi.h>

#include <shlobj.h>
#include <objidl.h>
#include <shlwapi.h>

#include "globals.h"
#include "resource.h"

#include <debug.h>

DWORD WINAPI
CMP_WaitNoPendingInstallEvents(DWORD dwTimeout);

/* GLOBALS ******************************************************************/

PSID DomainSid = NULL;
PSID AdminSid = NULL;

HINF hSysSetupInf = INVALID_HANDLE_VALUE;

/* FUNCTIONS ****************************************************************/

static VOID
DebugPrint(char* fmt,...)
{
    char buffer[512];
    va_list ap;

    va_start(ap, fmt);
    vsprintf(buffer, fmt, ap);
    va_end(ap);

    LogItem(SYSSETUP_SEVERITY_FATAL_ERROR, L"Failed");

    strcat(buffer, "\nRebooting now!");
    MessageBoxA(NULL,
                buffer,
                "ReactOS Setup",
                MB_OK);
}


HRESULT CreateShellLink(LPCTSTR linkPath, LPCTSTR cmd, LPCTSTR arg, LPCTSTR dir, LPCTSTR iconPath, int icon_nr, LPCTSTR comment)
{
    IShellLink* psl;
    IPersistFile* ppf;
#ifndef _UNICODE
    WCHAR buffer[MAX_PATH];
#endif /* _UNICODE */

    HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl);

    if (SUCCEEDED(hr))
    {
        hr = psl->lpVtbl->SetPath(psl, cmd);

        if (arg)
        {
            hr = psl->lpVtbl->SetArguments(psl, arg);
        }

        if (dir)
        {
            hr = psl->lpVtbl->SetWorkingDirectory(psl, dir);
        }

        if (iconPath)
        {
            hr = psl->lpVtbl->SetIconLocation(psl, iconPath, icon_nr);
        }

        if (comment)
        {
            hr = psl->lpVtbl->SetDescription(psl, comment);
        }

        hr = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hr))
        {
#ifdef _UNICODE
            hr = ppf->lpVtbl->Save(ppf, linkPath, TRUE);
#else /* _UNICODE */
            MultiByteToWideChar(CP_ACP, 0, linkPath, -1, buffer, MAX_PATH);

            hr = ppf->lpVtbl->Save(ppf, buffer, TRUE);
#endif /* _UNICODE */

            ppf->lpVtbl->Release(ppf);
        }

        psl->lpVtbl->Release(psl);
    }

    return hr;
}


static BOOL
CreateShortcut(int csidl, LPCTSTR folder, UINT nIdName, LPCTSTR command, UINT nIdTitle, BOOL bCheckExistence)
{
    TCHAR path[MAX_PATH];
    TCHAR exeName[MAX_PATH];
    TCHAR title[256];
    TCHAR name[256];
    LPTSTR p = path;
    TCHAR szWorkingDir[MAX_PATH];
    LPTSTR lpWorkingDir = NULL;
    LPTSTR lpFilePart;
    DWORD dwLen;

    if (ExpandEnvironmentStrings(command,
                                 path,
                                 sizeof(path) / sizeof(path[0])) == 0)
    {
        _tcscpy(path,
                command);
    }

    if (bCheckExistence)
    {
        if ((_taccess(path, 0 )) == -1)
            /* Expected error, don't return FALSE */
            return TRUE;
    }

    dwLen = GetFullPathName(path,
                            sizeof(szWorkingDir) / sizeof(szWorkingDir[0]),
                            szWorkingDir,
                            &lpFilePart);
    if (dwLen != 0 && dwLen <= sizeof(szWorkingDir) / sizeof(szWorkingDir[0]))
    {
        /* Save the file name */
        _tcscpy(exeName, lpFilePart);

        if (lpFilePart != NULL)
        {
            /* We're only interested in the path. Cut the file name off.
               Also remove the trailing backslash unless the working directory
               is only going to be a drive, ie. C:\ */
            *(lpFilePart--) = _T('\0');
            if (!(lpFilePart - szWorkingDir == 2 && szWorkingDir[1] == _T(':') &&
                  szWorkingDir[2] == _T('\\')))
            {
                *lpFilePart = _T('\0');
            }
        }

        lpWorkingDir = szWorkingDir;
    }


    if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
        return FALSE;

    if (folder)
    {
        p = PathAddBackslash(p);
        _tcscpy(p, folder);
    }

    p = PathAddBackslash(p);

    if (!LoadString(hDllInstance, nIdName, name, sizeof(name)/sizeof(name[0])))
        return FALSE;
    _tcscpy(p, name);

    if (!LoadString(hDllInstance, nIdTitle, title, sizeof(title)/sizeof(title[0])))
        return FALSE;

    // FIXME: we should pass 'command' straight in here, but shell32 doesn't expand it
    return SUCCEEDED(CreateShellLink(path, exeName, _T(""), lpWorkingDir, NULL, 0, title));
}


static BOOL
CreateShortcutFolder(int csidl, UINT nID, LPTSTR name, int nameLen)
{
    TCHAR path[MAX_PATH];
    LPTSTR p;

    if (!SHGetSpecialFolderPath(0, path, csidl, TRUE))
        return FALSE;

    if (!LoadString(hDllInstance, nID, name, nameLen))
        return FALSE;

    p = PathAddBackslash(path);
    _tcscpy(p, name);

    return CreateDirectory(path, NULL) || GetLastError()==ERROR_ALREADY_EXISTS;
}


static BOOL
CreateRandomSid(
    OUT PSID *Sid)
{
    SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
    LARGE_INTEGER SystemTime;
    PULONG Seed;
    NTSTATUS Status;

    NtQuerySystemTime(&SystemTime);
    Seed = &SystemTime.u.LowPart;

    Status = RtlAllocateAndInitializeSid(
        &SystemAuthority,
        4,
        SECURITY_NT_NON_UNIQUE,
        RtlUniform(Seed),
        RtlUniform(Seed),
        RtlUniform(Seed),
        SECURITY_NULL_RID,
        SECURITY_NULL_RID,
        SECURITY_NULL_RID,
        SECURITY_NULL_RID,
        Sid);
    return NT_SUCCESS(Status);
}


static VOID
AppendRidToSid(
    OUT PSID *Dst,
    IN PSID Src,
    IN ULONG NewRid)
{
    ULONG Rid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    UCHAR RidCount;
    ULONG i;

    RidCount = *RtlSubAuthorityCountSid (Src);

    for (i = 0; i < RidCount; i++)
        Rid[i] = *RtlSubAuthoritySid (Src, i);

    if (RidCount < 8)
    {
        Rid[RidCount] = NewRid;
        RidCount++;
    }

    RtlAllocateAndInitializeSid(
        RtlIdentifierAuthoritySid(Src),
        RidCount,
        Rid[0],
        Rid[1],
        Rid[2],
        Rid[3],
        Rid[4],
        Rid[5],
        Rid[6],
        Rid[7],
        Dst);
}


static VOID
CreateTempDir(
    IN LPCWSTR VarName)
{
    TCHAR szTempDir[MAX_PATH];
    TCHAR szBuffer[MAX_PATH];
    DWORD dwLength;
    HKEY hKey;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                     _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
                     0,
                     KEY_QUERY_VALUE,
                     &hKey))
    {
        DebugPrint("Error: %lu\n", GetLastError());
        return;
    }

    /* Get temp dir */
    dwLength = MAX_PATH * sizeof(TCHAR);
    if (RegQueryValueEx(hKey,
                        VarName,
                        NULL,
                        NULL,
                        (LPBYTE)szBuffer,
                        &dwLength))
    {
        DebugPrint("Error: %lu\n", GetLastError());
        RegCloseKey(hKey);
        return;
    }

    /* Expand it */
    if (!ExpandEnvironmentStrings(szBuffer,
                                  szTempDir,
                                  MAX_PATH))
    {
        DebugPrint("Error: %lu\n", GetLastError());
        RegCloseKey(hKey);
        return;
    }

    /* Create profiles directory */
    if (!CreateDirectory(szTempDir, NULL))
    {
        if (GetLastError() != ERROR_ALREADY_EXISTS)
        {
            DebugPrint("Error: %lu\n", GetLastError());
            RegCloseKey(hKey);
            return;
        }
    }

    RegCloseKey(hKey);
}


BOOL
ProcessSysSetupInf(VOID)
{
    INFCONTEXT InfContext;
    TCHAR LineBuffer[256];
    DWORD LineLength;

    if (!SetupFindFirstLine(hSysSetupInf,
                            _T("DeviceInfsToInstall"),
                            NULL,
                            &InfContext))
    {
        return FALSE;
    }

    do
    {
        if (!SetupGetStringField(&InfContext,
                                 0,
                                 LineBuffer,
                                 sizeof(LineBuffer)/sizeof(LineBuffer[0]),
                                 &LineLength))
        {
            return FALSE;
        }

        if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
        {
            return FALSE;
        }
    }
    while (SetupFindNextLine(&InfContext, &InfContext));

    return TRUE;
}


static BOOL
EnableUserModePnpManager(VOID)
{
    SC_HANDLE hSCManager = NULL;
    SC_HANDLE hService = NULL;
    BOOL ret = FALSE;

    hSCManager = OpenSCManager(NULL, NULL, 0);
    if (hSCManager == NULL)
        goto cleanup;

    hService = OpenService(hSCManager, _T("PlugPlay"), SERVICE_CHANGE_CONFIG | SERVICE_START);
    if (hService == NULL)
        goto cleanup;

    ret = ChangeServiceConfig(
        hService,
        SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
        NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    if (!ret)
        goto cleanup;

    ret = StartService(hService, 0, NULL);
    if (!ret)
        goto cleanup;

    ret = TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -