cfgmgr.c

来自「一个类似windows」· C语言 代码 · 共 2,242 行 · 第 1/5 页

C
2,242
字号
/*
 * Configuration manager functions
 *
 * Copyright 2000 James Hatheway
 * Copyright 2005, 2006 Eric Kohl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "setupapi_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

/* Registry key and value names */
static const WCHAR Backslash[] = {'\\', 0};
static const WCHAR Class[]  = {'C','l','a','s','s',0};

static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
                                     'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
                                     'C','o','n','t','r','o','l','\\',
                                     'C','l','a','s','s',0};

static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
                                      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
                                      'C','o','n','t','r','o','l','\\',
                                      'D','e','v','i','c','e','C','l','a','s','s','e','s',0};

typedef struct _MACHINE_INFO
{
    WCHAR szMachineName[MAX_PATH];
    RPC_BINDING_HANDLE BindingHandle;
    HSTRING_TABLE StringTable;
} MACHINE_INFO, *PMACHINE_INFO;


static BOOL GuidToString(LPGUID Guid, LPWSTR String)
{
    LPWSTR lpString;

    if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
        return FALSE;

    lstrcpyW(&String[1], lpString);

    String[0] = L'{';
    String[MAX_GUID_STRING_LEN - 2] = L'}';
    String[MAX_GUID_STRING_LEN - 1] = 0;

    RpcStringFree(&lpString);

    return TRUE;
}


/***********************************************************************
 * CMP_Init_Detection [SETUPAPI.@]
 */
CONFIGRET WINAPI CMP_Init_Detection(
    DWORD dwMagic)
{
    RPC_BINDING_HANDLE BindingHandle = NULL;

    TRACE("%lu\n", dwMagic);

    if (dwMagic != CMP_MAGIC)
        return CR_INVALID_DATA;

    if (!PnpGetLocalHandles(&BindingHandle, NULL))
        return CR_FAILURE;

    return PNP_InitDetection(BindingHandle);
}


/***********************************************************************
 * CMP_Report_LogOn [SETUPAPI.@]
 */
CONFIGRET WINAPI CMP_Report_LogOn(
    DWORD dwMagic,
    DWORD dwProcessId)
{
    RPC_BINDING_HANDLE BindingHandle = NULL;
    CONFIGRET ret = CR_SUCCESS;
    BOOL bAdmin;
    DWORD i;

    TRACE("%lu\n", dwMagic);

    if (dwMagic != CMP_MAGIC)
        return CR_INVALID_DATA;

    if (!PnpGetLocalHandles(&BindingHandle, NULL))
        return CR_FAILURE;

    bAdmin = IsUserAdmin();

    for (i = 0; i < 30; i++)
    {
        ret = PNP_ReportLogOn(BindingHandle,
                              bAdmin,
                              dwProcessId);
        if (ret == CR_SUCCESS)
            break;

        Sleep(5000);
    }

    return ret;
}


/***********************************************************************
 * CM_Add_IDA [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Add_IDA(
    DEVINST dnDevInst, PSTR pszID, ULONG ulFlags)
{
    TRACE("%p %s %lx\n", dnDevInst, pszID, ulFlags);
    return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
}


/***********************************************************************
 * CM_Add_IDW [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Add_IDW(
    DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags)
{
    TRACE("%p %s %lx\n", dnDevInst, debugstr_w(pszID), ulFlags);
    return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
}


/***********************************************************************
 * CM_Add_ID_ExA [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Add_ID_ExA(
    DEVINST dnDevInst, PSTR pszID, ULONG ulFlags, HMACHINE hMachine)
{
    PWSTR pszIDW;
    CONFIGRET ret;

    TRACE("%p %s %lx %p\n", dnDevInst, pszID, ulFlags, hMachine);

    if (CaptureAndConvertAnsiArg(pszID, &pszIDW))
        return CR_INVALID_DATA;

    ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);

    MyFree(pszIDW);

    return ret;
}


/***********************************************************************
 * CM_Add_ID_ExW [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Add_ID_ExW(
    DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags, HMACHINE hMachine)
{
    FIXME("%p %s %lx %p\n", dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
    return CR_CALL_NOT_IMPLEMENTED;
}


/***********************************************************************
 * CM_Connect_MachineA [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Connect_MachineA(
    PCSTR UNCServerName, PHMACHINE phMachine)
{
    PWSTR pServerNameW;
    CONFIGRET ret;

    TRACE("%s %p\n", UNCServerName, phMachine);

    if (UNCServerName == NULL || *UNCServerName == 0)
        return CM_Connect_MachineW(NULL, phMachine);

    if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
        return CR_INVALID_DATA;

    ret = CM_Connect_MachineW(pServerNameW, phMachine);

    MyFree(pServerNameW);

    return ret;
}


/***********************************************************************
 * CM_Connect_MachineW [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Connect_MachineW(
    PCWSTR UNCServerName, PHMACHINE phMachine)
{
    PMACHINE_INFO pMachine;

    TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);

    pMachine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MACHINE_INFO));
    if (pMachine == NULL)
        return CR_OUT_OF_MEMORY;

    lstrcpyW(pMachine->szMachineName, UNCServerName);

    pMachine->StringTable = StringTableInitialize();
    if (pMachine->StringTable == NULL)
    {
        HeapFree(GetProcessHeap(), 0, pMachine);
        return CR_FAILURE;
    }

    StringTableAddString(pMachine->StringTable, L"PLT", 1);

    if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
    {
        StringTableDestroy(pMachine->StringTable);
        HeapFree(GetProcessHeap(), 0, pMachine);
        return CR_INVALID_MACHINENAME;
    }

    phMachine = (PHMACHINE)pMachine;

    return CR_SUCCESS;
}


/***********************************************************************
 * CM_Create_DevNodeA [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Create_DevNodeA(
    PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
    ULONG ulFlags)
{
    TRACE("%p %s %p %lx\n",
          pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
    return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
                                 ulFlags, NULL);
}


/***********************************************************************
 * CM_Create_DevNodeW [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Create_DevNodeW(
    PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
    ULONG ulFlags)
{
    TRACE("%p %s %p %lx\n",
          pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
    return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
                                 ulFlags, NULL);
}


/***********************************************************************
 * CM_Create_DevNode_ExA [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Create_DevNode_ExA(
    PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
    ULONG ulFlags, HANDLE hMachine)
{
    DEVINSTID_W pDeviceIDW;
    CONFIGRET ret;

    TRACE("%p %s %p %lx %p\n",
          pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);

    if (CaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
        return CR_INVALID_DATA;

    ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
                                hMachine);

    MyFree(pDeviceIDW);

    return ret;
}


/***********************************************************************
 * CM_Create_DevNode_ExW [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Create_DevNode_ExW(
    PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
    ULONG ulFlags, HANDLE hMachine)
{
    RPC_BINDING_HANDLE BindingHandle = NULL;
    HSTRING_TABLE StringTable = NULL;
    LPWSTR lpParentDevInst;
    CONFIGRET ret = CR_SUCCESS;

    FIXME("%p %s %p %lx %p\n",
          pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);

    if (!IsUserAdmin())
        return CR_ACCESS_DENIED;

    if (pdnDevInst == NULL)
        return CR_INVALID_POINTER;

    if (pDeviceID == NULL || wcslen(pDeviceID) == 0)
        return CR_INVALID_DEVICE_ID;

    if (dnParent == 0)
        return CR_INVALID_DEVNODE;

    if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
        return CR_INVALID_FLAG;

    if (hMachine != NULL)
    {
        BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
        if (BindingHandle == NULL)
            return CR_FAILURE;

        StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
        if (StringTable == 0)
            return CR_FAILURE;
    }
    else
    {
        if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
            return CR_FAILURE;
    }

    lpParentDevInst = StringTableStringFromId(StringTable, dnParent);
    if (lpParentDevInst == NULL)
        return CR_INVALID_DEVNODE;

    ret = PNP_CreateDevInst(BindingHandle,
                            pDeviceID,
                            lpParentDevInst,
                            MAX_DEVICE_ID_LEN,
                            ulFlags);
    if (ret == CR_SUCCESS)
    {
        *pdnDevInst = StringTableAddString(StringTable, pDeviceID, 1);
        if (*pdnDevInst == 0)
            ret = CR_NO_SUCH_DEVNODE;
    }

    return ret;
}


/***********************************************************************
 * CM_Delete_Class_Key [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Delete_Class_Key(
    LPGUID ClassGuid, ULONG ulFlags)
{
    TRACE("%p %lx\n", ClassGuid, ulFlags);
    return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
}


/***********************************************************************
 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Delete_Class_Key_Ex(
    LPGUID ClassGuid, ULONG ulFlags, HANDLE hMachine)
{
    WCHAR szGuidString[MAX_GUID_STRING_LEN];
    RPC_BINDING_HANDLE BindingHandle = NULL;

    TRACE("%p %lx %lx\n", ClassGuid, ulFlags, hMachine);

    if (ClassGuid == NULL)
        return CR_INVALID_POINTER;

    if (ulFlags & ~CM_DELETE_CLASS_BITS)
        return CR_INVALID_FLAG;

    if (!GuidToString(ClassGuid, szGuidString))
        return CR_INVALID_DATA;

    if (hMachine != NULL)
    {
        BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
        if (BindingHandle == NULL)
            return CR_FAILURE;
    }
    else
    {
        if (!PnpGetLocalHandles(&BindingHandle, NULL))
            return CR_FAILURE;
    }

    return PNP_DeleteClassKey(BindingHandle,
                             szGuidString,
                             ulFlags);
}


/***********************************************************************
 * CM_Disable_DevNode [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Disable_DevNode(
    DEVINST dnDevInst, ULONG ulFlags)
{
    TRACE("%p %lx\n", dnDevInst, ulFlags);
    return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
}


/***********************************************************************
 * CM_Disable_DevNode_Ex [SETUPAPI.@]
 */
CONFIGRET WINAPI CM_Disable_DevNode_Ex(
    DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
{
    RPC_BINDING_HANDLE BindingHandle = NULL;
    HSTRING_TABLE StringTable = NULL;
    LPWSTR lpDevInst;

    FIXME("%p %lx %p\n", dnDevInst, ulFlags, hMachine);

    if (!IsUserAdmin())
        return CR_ACCESS_DENIED;

    if (dnDevInst == 0)
        return CR_INVALID_DEVINST;

    if (ulFlags != 0)
        return CR_INVALID_FLAG;

    if (hMachine != NULL)
    {
        BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
        if (BindingHandle == NULL)
            return CR_FAILURE;

        StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
        if (StringTable == 0)

⌨️ 快捷键说明

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