📄 cfgmgr.c
字号:
/*
* 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;
BOOL bLocal;
} MACHINE_INFO, *PMACHINE_INFO;
typedef struct _LOG_CONF_INFO
{
ULONG ulMagic;
DEVINST dnDevInst;
ULONG ulFlags;
ULONG ulTag;
} LOG_CONF_INFO, *PLOG_CONF_INFO;
#define LOG_CONF_MAGIC 0x464E434C /* "LCNF" */
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_WaitNoPendingInstallEvents [SETUPAPI.@]
*/
DWORD WINAPI CMP_WaitNoPendingInstallEvents(
DWORD dwTimeout)
{
HANDLE hEvent;
DWORD ret;
hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
if (hEvent == NULL)
return WAIT_FAILED;
ret = WaitForSingleObject(hEvent, dwTimeout);
CloseHandle(hEvent);
return ret;
}
/***********************************************************************
* 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_Empty_Log_Conf [SETUPAPI.@]
*/
CONFIGRET WINAPI CM_Add_Empty_Log_Conf(
PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
ULONG ulFlags)
{
TRACE("%p %p %lu %lx\n", plcLogConf, dnDevInst, Priority, ulFlags);
return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
ulFlags, NULL);
}
/***********************************************************************
* CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
*/
CONFIGRET WINAPI CM_Add_Empty_Log_Conf_Ex(
PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
ULONG ulFlags, HMACHINE hMachine)
{
RPC_BINDING_HANDLE BindingHandle = NULL;
HSTRING_TABLE StringTable = NULL;
ULONG ulLogConfTag = 0;
LPWSTR lpDevInst;
PLOG_CONF_INFO pLogConfInfo;
CONFIGRET ret = CR_SUCCESS;
FIXME("%p %p %lu %lx %p\n",
plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
if (!IsUserAdmin())
return CR_ACCESS_DENIED;
if (plcLogConf == NULL)
return CR_INVALID_POINTER;
if (dnDevInst == 0)
return CR_INVALID_DEVINST;
if (Priority > 0xFFFF)
return CR_INVALID_PRIORITY;
if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
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;
}
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
if (lpDevInst == NULL)
return CR_INVALID_DEVNODE;
ret = PNP_AddEmptyLogConf(BindingHandle, lpDevInst, Priority, &ulLogConfTag, ulFlags);
if (ret == CR_SUCCESS)
{
pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
if (pLogConfInfo == NULL)
{
ret = CR_OUT_OF_MEMORY;
}
else
{
pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
pLogConfInfo->dnDevInst = dnDevInst;
pLogConfInfo->ulFlags = ulFlags;
pLogConfInfo->ulTag = ulLogConfTag;
*plcLogConf = (LOG_CONF)pLogConfInfo;
ret = CR_SUCCESS;
}
}
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)
{
RPC_BINDING_HANDLE BindingHandle = NULL;
HSTRING_TABLE StringTable = NULL;
LPWSTR lpDevInst;
TRACE("%p %s %lx %p\n", dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
if (!IsUserAdmin())
return CR_ACCESS_DENIED;
if (dnDevInst == 0)
return CR_INVALID_DEVINST;
if (pszID == NULL)
return CR_INVALID_POINTER;
if (ulFlags & ~CM_ADD_ID_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;
}
lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
if (lpDevInst == NULL)
return CR_INVALID_DEVNODE;
return PNP_AddID(BindingHandle,
lpDevInst,
pszID,
ulFlags);
}
/***********************************************************************
* 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);
if (phMachine == NULL)
return CR_INVALID_POINTER;
*phMachine = NULL;
pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
if (pMachine == NULL)
return CR_OUT_OF_MEMORY;
if (UNCServerName == NULL || *UNCServerName == 0)
{
pMachine->bLocal = TRUE;
/* FIXME: store the computers name in pMachine->szMachineName */
if (!PnpGetLocalHandles(&pMachine->BindingHandle,
&pMachine->StringTable))
{
HeapFree(GetProcessHeap(), 0, pMachine);
return CR_FAILURE;
}
}
else
{
pMachine->bLocal = FALSE;
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -